From d84c956af9c648966da6a0063c39f63e34805651 Mon Sep 17 00:00:00 2001 From: vun Date: Thu, 29 Sep 2022 15:27:26 +0800 Subject: [PATCH 001/261] Refactor to move first-object detection to evaluation --- .../Difficulty/Evaluators/ColourEvaluator.cs | 12 +++++----- .../Colour/Data/AlternatingMonoPattern.cs | 6 +++++ .../Colour/Data/RepeatingHitPatterns.cs | 8 ++++++- .../TaikoColourDifficultyPreprocessor.cs | 23 +++++++++++++------ .../Colour/TaikoDifficultyHitObjectColour.cs | 6 ++--- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs index 7d88be2f70..36f8babc6b 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs @@ -54,12 +54,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators TaikoDifficultyHitObjectColour colour = ((TaikoDifficultyHitObject)hitObject).Colour; double difficulty = 0.0d; - if (colour.MonoStreak != null) // Difficulty for MonoStreak - difficulty += EvaluateDifficultyOf(colour.MonoStreak); - if (colour.AlternatingMonoPattern != null) // Difficulty for AlternatingMonoPattern - difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern); - if (colour.RepeatingHitPattern != null) // Difficulty for RepeatingHitPattern - difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern); + if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak + difficulty += EvaluateDifficultyOf(colour.MonoStreak!); + if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern + difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern!); + if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern + difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern!); return difficulty; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs index 7910a8262b..bc6e02319d 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data { @@ -31,6 +32,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => MonoStreaks[0].FirstHitObject; + /// + /// All s in this . + /// + public IEnumerable AllHitObjects => MonoStreaks.SelectMany(streak => streak.HitObjects); + /// /// Determine if this is a repetition of another . This /// is a strict comparison and is true if and only if the colour sequence is exactly the same. diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs index fe0dc6dd9a..9e3d9a21b2 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data @@ -23,10 +24,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data public readonly List AlternatingMonoPatterns = new List(); /// - /// The parent in this + /// The first in this /// public TaikoDifficultyHitObject FirstHitObject => AlternatingMonoPatterns[0].FirstHitObject; + /// + /// All s in this . + /// + public IEnumerable AllHitObjects => AlternatingMonoPatterns.SelectMany(pattern => pattern.AllHitObjects); + /// /// The previous . This is used to determine the repetition interval. /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs index d19e05f4e0..500078a879 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs @@ -15,18 +15,19 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour { /// /// Processes and encodes a list of s into a list of s, - /// assigning the appropriate s to each , - /// and pre-evaluating colour difficulty of each . + /// assigning the appropriate s to each . /// public static void ProcessAndAssign(List hitObjects) { List hitPatterns = encode(hitObjects); - // Assign indexing and encoding data to all relevant objects. Only the first note of each encoding type is - // assigned with the relevant encodings. + // Assign indexing and encoding data to all relevant objects. foreach (var repeatingHitPattern in hitPatterns) { - repeatingHitPattern.FirstHitObject.Colour.RepeatingHitPattern = repeatingHitPattern; + foreach (var hitObject in repeatingHitPattern.AllHitObjects) + { + hitObject.Colour.RepeatingHitPattern = repeatingHitPattern; + } // The outermost loop is kept a ForEach loop since it doesn't need index information, and we want to // keep i and j for AlternatingMonoPattern's and MonoStreak's index respectively, to keep it in line with @@ -36,14 +37,22 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour AlternatingMonoPattern monoPattern = repeatingHitPattern.AlternatingMonoPatterns[i]; monoPattern.Parent = repeatingHitPattern; monoPattern.Index = i; - monoPattern.FirstHitObject.Colour.AlternatingMonoPattern = monoPattern; + + foreach (var hitObject in monoPattern.AllHitObjects) + { + hitObject.Colour.AlternatingMonoPattern = monoPattern; + } for (int j = 0; j < monoPattern.MonoStreaks.Count; ++j) { MonoStreak monoStreak = monoPattern.MonoStreaks[j]; monoStreak.Parent = monoPattern; monoStreak.Index = j; - monoStreak.FirstHitObject.Colour.MonoStreak = monoStreak; + + foreach (var hitObject in monoStreak.HitObjects) + { + hitObject.Colour.MonoStreak = monoStreak; + } } } } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs index 9c147eee9c..84b6871ba7 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs @@ -11,17 +11,17 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour public class TaikoDifficultyHitObjectColour { /// - /// The that encodes this note, only present if this is the first note within a + /// The that encodes this note. /// public MonoStreak? MonoStreak; /// - /// The that encodes this note, only present if this is the first note within a + /// The that encodes this note. /// public AlternatingMonoPattern? AlternatingMonoPattern; /// - /// The that encodes this note, only present if this is the first note within a + /// The that encodes this note. /// public RepeatingHitPatterns? RepeatingHitPattern; } From 09a38fec94b55ed5edd25f36496a4e5de375bf95 Mon Sep 17 00:00:00 2001 From: vun Date: Fri, 30 Sep 2022 09:10:56 +0800 Subject: [PATCH 002/261] Implement mono tl nerf for stamina, disable convert specific nerfs --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 25 ++++++++++++++++++- .../Preprocessing/Colour/Data/MonoStreak.cs | 5 ++++ .../Difficulty/TaikoDifficultyCalculator.cs | 9 ------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 49b3ae2e19..9c5251df9b 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -24,6 +24,29 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators return 30 / interval; } + /// + /// Determines the number of fingers available to hit the current . + /// Any mono notes that is more than 0.5s apart from note of the other colour will be considered to have more + /// than 2 fingers available, since players can move their hand over to hit the same key with multiple fingers. + /// + private static int availableFingersFor(TaikoDifficultyHitObject hitObject) + { + DifficultyHitObject? previousColourChange = hitObject.Colour.MonoStreak?.FirstHitObject.Previous(0); + DifficultyHitObject? nextColourChange = hitObject.Colour.MonoStreak?.LastHitObject.Next(0); + + if (previousColourChange != null && hitObject.StartTime - previousColourChange.StartTime < 300) + { + return 2; + } + + if (nextColourChange != null && nextColourChange.StartTime - hitObject.StartTime < 300) + { + return 2; + } + + return 5; + } + /// /// Evaluates the minimum mechanical stamina required to play the current object. This is calculated using the /// maximum possible interval between two hits using the same key, by alternating 2 keys for each colour. @@ -37,7 +60,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators // Find the previous hit object hit by the current key, which is two notes of the same colour prior. TaikoDifficultyHitObject taikoCurrent = (TaikoDifficultyHitObject)current; - TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(1); + TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(availableFingersFor(taikoCurrent) - 1); if (keyPrevious == null) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs index 174988bed7..c01a0f6686 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs @@ -33,6 +33,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => HitObjects[0]; + /// + /// The last in this . + /// + public TaikoDifficultyHitObject LastHitObject => HitObjects[^1]; + /// /// The hit type of all objects encoded within this /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index 2b0b563323..24b5f5939a 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -83,15 +83,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double combinedRating = combined.DifficultyValue() * difficulty_multiplier; double starRating = rescale(combinedRating * 1.4); - // TODO: This is temporary measure as we don't detect abuse of multiple-input playstyles of converts within the current system. - if (beatmap.BeatmapInfo.Ruleset.OnlineID == 0) - { - starRating *= 0.925; - // For maps with low colour variance and high stamina requirement, multiple inputs are more likely to be abused. - if (colourRating < 2 && staminaRating > 8) - starRating *= 0.80; - } - HitWindows hitWindows = new TaikoHitWindows(); hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty); From 02092ede649fbcb5126c0d48197a1778414c3768 Mon Sep 17 00:00:00 2001 From: vun Date: Fri, 30 Sep 2022 11:42:48 +0800 Subject: [PATCH 003/261] Refactor previous and next colour change into TaikoDifficultyHitObjectColour --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 4 ++-- .../Colour/TaikoDifficultyHitObjectColour.cs | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 9c5251df9b..6a07d49f98 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// private static int availableFingersFor(TaikoDifficultyHitObject hitObject) { - DifficultyHitObject? previousColourChange = hitObject.Colour.MonoStreak?.FirstHitObject.Previous(0); - DifficultyHitObject? nextColourChange = hitObject.Colour.MonoStreak?.LastHitObject.Next(0); + DifficultyHitObject? previousColourChange = hitObject.Colour.PreviousColourChange; + DifficultyHitObject? nextColourChange = hitObject.Colour.NextColourChange; if (previousColourChange != null && hitObject.StartTime - previousColourChange.StartTime < 300) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs index 84b6871ba7..abf6fb3672 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs @@ -24,5 +24,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour /// The that encodes this note. /// public RepeatingHitPatterns? RepeatingHitPattern; + + /// + /// The closest past that's not the same colour. + /// + public TaikoDifficultyHitObject? PreviousColourChange => MonoStreak?.FirstHitObject.PreviousNote(0); + + /// + /// The closest future that's not the same colour. + /// + public TaikoDifficultyHitObject? NextColourChange => MonoStreak?.LastHitObject.NextNote(0); } } From e6093f94df42cacce79dcd42208989ecbb76bf33 Mon Sep 17 00:00:00 2001 From: vun Date: Fri, 30 Sep 2022 20:56:16 +0800 Subject: [PATCH 004/261] Apply nerfs to HD/FL bonuses with converts --- .../Difficulty/TaikoPerformanceCalculator.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 95a1e8bc66..6becfd349d 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -41,6 +41,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (totalSuccessfulHits > 0) effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; + // We are disabling some HD and/or FL Bonus for converts for now due to them having low pattern difficulty, and thus being easy to memorize. + bool readingBonusEnabled = score.BeatmapInfo.Ruleset.OnlineID == 1; + double multiplier = 1.13; if (score.Mods.Any(m => m is ModHidden)) @@ -49,8 +52,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes); - double accuracyValue = computeAccuracyValue(score, taikoAttributes); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, readingBonusEnabled); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, readingBonusEnabled); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -66,7 +69,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -78,19 +81,19 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden)) + if (score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) difficultyValue *= 1.050; - if (score.Mods.Any(m => m is ModFlashlight)) + if (score.Mods.Any(m => m is ModFlashlight) && readingBonusEnabled) difficultyValue *= 1.050 * lengthBonus; return difficultyValue * Math.Pow(score.Accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) { if (attributes.GreatHitWindow <= 0) return 0; @@ -100,8 +103,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double lengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); accuracyValue *= lengthBonus; - // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden)) + // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus); return accuracyValue; From a276e400333517524a2c4c6ea14dce891c24480d Mon Sep 17 00:00:00 2001 From: Jay L Date: Sun, 2 Oct 2022 09:05:58 +1000 Subject: [PATCH 005/261] reintroduce fl bonus to converts --- .../Difficulty/TaikoPerformanceCalculator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 6becfd349d..fe3dd1fad1 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModHardRock)) difficultyValue *= 1.050; - if (score.Mods.Any(m => m is ModFlashlight) && readingBonusEnabled) + if (score.Mods.Any(m => m is ModFlashlight)) difficultyValue *= 1.050 * lengthBonus; return difficultyValue * Math.Pow(score.Accuracy, 2.0); @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double lengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); accuracyValue *= lengthBonus; - // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. + // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus); From 4b562f782f35327e5e13f928aebe79c0836535eb Mon Sep 17 00:00:00 2001 From: Jay L Date: Sun, 2 Oct 2022 15:28:39 +1000 Subject: [PATCH 006/261] decrease finger count --- .idea/.idea.osu/.idea/discord.xml | 7 +++++++ .../Difficulty/Evaluators/StaminaEvaluator.cs | 2 +- .../Difficulty/TaikoPerformanceCalculator.cs | 16 ++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 .idea/.idea.osu/.idea/discord.xml diff --git a/.idea/.idea.osu/.idea/discord.xml b/.idea/.idea.osu/.idea/discord.xml new file mode 100644 index 0000000000..30bab2abb1 --- /dev/null +++ b/.idea/.idea.osu/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 6a07d49f98..3585393bbb 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators return 2; } - return 5; + return 4; } /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index fe3dd1fad1..63c18e5709 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; // We are disabling some HD and/or FL Bonus for converts for now due to them having low pattern difficulty, and thus being easy to memorize. - bool readingBonusEnabled = score.BeatmapInfo.Ruleset.OnlineID == 1; + bool rulesetTaiko = score.BeatmapInfo.Ruleset.OnlineID == 1; double multiplier = 1.13; @@ -52,8 +52,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes, readingBonusEnabled); - double accuracyValue = computeAccuracyValue(score, taikoAttributes, readingBonusEnabled); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, rulesetTaiko); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, rulesetTaiko); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) + if (score.Mods.Any(m => m is ModHidden) && rulesetTaiko) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficultyValue * Math.Pow(score.Accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) { if (attributes.GreatHitWindow <= 0) return 0; @@ -104,8 +104,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty accuracyValue *= lengthBonus; // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) - accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus); + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && rulesetTaiko) + accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus); return accuracyValue; } From 6752655b5a181b05065d22a0e13da3714a5ba588 Mon Sep 17 00:00:00 2001 From: Jay L Date: Sun, 2 Oct 2022 16:08:14 +1000 Subject: [PATCH 007/261] xml, remove speedbonus cap --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 6 ++---- .../Difficulty/TaikoPerformanceCalculator.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 3585393bbb..3326d72588 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -16,10 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// The interval between the current and previous note hit using the same key. private static double speedBonus(double interval) { - // Cap to 600bpm 1/4, 25ms note interval, 50ms key interval - // Interval will be capped at a very small value to avoid infinite/negative speed bonuses. - // TODO - This is a temporary measure as we need to implement methods of detecting playstyle-abuse of SpeedBonus. - interval = Math.Max(interval, 50); + // Interval is capped at a very small value to prevent infinite values. + interval = Math.Max(interval, 1); return 30 / interval; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 63c18e5709..b9a9dacddc 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (totalSuccessfulHits > 0) effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; - // We are disabling some HD and/or FL Bonus for converts for now due to them having low pattern difficulty, and thus being easy to memorize. + // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked. bool rulesetTaiko = score.BeatmapInfo.Ruleset.OnlineID == 1; double multiplier = 1.13; From c933b62df63ccd4b6fdf78e49622748902e2723c Mon Sep 17 00:00:00 2001 From: vun Date: Mon, 3 Oct 2022 14:16:53 +0800 Subject: [PATCH 008/261] Correct xmldoc --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 3326d72588..55dce4e9b3 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// /// Determines the number of fingers available to hit the current . - /// Any mono notes that is more than 0.5s apart from note of the other colour will be considered to have more - /// than 2 fingers available, since players can move their hand over to hit the same key with multiple fingers. + /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2 + /// fingers available, since players can hit the same key with multiple fingers. /// private static int availableFingersFor(TaikoDifficultyHitObject hitObject) { From 25976e1f105ab36e185fa9ee8d274e20c2a733d7 Mon Sep 17 00:00:00 2001 From: vun Date: Mon, 3 Oct 2022 14:20:01 +0800 Subject: [PATCH 009/261] Correct xmldocs --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 11 ++++++----- osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs | 3 --- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 55dce4e9b3..59b61f47d1 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -11,9 +11,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators public class StaminaEvaluator { /// - /// Applies a speed bonus dependent on the time since the last hit performed using this key. + /// Applies a speed bonus dependent on the time since the last hit performed using this finger. /// - /// The interval between the current and previous note hit using the same key. + /// The interval between the current and previous note hit using the same finger. private static double speedBonus(double interval) { // Interval is capped at a very small value to prevent infinite values. @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// /// Evaluates the minimum mechanical stamina required to play the current object. This is calculated using the - /// maximum possible interval between two hits using the same key, by alternating 2 keys for each colour. + /// maximum possible interval between two hits using the same key, by alternating available fingers for each colour. /// public static double EvaluateDifficultyOf(DifficultyHitObject current) { @@ -56,13 +56,14 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators return 0.0; } - // Find the previous hit object hit by the current key, which is two notes of the same colour prior. + // Find the previous hit object hit by the current finger, which is n notes prior, n being the number of + // available fingers. TaikoDifficultyHitObject taikoCurrent = (TaikoDifficultyHitObject)current; TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(availableFingersFor(taikoCurrent) - 1); if (keyPrevious == null) { - // There is no previous hit object hit by the current key + // There is no previous hit object hit by the current finger return 0.0; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs index 344004bcf6..d04c028fec 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs @@ -13,9 +13,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills /// /// Calculates the stamina coefficient of taiko difficulty. /// - /// - /// The reference play style chosen uses two hands, with full alternating (the hand changes after every hit). - /// public class Stamina : StrainDecaySkill { protected override double SkillMultiplier => 1.1; From 7e578f868c6eed983485c29f99874d786714720c Mon Sep 17 00:00:00 2001 From: Jay L Date: Mon, 3 Oct 2022 16:55:11 +1000 Subject: [PATCH 010/261] remove idea plugin xml --- .idea/.idea.osu/.idea/discord.xml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .idea/.idea.osu/.idea/discord.xml diff --git a/.idea/.idea.osu/.idea/discord.xml b/.idea/.idea.osu/.idea/discord.xml deleted file mode 100644 index 30bab2abb1..0000000000 --- a/.idea/.idea.osu/.idea/discord.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file From 47781a8f94ae17baf44dda250e32bfdfad7eecd6 Mon Sep 17 00:00:00 2001 From: vun Date: Mon, 3 Oct 2022 17:31:45 +0800 Subject: [PATCH 011/261] Fix code inspect issues and SR test cases --- .../TaikoDifficultyCalculatorTest.cs | 8 ++++---- .../Difficulty/Evaluators/StaminaEvaluator.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs index 425f72cadc..5685ac0f60 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs @@ -16,13 +16,13 @@ namespace osu.Game.Rulesets.Taiko.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; - [TestCase(3.1098944660126882d, 200, "diffcalc-test")] - [TestCase(3.1098944660126882d, 200, "diffcalc-test-strong")] + [TestCase(3.0920212594351191d, 200, "diffcalc-test")] + [TestCase(3.0920212594351191d, 200, "diffcalc-test-strong")] public void Test(double expectedStarRating, int expectedMaxCombo, string name) => base.Test(expectedStarRating, expectedMaxCombo, name); - [TestCase(4.0974106752474251d, 200, "diffcalc-test")] - [TestCase(4.0974106752474251d, 200, "diffcalc-test-strong")] + [TestCase(4.0789820318081444d, 200, "diffcalc-test")] + [TestCase(4.0789820318081444d, 200, "diffcalc-test-strong")] public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name) => Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime()); diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 59b61f47d1..84d5de4c63 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// /// Determines the number of fingers available to hit the current . - /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2 + /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2 /// fingers available, since players can hit the same key with multiple fingers. /// private static int availableFingersFor(TaikoDifficultyHitObject hitObject) From 122064d03fcdb4fa65dd7ccbbb20eebd4148a33e Mon Sep 17 00:00:00 2001 From: vun Date: Sun, 9 Oct 2022 07:09:05 +0800 Subject: [PATCH 012/261] Minor refactoring to reduce amount of looping --- .../Colour/Data/AlternatingMonoPattern.cs | 6 ------ .../Colour/Data/RepeatingHitPatterns.cs | 6 ------ .../Colour/TaikoColourDifficultyPreprocessor.cs | 12 ++---------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs index bc6e02319d..7910a8262b 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data { @@ -32,11 +31,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => MonoStreaks[0].FirstHitObject; - /// - /// All s in this . - /// - public IEnumerable AllHitObjects => MonoStreaks.SelectMany(streak => streak.HitObjects); - /// /// Determine if this is a repetition of another . This /// is a strict comparison and is true if and only if the colour sequence is exactly the same. diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs index 9e3d9a21b2..468a9ab876 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data @@ -28,11 +27,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => AlternatingMonoPatterns[0].FirstHitObject; - /// - /// All s in this . - /// - public IEnumerable AllHitObjects => AlternatingMonoPatterns.SelectMany(pattern => pattern.AllHitObjects); - /// /// The previous . This is used to determine the repetition interval. /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs index 500078a879..18a299ae92 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs @@ -24,11 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour // Assign indexing and encoding data to all relevant objects. foreach (var repeatingHitPattern in hitPatterns) { - foreach (var hitObject in repeatingHitPattern.AllHitObjects) - { - hitObject.Colour.RepeatingHitPattern = repeatingHitPattern; - } - // The outermost loop is kept a ForEach loop since it doesn't need index information, and we want to // keep i and j for AlternatingMonoPattern's and MonoStreak's index respectively, to keep it in line with // documentation. @@ -38,11 +33,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour monoPattern.Parent = repeatingHitPattern; monoPattern.Index = i; - foreach (var hitObject in monoPattern.AllHitObjects) - { - hitObject.Colour.AlternatingMonoPattern = monoPattern; - } - for (int j = 0; j < monoPattern.MonoStreaks.Count; ++j) { MonoStreak monoStreak = monoPattern.MonoStreaks[j]; @@ -51,6 +41,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour foreach (var hitObject in monoStreak.HitObjects) { + hitObject.Colour.RepeatingHitPattern = repeatingHitPattern; + hitObject.Colour.AlternatingMonoPattern = monoPattern; hitObject.Colour.MonoStreak = monoStreak; } } From 4149235e63173f374a80a7235411ef72588c455b Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 5 Oct 2022 17:50:36 +0900 Subject: [PATCH 013/261] Limit minimum brightness of combo colours --- osu.Game/Configuration/OsuConfigManager.cs | 4 +- osu.Game/Graphics/OsuColour.cs | 167 ++++++++++++++++++ .../Sections/Gameplay/BeatmapSettings.cs | 6 + .../Objects/Drawables/DrawableHitObject.cs | 14 +- 4 files changed, 189 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index e3bfb6b1e9..b433d81f31 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,6 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); + SetDefault(OsuSetting.ComboColourBrightness, 0.7f, 0f, 1f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -370,6 +371,7 @@ namespace osu.Game.Configuration DiscordRichPresence, AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, - LastProcessedMetadataId + LastProcessedMetadataId, + ComboColourBrightness } } diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 91161d5c71..bd0604bb76 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -229,6 +229,173 @@ namespace osu.Game.Graphics return Gray(brightness > 0.5f ? 0.2f : 0.9f); } + /// + /// Converts RGBA to HSPA. + /// + public static Color4 ToHSPA(Color4 colour) + { + const float p_r = 0.299f; + const float p_g = 0.587f; + const float p_b = 0.114f; + + Color4 result = new Color4 + { + A = colour.A, + B = MathF.Sqrt(colour.R * colour.R * p_r + colour.G * colour.G * p_g + colour.B + colour.B * p_b) + }; + + if (colour.R == colour.G && colour.R == colour.B) + return result; + + if (colour.R >= colour.G && colour.R >= colour.B) + { + if (colour.B >= colour.G) + { + result.R = 6f / 6f - 1f / 6f * (colour.B - colour.G) / (colour.R - colour.G); + result.G = 1f - colour.G / colour.R; + } + else + { + result.R = 0f / 6f + 1f / 6f * (colour.G - colour.B) / (colour.R - colour.B); + result.G = 1f - colour.B / colour.R; + } + } + else if (colour.G >= colour.R && colour.G >= colour.B) + { + if (colour.R >= colour.B) + { + result.R = 2f / 6f - 1f / 6f * (colour.R - colour.B) / (colour.G - colour.B); + result.G = 1f - colour.B / colour.G; + } + else + { + result.R = 2f / 6f + 1f / 6f * (colour.B - colour.R) / (colour.G - colour.R); + result.G = 1f - colour.R / colour.G; + } + } + else + { + if (colour.G >= colour.R) + { + result.R = 4f / 6f - 1f / 6f * (colour.G - colour.R) / (colour.B - colour.R); + result.G = 1f - colour.R / colour.B; + } + else + { + result.R = 4f / 6f + 1f / 6f * (colour.R - colour.G) / (colour.B - colour.G); + result.G = 1f - colour.G / colour.B; + } + } + + return result; + } + + public static Color4 FromHSPA(Color4 colour) + { + const float p_r = 0.299f; + const float p_g = 0.587f; + const float p_b = 0.114f; + + float minOverMax = 1f - colour.G; + + Color4 result = new Color4 { A = colour.A }; + + if (minOverMax > 0f) + { + float part = 1f + colour.R * (1f / minOverMax - 1f); + + if (colour.R < 1f / 6f) + { + colour.R = 6f * (colour.R - 0f / 6f); + result.B = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); + result.R = result.B / minOverMax; + result.G = result.B + colour.R * (result.R - result.B); + } + else if (colour.R < 2f / 6f) + { + colour.R = 6f * (-colour.R + 2f / 6f); + result.B = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); + result.G = result.B / minOverMax; + result.R = result.B + colour.R * (result.R - result.B); + } + else if (colour.R < 3f / 6f) + { + colour.R = 6f * (colour.R - 2f / 6f); + result.R = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); + result.G = result.R / minOverMax; + result.B = result.R + colour.R * (result.G - result.R); + } + else if (colour.R < 4f / 6f) + { + colour.R = 6f * (-colour.R + 4f / 6f); + result.R = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); + result.B = result.R / minOverMax; + result.G = result.R + colour.R * (result.B - result.R); + } + else if (colour.R < 5f / 6f) + { + colour.R = 6f * (colour.R - 4f / 6f); + result.G = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); + result.B = result.G / minOverMax; + result.R = result.G + colour.R * (result.B - result.G); + } + else + { + colour.R = 6f * (-colour.R + 6f / 6f); + result.G = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); + result.R = result.G / minOverMax; + result.B = result.G + colour.R * (result.R - result.G); + } + } + else + { + if (colour.R < 1f / 6f) + { + colour.R = 6f * (colour.R - 0f / 6f); + result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_g * colour.R * colour.R)); + result.G = result.R * colour.R; + result.B = 0f; + } + else if (colour.R < 2f / 6f) + { + colour.R = 6f * (-colour.R + 2f / 6f); + result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_r * colour.R * colour.R)); + result.R = result.G * colour.R; + result.B = 0f; + } + else if (colour.R < 3f / 6f) + { + colour.R = 6f * (colour.R - 2f / 6f); + result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_b * colour.R * colour.R)); + result.B = result.G * colour.R; + result.R = 0f; + } + else if (colour.R < 4f / 6f) + { + colour.R = 6f * (-colour.R + 4f / 6f); + result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_g * colour.R * colour.R)); + result.G = result.B * colour.R; + result.R = 0f; + } + else if (colour.R < 5f / 6f) + { + colour.R = 6f * (colour.R - 4f / 6f); + result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_r * colour.R * colour.R)); + result.R = result.B * colour.R; + result.G = 0f; + } + else + { + colour.R = 6f * (-colour.R + 6f / 6f); + result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_b * colour.R * colour.R)); + result.B = result.R * colour.R; + result.G = 0f; + } + } + + return result; + } + public readonly Color4 TeamColourRed = Color4Extensions.FromHex("#AA1414"); public readonly Color4 TeamColourBlue = Color4Extensions.FromHex("#1462AA"); diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index becb7aa80f..16b7b74f38 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -40,6 +40,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, + new SettingsSlider + { + LabelText = "Combo colour brightness", + Current = config.GetBindable(OsuSetting.ComboColourBrightness), + DisplayAsPercentage = true + } }; } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index dec68a6c22..0ef15ed5c2 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.Primitives; using osu.Framework.Threading; using osu.Game.Audio; using osu.Game.Configuration; +using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Pooling; using osu.Game.Rulesets.Objects.Types; @@ -128,6 +129,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Bindable comboIndexBindable = new Bindable(); private readonly Bindable positionalHitsoundsLevel = new Bindable(); + private readonly Bindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); protected override bool RequiresChildrenUpdate => true; @@ -171,6 +173,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); + config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); @@ -192,6 +195,8 @@ namespace osu.Game.Rulesets.Objects.Drawables comboIndexBindable.BindValueChanged(_ => UpdateComboColour()); comboIndexWithOffsetsBindable.BindValueChanged(_ => UpdateComboColour(), true); + comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); + // Apply transforms updateState(State.Value, true); } @@ -519,7 +524,14 @@ namespace osu.Game.Rulesets.Objects.Drawables { if (!(HitObject is IHasComboInformation combo)) return; - AccentColour.Value = combo.GetComboColour(CurrentSkin); + Color4 colour = combo.GetComboColour(CurrentSkin); + + // Normalise the combo colour to the given brightness level. + colour = OsuColour.ToHSPA(colour); + colour.B = comboColourBrightness.Value; + colour = OsuColour.FromHSPA(colour); + + AccentColour.Value = colour; } /// From aa8040d69675ef646a4bc8f2fea0db70fb00e574 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 13 Oct 2022 15:52:06 +0300 Subject: [PATCH 014/261] Add hover box to beatmap card icon button --- .../Cards/Buttons/BeatmapCardIconButton.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index c5b251cc2b..de75fceec8 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -4,13 +4,16 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osuTK; +using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { @@ -59,6 +62,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons protected override Container Content => content; private readonly Container content; + private readonly Box hover; protected BeatmapCardIconButton() { @@ -69,6 +73,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { RelativeSizeAxes = Axes.Both, Masking = true, + CornerRadius = BeatmapCard.CORNER_RADIUS, Origin = Anchor.Centre, Anchor = Anchor.Centre, Children = new Drawable[] @@ -76,8 +81,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons Icon = new SpriteIcon { Origin = Anchor.Centre, - Anchor = Anchor.Centre - } + Anchor = Anchor.Centre, + }, + hover = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White.Opacity(0.1f), + Blending = BlendingParameters.Additive, + }, } }); @@ -116,8 +127,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { bool isHovered = IsHovered && Enabled.Value; - content.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); - content.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); + hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint); + Icon.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); + Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); } } } From 6c316bcc9e8746104b6875da8efecf0e668d8406 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 13 Oct 2022 15:52:20 +0300 Subject: [PATCH 015/261] Make beatmap card icon buttons fill up to the area --- .../TestSceneBeatmapCardDownloadButton.cs | 3 ++- .../TestSceneBeatmapCardFavouriteButton.cs | 12 ++++++++++-- .../Drawables/Cards/BeatmapCardExtra.cs | 1 - .../Drawables/Cards/BeatmapCardNormal.cs | 1 - .../Cards/Buttons/BeatmapCardIconButton.cs | 1 - .../Cards/CollapsibleButtonContainer.cs | 19 ++++++++++--------- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs index 10515fd95f..82e18e45bb 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs @@ -59,8 +59,9 @@ namespace osu.Game.Tests.Visual.Beatmaps { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Size = new Vector2(25f, 50f), + Scale = new Vector2(2f), State = { Value = DownloadState.NotDownloaded }, - Scale = new Vector2(2) }; }); } diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs index 2fe2264348..9540d9e4f7 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs @@ -37,7 +37,11 @@ namespace osu.Game.Tests.Visual.Beatmaps beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value); beatmapSetInfo.HasFavourited = favourited; }); - AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) }); + AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) + { + Size = new Vector2(25f, 50f), + Scale = new Vector2(2f), + }); assertCorrectIcon(favourited); AddAssert("correct tooltip text", () => button.TooltipText == (favourited ? BeatmapsetsStrings.ShowDetailsUnfavourite : BeatmapsetsStrings.ShowDetailsFavourite)); @@ -51,7 +55,11 @@ namespace osu.Game.Tests.Visual.Beatmaps BeatmapFavouriteAction? lastRequestAction = null; AddStep("create beatmap set", () => beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value)); - AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) }); + AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) + { + Size = new Vector2(25f, 50f), + Scale = new Vector2(2f), + }); assertCorrectIcon(false); diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs index 4b9e5d9ae4..646c990564 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs @@ -81,7 +81,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards FavouriteState = { BindTarget = FavouriteState }, ButtonsCollapsedWidth = CORNER_RADIUS, ButtonsExpandedWidth = 30, - ButtonsPadding = new MarginPadding { Vertical = 35 }, Children = new Drawable[] { new FillFlowContainer diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs index d9ce64879f..addc88700c 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs @@ -82,7 +82,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards FavouriteState = { BindTarget = FavouriteState }, ButtonsCollapsedWidth = CORNER_RADIUS, ButtonsExpandedWidth = 30, - ButtonsPadding = new MarginPadding { Vertical = 17.5f }, Children = new Drawable[] { new FillFlowContainer diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index de75fceec8..a4beab02ed 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -92,7 +92,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons } }); - Size = new Vector2(24); IconSize = 12; } diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index 107c126eb5..5ace3233e2 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -48,12 +48,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards } } - public MarginPadding ButtonsPadding - { - get => buttons.Padding; - set => buttons.Padding = value; - } - protected override Container Content => mainContent; private readonly Container background; @@ -104,25 +98,32 @@ namespace osu.Game.Beatmaps.Drawables.Cards Child = buttons = new Container { RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(3), Children = new BeatmapCardIconButton[] { new FavouriteButton(beatmapSet) { Current = FavouriteState, Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.48f, }, new DownloadButton(beatmapSet) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - State = { BindTarget = downloadTracker.State } + State = { BindTarget = downloadTracker.State }, + RelativeSizeAxes = Axes.Both, + Height = 0.48f, }, new GoToBeatmapButton(beatmapSet) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - State = { BindTarget = downloadTracker.State } + State = { BindTarget = downloadTracker.State }, + RelativeSizeAxes = Axes.Both, + Height = 0.48f, } } } From ef72b66dad05a31ed45c979d9e8468d0a12c4e16 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 13 Oct 2022 16:09:50 +0300 Subject: [PATCH 016/261] Remove beatmap card background workaround to fix broken corners --- .../Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index 5ace3233e2..f70694bdda 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -80,9 +80,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards RelativeSizeAxes = Axes.Both, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - // workaround for masking artifacts at the top & bottom of card, - // which become especially visible on downloaded beatmaps (when the icon area has a lime background). - Padding = new MarginPadding { Vertical = 1 }, Child = new Box { RelativeSizeAxes = Axes.Both, From 3e5e717fce3a47983793f60ef8147aa624178b84 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 Oct 2022 01:59:55 +0300 Subject: [PATCH 017/261] Add failing test cases --- .../TestSceneModSelectOverlay.cs | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 4c43a2fdcd..0292ce5905 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Mods; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; @@ -338,26 +339,36 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestRulesetChanges() + public void TestCommonModsMaintainedOnRulesetChange() { createScreen(); changeRuleset(0); - var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail); - - AddStep("set mods externally", () => { SelectedMods.Value = new[] { noFailMod }; }); + AddStep("select relax mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod() }); changeRuleset(0); + AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModRelax); - AddAssert("ensure mods still selected", () => SelectedMods.Value.SingleOrDefault(m => m is OsuModNoFail) != null); + changeRuleset(2); + AddAssert("catch variant selected", () => SelectedMods.Value.SingleOrDefault() is CatchModRelax); changeRuleset(3); + AddAssert("no mod selected", () => SelectedMods.Value.Count == 0); + } - AddAssert("ensure mods not selected", () => SelectedMods.Value.Count == 0); - + [Test] + public void TestUncommonModsDiscardedOnRulesetChange() + { + createScreen(); changeRuleset(0); - AddAssert("ensure mods not selected", () => SelectedMods.Value.Count == 0); + AddStep("select single tap mod", () => SelectedMods.Value = new[] { new OsuModSingleTap() }); + + changeRuleset(0); + AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModSingleTap); + + changeRuleset(3); + AddAssert("no mod selected", () => SelectedMods.Value.Count == 0); } [Test] From 739b21ab3bb3245910ce1115e6f6003fa589e2c1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 Oct 2022 02:02:24 +0300 Subject: [PATCH 018/261] Maintain mod selection on ruleset change for common mods --- osu.Game/OsuGameBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 478f154d58..662d165580 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -586,11 +586,16 @@ namespace osu.Game return; } + var previouslySelectedMods = SelectedMods.Value.ToArray(); + if (!SelectedMods.Disabled) SelectedMods.Value = Array.Empty(); AvailableMods.Value = dict; + if (!SelectedMods.Disabled) + SelectedMods.Value = previouslySelectedMods.Select(m => instance.CreateModFromAcronym(m.Acronym)).Where(m => m != null).ToArray(); + void revertRulesetChange() => Ruleset.Value = r.OldValue?.Available == true ? r.OldValue : RulesetStore.AvailableRulesets.First(); } From 01c65d3cc1281da68e501506785724ac5e2f9f58 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 Oct 2022 02:16:23 +0300 Subject: [PATCH 019/261] Remove seemingly unnecessary/leftover code --- osu.Game/Screens/Select/SongSelect.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index ece94b5365..f5a058e945 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -502,8 +502,6 @@ namespace osu.Game.Screens.Select if (transferRulesetValue()) { - Mods.Value = Array.Empty(); - // transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it. // The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here. // We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert). From b43bae122c1ec719b074b7f2e1ac39cbda338541 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 13:40:48 +0900 Subject: [PATCH 020/261] Fix incorrect porting of code --- osu.Game/Graphics/OsuColour.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index bd0604bb76..0f055856d3 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -302,11 +302,10 @@ namespace osu.Game.Graphics if (minOverMax > 0f) { - float part = 1f + colour.R * (1f / minOverMax - 1f); - if (colour.R < 1f / 6f) { colour.R = 6f * (colour.R - 0f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.B = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); result.R = result.B / minOverMax; result.G = result.B + colour.R * (result.R - result.B); @@ -314,13 +313,15 @@ namespace osu.Game.Graphics else if (colour.R < 2f / 6f) { colour.R = 6f * (-colour.R + 2f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.B = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); result.G = result.B / minOverMax; - result.R = result.B + colour.R * (result.R - result.B); + result.R = result.B + colour.R * (result.G - result.B); } else if (colour.R < 3f / 6f) { colour.R = 6f * (colour.R - 2f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.R = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); result.G = result.R / minOverMax; result.B = result.R + colour.R * (result.G - result.R); @@ -328,6 +329,7 @@ namespace osu.Game.Graphics else if (colour.R < 4f / 6f) { colour.R = 6f * (-colour.R + 4f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.R = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); result.B = result.R / minOverMax; result.G = result.R + colour.R * (result.B - result.R); @@ -335,6 +337,7 @@ namespace osu.Game.Graphics else if (colour.R < 5f / 6f) { colour.R = 6f * (colour.R - 4f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.G = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); result.B = result.G / minOverMax; result.R = result.G + colour.R * (result.B - result.G); @@ -342,6 +345,7 @@ namespace osu.Game.Graphics else { colour.R = 6f * (-colour.R + 6f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.G = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); result.R = result.G / minOverMax; result.B = result.G + colour.R * (result.R - result.G); From 15db65c037c22f672272733fb4b8e1d9a25f731b Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 14:12:48 +0900 Subject: [PATCH 021/261] Extract to struct, add dictionary term --- osu.Game/Graphics/HSPAColour.cs | 200 ++++++++++++++++++ osu.Game/Graphics/OsuColour.cs | 171 --------------- .../Objects/Drawables/DrawableHitObject.cs | 4 +- osu.sln.DotSettings | 1 + 4 files changed, 202 insertions(+), 174 deletions(-) create mode 100644 osu.Game/Graphics/HSPAColour.cs diff --git a/osu.Game/Graphics/HSPAColour.cs b/osu.Game/Graphics/HSPAColour.cs new file mode 100644 index 0000000000..5e3bc29b7e --- /dev/null +++ b/osu.Game/Graphics/HSPAColour.cs @@ -0,0 +1,200 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osuTK.Graphics; + +namespace osu.Game.Graphics +{ + public struct HSPAColour + { + private const float p_r = 0.299f; + private const float p_g = 0.587f; + private const float p_b = 0.114f; + + /// + /// The hue. + /// + public float H; + + /// + /// The saturation. + /// + public float S; + + /// + /// The perceived brightness of this colour. + /// + public float P; + + /// + /// The alpha. + /// + public float A; + + public HSPAColour(float h, float s, float p, float a) + { + H = h; + S = s; + P = p; + A = a; + } + + public HSPAColour(Color4 colour) + { + H = 0; + S = 0; + P = MathF.Sqrt(colour.R * colour.R * p_r + colour.G * colour.G * p_g + colour.B + colour.B * p_b); + A = colour.A; + + if (colour.R == colour.G && colour.R == colour.B) + return; + + if (colour.R >= colour.G && colour.R >= colour.B) + { + if (colour.B >= colour.G) + { + H = 6f / 6f - 1f / 6f * (colour.B - colour.G) / (colour.R - colour.G); + S = 1f - colour.G / colour.R; + } + else + { + H = 0f / 6f + 1f / 6f * (colour.G - colour.B) / (colour.R - colour.B); + S = 1f - colour.B / colour.R; + } + } + else if (colour.G >= colour.R && colour.G >= colour.B) + { + if (colour.R >= colour.B) + { + H = 2f / 6f - 1f / 6f * (colour.R - colour.B) / (colour.G - colour.B); + S = 1f - colour.B / colour.G; + } + else + { + H = 2f / 6f + 1f / 6f * (colour.B - colour.R) / (colour.G - colour.R); + S = 1f - colour.R / colour.G; + } + } + else + { + if (colour.G >= colour.R) + { + H = 4f / 6f - 1f / 6f * (colour.G - colour.R) / (colour.B - colour.R); + S = 1f - colour.R / colour.B; + } + else + { + H = 4f / 6f + 1f / 6f * (colour.R - colour.G) / (colour.B - colour.G); + S = 1f - colour.G / colour.B; + } + } + } + + public Color4 ToColor4() + { + float minOverMax = 1f - S; + + Color4 result = new Color4 { A = A }; + + if (minOverMax > 0f) + { + if (H < 1f / 6f) + { + H = 6f * (H - 0f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.B = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); + result.R = result.B / minOverMax; + result.G = result.B + H * (result.R - result.B); + } + else if (H < 2f / 6f) + { + H = 6f * (-H + 2f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.B = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); + result.G = result.B / minOverMax; + result.R = result.B + H * (result.G - result.B); + } + else if (H < 3f / 6f) + { + H = 6f * (H - 2f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.R = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); + result.G = result.R / minOverMax; + result.B = result.R + H * (result.G - result.R); + } + else if (H < 4f / 6f) + { + H = 6f * (-H + 4f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.R = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); + result.B = result.R / minOverMax; + result.G = result.R + H * (result.B - result.R); + } + else if (H < 5f / 6f) + { + H = 6f * (H - 4f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.G = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); + result.B = result.G / minOverMax; + result.R = result.G + H * (result.B - result.G); + } + else + { + H = 6f * (-H + 6f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.G = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); + result.R = result.G / minOverMax; + result.B = result.G + H * (result.R - result.G); + } + } + else + { + if (H < 1f / 6f) + { + H = 6f * (H - 0f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_g * H * H)); + result.G = result.R * H; + result.B = 0f; + } + else if (H < 2f / 6f) + { + H = 6f * (-H + 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_r * H * H)); + result.R = result.G * H; + result.B = 0f; + } + else if (H < 3f / 6f) + { + H = 6f * (H - 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_b * H * H)); + result.B = result.G * H; + result.R = 0f; + } + else if (H < 4f / 6f) + { + H = 6f * (-H + 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_g * H * H)); + result.G = result.B * H; + result.R = 0f; + } + else if (H < 5f / 6f) + { + H = 6f * (H - 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_r * H * H)); + result.R = result.B * H; + result.G = 0f; + } + else + { + H = 6f * (-H + 6f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_b * H * H)); + result.B = result.R * H; + result.G = 0f; + } + } + + return result; + } + } +} diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 0f055856d3..91161d5c71 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -229,177 +229,6 @@ namespace osu.Game.Graphics return Gray(brightness > 0.5f ? 0.2f : 0.9f); } - /// - /// Converts RGBA to HSPA. - /// - public static Color4 ToHSPA(Color4 colour) - { - const float p_r = 0.299f; - const float p_g = 0.587f; - const float p_b = 0.114f; - - Color4 result = new Color4 - { - A = colour.A, - B = MathF.Sqrt(colour.R * colour.R * p_r + colour.G * colour.G * p_g + colour.B + colour.B * p_b) - }; - - if (colour.R == colour.G && colour.R == colour.B) - return result; - - if (colour.R >= colour.G && colour.R >= colour.B) - { - if (colour.B >= colour.G) - { - result.R = 6f / 6f - 1f / 6f * (colour.B - colour.G) / (colour.R - colour.G); - result.G = 1f - colour.G / colour.R; - } - else - { - result.R = 0f / 6f + 1f / 6f * (colour.G - colour.B) / (colour.R - colour.B); - result.G = 1f - colour.B / colour.R; - } - } - else if (colour.G >= colour.R && colour.G >= colour.B) - { - if (colour.R >= colour.B) - { - result.R = 2f / 6f - 1f / 6f * (colour.R - colour.B) / (colour.G - colour.B); - result.G = 1f - colour.B / colour.G; - } - else - { - result.R = 2f / 6f + 1f / 6f * (colour.B - colour.R) / (colour.G - colour.R); - result.G = 1f - colour.R / colour.G; - } - } - else - { - if (colour.G >= colour.R) - { - result.R = 4f / 6f - 1f / 6f * (colour.G - colour.R) / (colour.B - colour.R); - result.G = 1f - colour.R / colour.B; - } - else - { - result.R = 4f / 6f + 1f / 6f * (colour.R - colour.G) / (colour.B - colour.G); - result.G = 1f - colour.G / colour.B; - } - } - - return result; - } - - public static Color4 FromHSPA(Color4 colour) - { - const float p_r = 0.299f; - const float p_g = 0.587f; - const float p_b = 0.114f; - - float minOverMax = 1f - colour.G; - - Color4 result = new Color4 { A = colour.A }; - - if (minOverMax > 0f) - { - if (colour.R < 1f / 6f) - { - colour.R = 6f * (colour.R - 0f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.B = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); - result.R = result.B / minOverMax; - result.G = result.B + colour.R * (result.R - result.B); - } - else if (colour.R < 2f / 6f) - { - colour.R = 6f * (-colour.R + 2f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.B = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); - result.G = result.B / minOverMax; - result.R = result.B + colour.R * (result.G - result.B); - } - else if (colour.R < 3f / 6f) - { - colour.R = 6f * (colour.R - 2f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.R = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); - result.G = result.R / minOverMax; - result.B = result.R + colour.R * (result.G - result.R); - } - else if (colour.R < 4f / 6f) - { - colour.R = 6f * (-colour.R + 4f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.R = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); - result.B = result.R / minOverMax; - result.G = result.R + colour.R * (result.B - result.R); - } - else if (colour.R < 5f / 6f) - { - colour.R = 6f * (colour.R - 4f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.G = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); - result.B = result.G / minOverMax; - result.R = result.G + colour.R * (result.B - result.G); - } - else - { - colour.R = 6f * (-colour.R + 6f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.G = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); - result.R = result.G / minOverMax; - result.B = result.G + colour.R * (result.R - result.G); - } - } - else - { - if (colour.R < 1f / 6f) - { - colour.R = 6f * (colour.R - 0f / 6f); - result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_g * colour.R * colour.R)); - result.G = result.R * colour.R; - result.B = 0f; - } - else if (colour.R < 2f / 6f) - { - colour.R = 6f * (-colour.R + 2f / 6f); - result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_r * colour.R * colour.R)); - result.R = result.G * colour.R; - result.B = 0f; - } - else if (colour.R < 3f / 6f) - { - colour.R = 6f * (colour.R - 2f / 6f); - result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_b * colour.R * colour.R)); - result.B = result.G * colour.R; - result.R = 0f; - } - else if (colour.R < 4f / 6f) - { - colour.R = 6f * (-colour.R + 4f / 6f); - result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_g * colour.R * colour.R)); - result.G = result.B * colour.R; - result.R = 0f; - } - else if (colour.R < 5f / 6f) - { - colour.R = 6f * (colour.R - 4f / 6f); - result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_r * colour.R * colour.R)); - result.R = result.B * colour.R; - result.G = 0f; - } - else - { - colour.R = 6f * (-colour.R + 6f / 6f); - result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_b * colour.R * colour.R)); - result.B = result.R * colour.R; - result.G = 0f; - } - } - - return result; - } - public readonly Color4 TeamColourRed = Color4Extensions.FromHex("#AA1414"); public readonly Color4 TeamColourBlue = Color4Extensions.FromHex("#1462AA"); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 0ef15ed5c2..4ba64687db 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -527,9 +527,7 @@ namespace osu.Game.Rulesets.Objects.Drawables Color4 colour = combo.GetComboColour(CurrentSkin); // Normalise the combo colour to the given brightness level. - colour = OsuColour.ToHSPA(colour); - colour.B = comboColourBrightness.Value; - colour = OsuColour.FromHSPA(colour); + colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); AccentColour.Value = colour; } diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 44df495929..154ad0fe8c 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -334,6 +334,7 @@ GL GLSL HID + HSPA HSV HTML HUD From 8a88339e787293a7b585acce105aaff236f2c565 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 14:37:24 +0900 Subject: [PATCH 022/261] Allow combo colour normalisation to be disabled --- osu.Game/Configuration/OsuConfigManager.cs | 3 +++ .../Sections/Gameplay/BeatmapSettings.cs | 23 +++++++++++++++++-- .../Objects/Drawables/DrawableHitObject.cs | 6 ++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b433d81f31..33e61372da 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,6 +175,8 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); + + SetDefault(OsuSetting.NormaliseComboColourBrightness, false); SetDefault(OsuSetting.ComboColourBrightness, 0.7f, 0f, 1f); } @@ -372,6 +374,7 @@ namespace osu.Game.Configuration AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, LastProcessedMetadataId, + NormaliseComboColourBrightness, ComboColourBrightness } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 16b7b74f38..0de8f6509f 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -4,6 +4,7 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; @@ -15,9 +16,15 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; + private readonly BindableFloat comboColourBrightness = new BindableFloat(); + private readonly BindableBool normaliseComboColourBrightness = new BindableBool(); + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); + config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); + Children = new Drawable[] { new SettingsCheckbox @@ -40,13 +47,25 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, + new SettingsCheckbox + { + LabelText = "Normalise combo colour brightness", + Current = normaliseComboColourBrightness + }, new SettingsSlider { LabelText = "Combo colour brightness", - Current = config.GetBindable(OsuSetting.ComboColourBrightness), - DisplayAsPercentage = true + Current = comboColourBrightness, + DisplayAsPercentage = true, } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + normaliseComboColourBrightness.BindValueChanged(normalise => comboColourBrightness.Disabled = !normalise.NewValue, true); + } } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4ba64687db..7e2f93dced 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -129,6 +129,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Bindable comboIndexBindable = new Bindable(); private readonly Bindable positionalHitsoundsLevel = new Bindable(); + private readonly Bindable normaliseComboColourBrightness = new Bindable(); private readonly Bindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); @@ -173,6 +174,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); + config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. @@ -195,6 +197,7 @@ namespace osu.Game.Rulesets.Objects.Drawables comboIndexBindable.BindValueChanged(_ => UpdateComboColour()); comboIndexWithOffsetsBindable.BindValueChanged(_ => UpdateComboColour(), true); + normaliseComboColourBrightness.BindValueChanged(_ => UpdateComboColour()); comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); // Apply transforms @@ -527,7 +530,8 @@ namespace osu.Game.Rulesets.Objects.Drawables Color4 colour = combo.GetComboColour(CurrentSkin); // Normalise the combo colour to the given brightness level. - colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); + if (normaliseComboColourBrightness.Value) + colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); AccentColour.Value = colour; } From c65a8a83f390d8bc49d0946cf4c1588b5afc185f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 15:52:09 +0300 Subject: [PATCH 023/261] Add basic UI for reporting --- .../Visual/Online/TestSceneCommentActions.cs | 9 ++- .../Overlays/Comments/CommentReportReason.cs | 14 ++++ osu.Game/Overlays/Comments/DrawableComment.cs | 13 +++- .../Overlays/Comments/ReportCommentPopover.cs | 78 +++++++++++++++++++ 4 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentReportReason.cs create mode 100644 osu.Game/Overlays/Comments/ReportCommentPopover.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index bf01d3b0ac..1f3e9dd54c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -10,6 +10,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Testing; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -42,9 +43,13 @@ namespace osu.Game.Tests.Visual.Online { base.Content.AddRange(new Drawable[] { - content = new OsuScrollContainer + new PopoverContainer() { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Child = content = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both + } }, dialogOverlay }); diff --git a/osu.Game/Overlays/Comments/CommentReportReason.cs b/osu.Game/Overlays/Comments/CommentReportReason.cs new file mode 100644 index 0000000000..e768214438 --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentReportReason.cs @@ -0,0 +1,14 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Overlays.Comments +{ + public enum CommentReportReason + { + Insults, + Spam, + UnwantedContent, + Nonsense, + Other + } +} diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 193d15064a..e675ceef4e 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -19,6 +19,8 @@ using System; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.IEnumerableExtensions; using System.Collections.Specialized; +using osu.Framework.Extensions; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; @@ -29,7 +31,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class DrawableComment : CompositeDrawable + public class DrawableComment : CompositeDrawable, IHasPopover { private const int avatar_size = 40; @@ -324,9 +326,9 @@ namespace osu.Game.Overlays.Comments makeDeleted(); if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) - { actionsContainer.AddLink("Delete", deleteComment); - } + else + actionsContainer.AddLink("Report", this.ShowPopover); if (Comment.IsTopLevel) { @@ -544,5 +546,10 @@ namespace osu.Game.Overlays.Comments return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? "deleted" : string.Empty; } } + + public Popover GetPopover() + { + return new ReportCommentPopover(Comment.Id); + } } } diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs new file mode 100644 index 0000000000..119b51a7d7 --- /dev/null +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -0,0 +1,78 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterfaceV2; +using osuTK; + +namespace osu.Game.Overlays.Comments +{ + public class ReportCommentPopover : OsuPopover + { + public readonly long ID; + private LabelledEnumDropdown reason = null!; + private LabelledTextBox info = null!; + private ShakeContainer shaker = null!; + + public ReportCommentPopover(long id) + { + ID = id; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Child = new FillFlowContainer + { + Direction = FillDirection.Vertical, + Width = 500, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(7), + Children = new Drawable[] + { + reason = new LabelledEnumDropdown + { + Label = "Reason" + }, + info = new LabelledTextBox + { + Label = "Additional info", + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = shaker = new ShakeContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = new RoundedButton + { + BackgroundColour = colours.Pink3, + Text = "Send report", + RelativeSizeAxes = Axes.X, + Action = send + } + } + } + } + }; + } + + private void send() + { + string infoValue = info.Current.Value; + var reasonValue = reason.Current.Value; + + if (reasonValue == CommentReportReason.Other && string.IsNullOrWhiteSpace(infoValue)) + { + shaker.Shake(); + return; + } + } + } +} From 7251d41deba1823276c129cb99e9d35823a1c094 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 16:15:28 +0300 Subject: [PATCH 024/261] Add request class --- .../API/Requests/CommentReportRequest.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 osu.Game/Online/API/Requests/CommentReportRequest.cs diff --git a/osu.Game/Online/API/Requests/CommentReportRequest.cs b/osu.Game/Online/API/Requests/CommentReportRequest.cs new file mode 100644 index 0000000000..2195d612f3 --- /dev/null +++ b/osu.Game/Online/API/Requests/CommentReportRequest.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Overlays.Comments; + +namespace osu.Game.Online.API.Requests +{ + public class CommentReportRequest : APIRequest + { + public readonly long CommentID; + public readonly CommentReportReason Reason; + public readonly string? Info; + + public CommentReportRequest(long commentID, CommentReportReason reason, string? info) + { + CommentID = commentID; + Reason = reason; + Info = info; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + + req.AddParameter(@"reportable_type", @"comment"); + req.AddParameter(@"reportable_id", $"{CommentID}"); + req.AddParameter(@"reason", Reason.ToString()); + if (!string.IsNullOrWhiteSpace(Info)) + req.AddParameter(@"comments", Info); + + return req; + } + + protected override string Target => @"reports"; + } +} From 3e9fd4c08c9dde11b6925ffa43ae3c1a486da50f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 16:26:25 +0300 Subject: [PATCH 025/261] Implement reporting flow --- osu.Game/Overlays/Comments/DrawableComment.cs | 28 ++++++++++++++++++- .../Overlays/Comments/ReportCommentPopover.cs | 11 ++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index e675ceef4e..f7f71788ee 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -27,6 +27,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Comments.Buttons; using osu.Game.Overlays.Dialog; +using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -73,6 +74,9 @@ namespace osu.Game.Overlays.Comments [Resolved] private IAPIProvider api { get; set; } = null!; + [Resolved(canBeNull: true)] + private NotificationOverlay? notificationOverlay { get; set; } + public DrawableComment(Comment comment) { Comment = comment; @@ -405,6 +409,28 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } + public void ReportComment(CommentReportReason reason, string comment) + { + actionsContainer.Hide(); + actionsLoading.Show(); + var request = new CommentReportRequest(Comment.Id, reason, comment); + request.Success += () => + { + actionsLoading.Hide(); + notificationOverlay?.Post(new SimpleNotification + { + Icon = FontAwesome.Solid.CheckCircle, + Text = "The comment reported successfully." + }); + }; + request.Failure += _ => + { + actionsLoading.Hide(); + actionsContainer.Show(); + }; + api.Queue(request); + } + protected override void LoadComplete() { ShowDeleted.BindValueChanged(show => @@ -549,7 +575,7 @@ namespace osu.Game.Overlays.Comments public Popover GetPopover() { - return new ReportCommentPopover(Comment.Id); + return new ReportCommentPopover(ReportComment); } } } diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 119b51a7d7..5f9e7ff45c 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -13,14 +15,14 @@ namespace osu.Game.Overlays.Comments { public class ReportCommentPopover : OsuPopover { - public readonly long ID; + private readonly Action action; private LabelledEnumDropdown reason = null!; private LabelledTextBox info = null!; private ShakeContainer shaker = null!; - public ReportCommentPopover(long id) + public ReportCommentPopover(Action action) { - ID = id; + this.action = action; } [BackgroundDependencyLoader] @@ -73,6 +75,9 @@ namespace osu.Game.Overlays.Comments shaker.Shake(); return; } + + this.HidePopover(); + action.Invoke(reasonValue, infoValue); } } } From dc0aa2295a6969172e736686892b3f59fb93e34d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 16:51:48 +0300 Subject: [PATCH 026/261] Add test --- .../Visual/Online/TestSceneCommentActions.cs | 85 +++++++++++++++++-- osu.Game/Overlays/Comments/DrawableComment.cs | 8 +- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 1f3e9dd54c..00ae59fa30 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -15,6 +15,7 @@ using osu.Framework.Testing; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -38,12 +39,14 @@ namespace osu.Game.Tests.Visual.Online private CommentsContainer commentsContainer = null!; + private readonly ManualResetEventSlim requestLock = new ManualResetEventSlim(); + [BackgroundDependencyLoader] private void load() { base.Content.AddRange(new Drawable[] { - new PopoverContainer() + new PopoverContainer { RelativeSizeAxes = Axes.Both, Child = content = new OsuScrollContainer @@ -85,8 +88,6 @@ namespace osu.Game.Tests.Visual.Online }); } - private readonly ManualResetEventSlim deletionPerformed = new ManualResetEventSlim(); - [Test] public void TestDeletion() { @@ -110,7 +111,7 @@ namespace osu.Game.Tests.Visual.Online }); AddStep("Setup request handling", () => { - deletionPerformed.Reset(); + requestLock.Reset(); dummyAPI.HandleRequest = request => { @@ -143,7 +144,7 @@ namespace osu.Game.Tests.Visual.Online Task.Run(() => { - deletionPerformed.Wait(10000); + requestLock.Wait(10000); req.TriggerSuccess(cb); }); @@ -154,7 +155,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Loading spinner shown", () => commentsContainer.ChildrenOfType().Any(d => d.IsPresent)); - AddStep("Complete request", () => deletionPerformed.Set()); + AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Comment is deleted locally", () => this.ChildrenOfType().Single(x => x.Comment.Id == 1).WasDeleted); } @@ -209,6 +210,78 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestReport() + { + const string report_text = "I don't like this comment"; + DrawableComment? targetComment = null; + CommentReportRequest? request = null; + + addTestComments(); + AddUntilStep("Comment exists", () => + { + var comments = this.ChildrenOfType(); + targetComment = comments.SingleOrDefault(x => x.Comment.Id == 2); + return targetComment != null; + }); + AddStep("Setup request handling", () => + { + requestLock.Reset(); + + dummyAPI.HandleRequest = r => + { + if (!(r is CommentReportRequest req)) + return false; + + Task.Run(() => + { + request = req; + requestLock.Wait(10000); + req.TriggerSuccess(); + }); + + return true; + }; + }); + AddStep("Click the button", () => + { + var btn = targetComment.ChildrenOfType().Single(x => x.Text == "Report"); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + AddStep("Select \"other\"", () => + { + var field = this.ChildrenOfType>().Single(); + field.Current.Value = CommentReportReason.Other; + }); + AddStep("Try to report", () => + { + var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + AddWaitStep("Wait", 3); + AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); + AddStep("Enter some text", () => + { + var field = this.ChildrenOfType().Single(); + field.Current.Value = report_text; + }); + AddStep("Try to report", () => + { + var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + AddWaitStep("Wait", 3); + AddAssert("Overlay closed", () => !this.ChildrenOfType().Any()); + AddAssert("Loading spinner shown", () => targetComment.ChildrenOfType().Any(d => d.IsPresent)); + AddStep("Complete request", () => requestLock.Set()); + AddUntilStep("Request sent", () => request != null); + AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Info == report_text && request.Reason == CommentReportReason.Other); + AddUntilStep("Buttons hidden", () => !targetComment.ChildrenOfType().Single(x => x.Name == @"Actions buttons").IsPresent); + } + private void addTestComments() { AddStep("set up response", () => diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index f7f71788ee..362e0634c5 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -414,7 +414,7 @@ namespace osu.Game.Overlays.Comments actionsContainer.Hide(); actionsLoading.Show(); var request = new CommentReportRequest(Comment.Id, reason, comment); - request.Success += () => + request.Success += () => Schedule(() => { actionsLoading.Hide(); notificationOverlay?.Post(new SimpleNotification @@ -422,12 +422,12 @@ namespace osu.Game.Overlays.Comments Icon = FontAwesome.Solid.CheckCircle, Text = "The comment reported successfully." }); - }; - request.Failure += _ => + }); + request.Failure += _ => Schedule(() => { actionsLoading.Hide(); actionsContainer.Show(); - }; + }); api.Queue(request); } From 7d53d35bf619aa209391edd773d5c594d7bce15d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 15 Oct 2022 16:23:54 +0300 Subject: [PATCH 027/261] Remove duplicate & outdated test case --- .../SongSelect/TestScenePlaySongSelect.cs | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index cc8746959b..248bf9f5ed 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -538,36 +538,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("selection shown on wedge", () => songSelect!.CurrentBeatmapDetailsBeatmap.BeatmapInfo.MatchesOnlineID(target)); } - [Test] - public void TestRulesetChangeResetsMods() - { - createSongSelect(); - changeRuleset(0); - - changeMods(new OsuModHardRock()); - - int actionIndex = 0; - int modChangeIndex = 0; - int rulesetChangeIndex = 0; - - AddStep("change ruleset", () => - { - SelectedMods.ValueChanged += onModChange; - songSelect!.Ruleset.ValueChanged += onRulesetChange; - - Ruleset.Value = new TaikoRuleset().RulesetInfo; - - SelectedMods.ValueChanged -= onModChange; - songSelect!.Ruleset.ValueChanged -= onRulesetChange; - }); - - AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex); - AddAssert("empty mods", () => !SelectedMods.Value.Any()); - - void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; - void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex++; - } - [Test] public void TestModsRetainedBetweenSongSelect() { From 841e20c3363ebe2dd5e9fd0c408d7342ca78273d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 15 Oct 2022 17:16:08 +0300 Subject: [PATCH 028/261] Remove unused usings --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 248bf9f5ed..63532fdba8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; @@ -32,7 +31,6 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Taiko; using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Screens.Select; From 9822a092c4f11c46f8e185d029772eb5ef71d934 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 16 Oct 2022 19:50:55 +0300 Subject: [PATCH 029/261] Add localization for enum --- osu.Game/Overlays/Comments/CommentReportReason.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Overlays/Comments/CommentReportReason.cs b/osu.Game/Overlays/Comments/CommentReportReason.cs index e768214438..4fbec0164d 100644 --- a/osu.Game/Overlays/Comments/CommentReportReason.cs +++ b/osu.Game/Overlays/Comments/CommentReportReason.cs @@ -1,14 +1,26 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Localisation; +using osu.Game.Resources.Localisation.Web; + namespace osu.Game.Overlays.Comments { public enum CommentReportReason { + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsInsults))] Insults, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsSpam))] Spam, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsUnwantedContent))] UnwantedContent, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsNonsense))] Nonsense, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsOther))] Other } } From ba595ab8fa6f9d520e98f3adb46c53d98ed1ab00 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 16 Oct 2022 19:57:21 +0300 Subject: [PATCH 030/261] Display toast instead of notification --- osu.Game/Overlays/Comments/DrawableComment.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 362e0634c5..998f3b8e62 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -23,11 +23,12 @@ using osu.Framework.Extensions; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Comments.Buttons; using osu.Game.Overlays.Dialog; -using osu.Game.Overlays.Notifications; +using osu.Game.Overlays.OSD; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -75,7 +76,7 @@ namespace osu.Game.Overlays.Comments private IAPIProvider api { get; set; } = null!; [Resolved(canBeNull: true)] - private NotificationOverlay? notificationOverlay { get; set; } + private OnScreenDisplay? onScreenDisplay { get; set; } public DrawableComment(Comment comment) { @@ -417,11 +418,7 @@ namespace osu.Game.Overlays.Comments request.Success += () => Schedule(() => { actionsLoading.Hide(); - notificationOverlay?.Post(new SimpleNotification - { - Icon = FontAwesome.Solid.CheckCircle, - Text = "The comment reported successfully." - }); + onScreenDisplay?.Display(new ReportToast()); }); request.Failure += _ => Schedule(() => { @@ -577,5 +574,13 @@ namespace osu.Game.Overlays.Comments { return new ReportCommentPopover(ReportComment); } + + private class ReportToast : Toast + { + public ReportToast() + : base(UserInterfaceStrings.GeneralHeader, UsersStrings.ReportThanks, "") + { + } + } } } From e1785f73a28c3da1befcc9aa8dd1b41f3f8207d2 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 16 Oct 2022 20:14:05 +0300 Subject: [PATCH 031/261] Make report's comment not optional --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 2 +- osu.Game/Online/API/Requests/CommentReportRequest.cs | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 00ae59fa30..3515b5fb0a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -278,7 +278,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Loading spinner shown", () => targetComment.ChildrenOfType().Any(d => d.IsPresent)); AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); - AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Info == report_text && request.Reason == CommentReportReason.Other); + AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); AddUntilStep("Buttons hidden", () => !targetComment.ChildrenOfType().Single(x => x.Name == @"Actions buttons").IsPresent); } diff --git a/osu.Game/Online/API/Requests/CommentReportRequest.cs b/osu.Game/Online/API/Requests/CommentReportRequest.cs index 2195d612f3..3f57756ced 100644 --- a/osu.Game/Online/API/Requests/CommentReportRequest.cs +++ b/osu.Game/Online/API/Requests/CommentReportRequest.cs @@ -11,13 +11,13 @@ namespace osu.Game.Online.API.Requests { public readonly long CommentID; public readonly CommentReportReason Reason; - public readonly string? Info; + public readonly string Comment; - public CommentReportRequest(long commentID, CommentReportReason reason, string? info) + public CommentReportRequest(long commentID, CommentReportReason reason, string comment) { CommentID = commentID; Reason = reason; - Info = info; + Comment = comment; } protected override WebRequest CreateWebRequest() @@ -28,8 +28,7 @@ namespace osu.Game.Online.API.Requests req.AddParameter(@"reportable_type", @"comment"); req.AddParameter(@"reportable_id", $"{CommentID}"); req.AddParameter(@"reason", Reason.ToString()); - if (!string.IsNullOrWhiteSpace(Info)) - req.AddParameter(@"comments", Info); + req.AddParameter(@"comments", Comment); return req; } From 2adbf4cc1a5d27aad1d5a99d41766c598b7dfa60 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 17 Oct 2022 08:26:51 +0300 Subject: [PATCH 032/261] Add arc-shaped progress bars to "argon" spinner --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 105 +++++++++++++----- .../Skinning/Argon/ArgonSpinnerProgressArc.cs | 67 +++++++++++ .../Skinning/Argon/ArgonSpinnerRingArc.cs | 33 ++++++ 3 files changed, 175 insertions(+), 30 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs create mode 100644 osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index 4669b5b913..3b418fcb2d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -16,7 +16,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Skinning.Default; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { @@ -52,6 +51,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon private Container centre = null!; private CircularContainer fill = null!; + private Container ticksContainer = null!; + private ArgonSpinnerTicks ticks = null!; + [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject) { @@ -70,41 +72,84 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - fill = new CircularContainer + new Container { - Name = @"Fill", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Masking = true, - EdgeEffect = new EdgeEffectParameters + Padding = new MarginPadding(8f), + Children = new[] { - Type = EdgeEffectType.Shadow, - Colour = Colour4.FromHex("FC618F").Opacity(1f), - Radius = 40, + fill = new CircularContainer + { + Name = @"Fill", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Colour4.FromHex("FC618F").Opacity(1f), + Radius = 40, + }, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + AlwaysPresent = true, + } + }, + new Container + { + Name = @"Ring", + Masking = true, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Top Arc", + }, + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Bottom Arc", + Scale = new Vector2(1, -1), + }, + } + }, + ticksContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Child = ticks = new ArgonSpinnerTicks(), + } }, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0f, - AlwaysPresent = true, - } }, - new CircularContainer + new Container { - Name = @"Ring", - Masking = true, - BorderColour = Color4.White, - BorderThickness = 5, + Name = @"Sides", RelativeSizeAxes = Axes.Both, - Child = new Box + Children = new[] { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, + new ArgonSpinnerProgressArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Left Bar" + }, + new ArgonSpinnerProgressArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Right Bar", + Scale = new Vector2(-1, 1), + }, } }, - new ArgonSpinnerTicks(), } }, centre = new Container @@ -167,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress; fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1))); - disc.Rotation = drawableSpinner.RotationTracker.Rotation; + ticks.Rotation = drawableSpinner.RotationTracker.Rotation; } private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) @@ -180,12 +225,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt)) { this.ScaleTo(initial_scale); - this.RotateTo(0); + ticksContainer.RotateTo(0); using (BeginDelayedSequence(spinner.TimePreempt / 2)) { // constant ambient rotation to give the spinner "spinning" character. - this.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration); + ticksContainer.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration); } using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset)) @@ -194,7 +239,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { case ArmedState.Hit: this.ScaleTo(initial_scale * 1.2f, 320, Easing.Out); - this.RotateTo(Rotation + 180, 320); + ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320); break; case ArmedState.Miss: diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs new file mode 100644 index 0000000000..be7921a1f1 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs @@ -0,0 +1,67 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Utils; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Skinning.Argon +{ + public class ArgonSpinnerProgressArc : CompositeDrawable + { + private const float arc_fill = 0.15f; + private const float arc_radius = 0.12f; + + private CircularProgress fill = null!; + + private DrawableSpinner spinner = null!; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject, OsuColour colours) + { + RelativeSizeAxes = Axes.Both; + + spinner = (DrawableSpinner)drawableHitObject; + + InternalChildren = new Drawable[] + { + new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Color4.White.Opacity(0.25f), + RelativeSizeAxes = Axes.Both, + Current = { Value = arc_fill }, + Rotation = 90 - arc_fill * 180, + InnerRadius = arc_radius, + RoundedCaps = true, + }, + fill = new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + InnerRadius = arc_radius, + RoundedCaps = true, + } + }; + } + + protected override void Update() + { + base.Update(); + + fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 ? 1 : 0, 120f, (float)Math.Abs(Time.Elapsed)); + fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, arc_fill * spinner.Progress, 120f, (float)Math.Abs(Time.Elapsed)); + fill.Rotation = (float)(90 - fill.Current.Value * 180); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs new file mode 100644 index 0000000000..ec9d7bbae5 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Rulesets.Osu.Skinning.Argon +{ + public class ArgonSpinnerRingArc : CompositeDrawable + { + private const float arc_fill = 0.31f; + private const float arc_radius = 0.02f; + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Current = { Value = arc_fill }, + Rotation = -arc_fill * 180, + InnerRadius = arc_radius, + RoundedCaps = true, + }; + } + } +} From 7ed26369a3e7b974466d15131bdc3e4a722ef210 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 12:41:57 +0300 Subject: [PATCH 033/261] Make a new report form, closer to web --- .../Overlays/Comments/CommentReportDialog.cs | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 osu.Game/Overlays/Comments/CommentReportDialog.cs diff --git a/osu.Game/Overlays/Comments/CommentReportDialog.cs b/osu.Game/Overlays/Comments/CommentReportDialog.cs new file mode 100644 index 0000000000..26a768b4ec --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentReportDialog.cs @@ -0,0 +1,144 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Resources.Localisation.Web; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Comments +{ + public class CommentReportDialog : VisibilityContainer + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider, OsuColour colours) + { + RelativeSizeAxes = Axes.Both; + + Child = new Container + { + Masking = true, + CornerRadius = 10, + Width = 500, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + Colour = colourProvider.Background6, + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(10), + Children = new[] + { + new CircularContainer + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Masking = true, + Size = new Vector2(100f), + BorderColour = Color4.White, + BorderThickness = 5f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0), + }, + new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Icon = FontAwesome.Solid.ExclamationTriangle, + Size = new Vector2(50), + }, + }, + }, + new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 25)) + { + Text = UsersStrings.ReportTitle("the comment"), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + TextAnchor = Anchor.TopCentre, + }, + Empty().With(d => d.Height = 10), + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportReason, + Font = OsuFont.Torus.With(size: 20), + }, + new OsuEnumDropdown + { + RelativeSizeAxes = Axes.X + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportComments, + Font = OsuFont.Torus.With(size: 20), + }, + new OsuTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = UsersStrings.ReportPlaceholder + }, + new RoundedButton + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = send, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, + }, + new RoundedButton + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + Text = UsersStrings.ReportActionsCancel, + Action = () => + { + Hide(); + Expire(); + } + } + } + } + } + }; + } + + private void send() + { + } + + protected override void PopIn() + { + } + + protected override void PopOut() + { + } + } +} From d7e5bcbd3c401a99e5414a25cd5e097c3c6a7836 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:41:46 +0300 Subject: [PATCH 034/261] Add popover containers to overlays --- osu.Game/Overlays/BeatmapSetOverlay.cs | 24 ++++++---- .../Changelog/ChangelogSingleBuild.cs | 46 +++++++++++-------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 207dc91ca5..904fd6ead6 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet; @@ -44,20 +45,25 @@ namespace osu.Game.Overlays Info info; CommentsSection comments; - Child = new FillFlowContainer + Child = new PopoverContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] + Child = new FillFlowContainer { - info = new Info(), - new ScoresContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] { - Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } - }, - comments = new CommentsSection() + info = new Info(), + new ScoresContainer + { + Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } + }, + comments = new CommentsSection() + } } }; diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index e4f240f0e7..afdfd0ff68 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; @@ -63,28 +64,33 @@ namespace osu.Game.Overlays.Changelog { CommentsContainer comments; - Children = new Drawable[] + Child = new PopoverContainer { - new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, - new Box + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Margin = new MarginPadding { Top = 30 }, - }, - new ChangelogSupporterPromo - { - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - comments = new CommentsContainer() + new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Top = 30 }, + }, + new ChangelogSupporterPromo + { + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + comments = new CommentsContainer() + } }; comments.ShowComments(CommentableType.Build, build.Id); From ffa22d8a682983cd8aa7e2ade12d824cb6f18f46 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:42:17 +0300 Subject: [PATCH 035/261] Update popover not to use labelled drawables --- osu.Game/Overlays/Comments/DrawableComment.cs | 5 +-- .../Overlays/Comments/ReportCommentPopover.cs | 43 ++++++++++++++----- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 998f3b8e62..04e088dc35 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -570,10 +570,7 @@ namespace osu.Game.Overlays.Comments } } - public Popover GetPopover() - { - return new ReportCommentPopover(ReportComment); - } + public Popover GetPopover() => new ReportCommentPopover(ReportComment); private class ReportToast : Toast { diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 5f9e7ff45c..ad135f7eec 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -8,7 +8,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Resources.Localisation.Web; using osuTK; namespace osu.Game.Overlays.Comments @@ -16,8 +19,8 @@ namespace osu.Game.Overlays.Comments public class ReportCommentPopover : OsuPopover { private readonly Action action; - private LabelledEnumDropdown reason = null!; - private LabelledTextBox info = null!; + private OsuEnumDropdown reason = null!; + private OsuTextBox info = null!; private ShakeContainer shaker = null!; public ReportCommentPopover(Action action) @@ -36,13 +39,28 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(7), Children = new Drawable[] { - reason = new LabelledEnumDropdown + new OsuSpriteText { - Label = "Reason" + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportReason, + Font = OsuFont.Torus.With(size: 20), }, - info = new LabelledTextBox + reason = new OsuEnumDropdown { - Label = "Additional info", + RelativeSizeAxes = Axes.X + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportComments, + Font = OsuFont.Torus.With(size: 20), + }, + info = new OsuTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = UsersStrings.ReportPlaceholder }, new Container { @@ -54,10 +72,13 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Y, Child = new RoundedButton { - BackgroundColour = colours.Pink3, - Text = "Send report", - RelativeSizeAxes = Axes.X, - Action = send + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = send, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, } } } @@ -70,7 +91,7 @@ namespace osu.Game.Overlays.Comments string infoValue = info.Current.Value; var reasonValue = reason.Current.Value; - if (reasonValue == CommentReportReason.Other && string.IsNullOrWhiteSpace(infoValue)) + if (string.IsNullOrWhiteSpace(infoValue)) { shaker.Shake(); return; From ceb4d624b5b4749dc08ea2591ce93513aeb1afe6 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:43:35 +0300 Subject: [PATCH 036/261] Delete wip form --- .../Overlays/Comments/CommentReportDialog.cs | 144 ------------------ 1 file changed, 144 deletions(-) delete mode 100644 osu.Game/Overlays/Comments/CommentReportDialog.cs diff --git a/osu.Game/Overlays/Comments/CommentReportDialog.cs b/osu.Game/Overlays/Comments/CommentReportDialog.cs deleted file mode 100644 index 26a768b4ec..0000000000 --- a/osu.Game/Overlays/Comments/CommentReportDialog.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Graphics.UserInterfaceV2; -using osu.Game.Resources.Localisation.Web; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.Comments -{ - public class CommentReportDialog : VisibilityContainer - { - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours) - { - RelativeSizeAxes = Axes.Both; - - Child = new Container - { - Masking = true, - CornerRadius = 10, - Width = 500, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Box - { - Colour = colourProvider.Background6, - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - Direction = FillDirection.Vertical, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(10), - Children = new[] - { - new CircularContainer - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Masking = true, - Size = new Vector2(100f), - BorderColour = Color4.White, - BorderThickness = 5f, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0), - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = FontAwesome.Solid.ExclamationTriangle, - Size = new Vector2(50), - }, - }, - }, - new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 25)) - { - Text = UsersStrings.ReportTitle("the comment"), - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - TextAnchor = Anchor.TopCentre, - }, - Empty().With(d => d.Height = 10), - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportReason, - Font = OsuFont.Torus.With(size: 20), - }, - new OsuEnumDropdown - { - RelativeSizeAxes = Axes.X - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportComments, - Font = OsuFont.Torus.With(size: 20), - }, - new OsuTextBox - { - RelativeSizeAxes = Axes.X, - PlaceholderText = UsersStrings.ReportPlaceholder - }, - new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - BackgroundColour = colours.Red3, - Text = UsersStrings.ReportActionsSend, - Action = send, - Margin = new MarginPadding { Bottom = 5, Top = 10 }, - }, - new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - Text = UsersStrings.ReportActionsCancel, - Action = () => - { - Hide(); - Expire(); - } - } - } - } - } - }; - } - - private void send() - { - } - - protected override void PopIn() - { - } - - protected override void PopOut() - { - } - } -} From 3bcc91511fb185d63061d80268c88cec9e57e31e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:46:13 +0300 Subject: [PATCH 037/261] Update test --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 3515b5fb0a..a6524aad1a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -249,11 +249,6 @@ namespace osu.Game.Tests.Visual.Online InputManager.MoveMouseTo(btn); InputManager.Click(MouseButton.Left); }); - AddStep("Select \"other\"", () => - { - var field = this.ChildrenOfType>().Single(); - field.Current.Value = CommentReportReason.Other; - }); AddStep("Try to report", () => { var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); @@ -264,7 +259,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); AddStep("Enter some text", () => { - var field = this.ChildrenOfType().Single(); + var field = this.ChildrenOfType().Single(); field.Current.Value = report_text; }); AddStep("Try to report", () => From 18cc3b0bd313772d92f58c34c2cf71e9561cb74f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 20:23:25 +0300 Subject: [PATCH 038/261] Fix reason not set in test --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index a6524aad1a..54c135ba15 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -257,10 +257,12 @@ namespace osu.Game.Tests.Visual.Online }); AddWaitStep("Wait", 3); AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); - AddStep("Enter some text", () => + AddStep("Set report data", () => { var field = this.ChildrenOfType().Single(); field.Current.Value = report_text; + var reason = this.ChildrenOfType>().Single(); + reason.Current.Value = CommentReportReason.Other; }); AddStep("Try to report", () => { From 797acf334f431f02795722a8495e81cfe2e181fe Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 20:41:13 +0300 Subject: [PATCH 039/261] Show username in popup --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- .../Overlays/Comments/ReportCommentPopover.cs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 04e088dc35..5fca9b0b4b 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -570,7 +570,7 @@ namespace osu.Game.Overlays.Comments } } - public Popover GetPopover() => new ReportCommentPopover(ReportComment); + public Popover GetPopover() => new ReportCommentPopover(this); private class ReportToast : Toast { diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index ad135f7eec..5214f8a3e3 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Graphics; @@ -18,14 +17,14 @@ namespace osu.Game.Overlays.Comments { public class ReportCommentPopover : OsuPopover { - private readonly Action action; + private readonly DrawableComment comment; private OsuEnumDropdown reason = null!; private OsuTextBox info = null!; private ShakeContainer shaker = null!; - public ReportCommentPopover(Action action) + public ReportCommentPopover(DrawableComment comment) { - this.action = action; + this.comment = comment; } [BackgroundDependencyLoader] @@ -39,6 +38,14 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(7), Children = new Drawable[] { + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), + Font = OsuFont.Torus.With(size: 25), + Margin = new MarginPadding { Bottom = 10 } + }, new OsuSpriteText { Origin = Anchor.TopCentre, @@ -98,7 +105,7 @@ namespace osu.Game.Overlays.Comments } this.HidePopover(); - action.Invoke(reasonValue, infoValue); + comment.ReportComment(reasonValue, infoValue); } } } From cd77ae062e43a2202bd2a1e074700d30793ce4bc Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 20:41:23 +0300 Subject: [PATCH 040/261] Localize the button --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 5fca9b0b4b..6182f9b188 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -333,7 +333,7 @@ namespace osu.Game.Overlays.Comments if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink("Delete", deleteComment); else - actionsContainer.AddLink("Report", this.ShowPopover); + actionsContainer.AddLink(UsersStrings.ReportButtonText, this.ShowPopover); if (Comment.IsTopLevel) { From 57320074a0f6140bdd17423e416af3db200361c8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 01:24:36 +0300 Subject: [PATCH 041/261] Fix accidental breakage of changelog layout --- .../Overlays/Changelog/ChangelogContent.cs | 13 +++++- .../Changelog/ChangelogSingleBuild.cs | 46 ++++++++----------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index 1e49efb10e..dca2f3b1b0 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -7,20 +7,29 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Changelog { - public class ChangelogContent : FillFlowContainer + public class ChangelogContent : PopoverContainer { public Action BuildSelected; public void SelectBuild(APIChangelogBuild build) => BuildSelected?.Invoke(build); + protected override Container Content { get; } + public ChangelogContent() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; + Content = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }; + base.Content.Add(Content); } } } diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index afdfd0ff68..e4f240f0e7 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; @@ -64,33 +63,28 @@ namespace osu.Game.Overlays.Changelog { CommentsContainer comments; - Child = new PopoverContainer + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, + new Box { - new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Margin = new MarginPadding { Top = 30 }, - }, - new ChangelogSupporterPromo - { - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - comments = new CommentsContainer() - } + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Top = 30 }, + }, + new ChangelogSupporterPromo + { + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + comments = new CommentsContainer() }; comments.ShowComments(CommentableType.Build, build.Id); From ed39481932a148297c546013987e8fbbccaeaf47 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:11:35 +0300 Subject: [PATCH 042/261] Use another string for title --- osu.Game/Overlays/Comments/ReportCommentPopover.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 5214f8a3e3..83b13c8f56 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Comments { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), + Text = ReportStrings.CommentTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), Font = OsuFont.Torus.With(size: 25), Margin = new MarginPadding { Bottom = 10 } }, From 635900085c62854e4b8ec842a2a003cfbaff90e0 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:12:20 +0300 Subject: [PATCH 043/261] Disable button when there is no text --- .../Overlays/Comments/ReportCommentPopover.cs | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 83b13c8f56..14da02f838 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -2,11 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Comments { private readonly DrawableComment comment; private OsuEnumDropdown reason = null!; - private OsuTextBox info = null!; - private ShakeContainer shaker = null!; + private readonly Bindable commentText = new Bindable(); + private RoundedButton submitButton = null!; public ReportCommentPopover(DrawableComment comment) { @@ -64,48 +64,37 @@ namespace osu.Game.Overlays.Comments Text = UsersStrings.ReportComments, Font = OsuFont.Torus.With(size: 20), }, - info = new OsuTextBox + new OsuTextBox { RelativeSizeAxes = Axes.X, - PlaceholderText = UsersStrings.ReportPlaceholder + PlaceholderText = UsersStrings.ReportPlaceholder, + Current = commentText }, - new Container + submitButton = new RoundedButton { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = shaker = new ShakeContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - BackgroundColour = colours.Red3, - Text = UsersStrings.ReportActionsSend, - Action = send, - Margin = new MarginPadding { Bottom = 5, Top = 10 }, - } - } + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = send, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, } } }; + commentText.BindValueChanged(e => + { + submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); + }, true); } private void send() { - string infoValue = info.Current.Value; - var reasonValue = reason.Current.Value; - - if (string.IsNullOrWhiteSpace(infoValue)) - { - shaker.Shake(); + if (string.IsNullOrWhiteSpace(commentText.Value)) return; - } this.HidePopover(); - comment.ReportComment(reasonValue, infoValue); + comment.ReportComment(reason.Current.Value, commentText.Value); } } } From da4f04ace77929cb1927f4c5aa34ccde189d551f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:22:55 +0300 Subject: [PATCH 044/261] Make dropdown not resize --- osu.Game/Overlays/Comments/ReportCommentPopover.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 14da02f838..202f27777d 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; @@ -30,7 +31,7 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OsuColour colours) { - Child = new FillFlowContainer + Child = new ReverseChildIDFillFlowContainer { Direction = FillDirection.Vertical, Width = 500, @@ -53,9 +54,14 @@ namespace osu.Game.Overlays.Comments Text = UsersStrings.ReportReason, Font = OsuFont.Torus.With(size: 20), }, - reason = new OsuEnumDropdown + new Container { - RelativeSizeAxes = Axes.X + RelativeSizeAxes = Axes.X, + Height = 40, + Child = reason = new OsuEnumDropdown + { + RelativeSizeAxes = Axes.X + } }, new OsuSpriteText { From 0ef903230c04e118d8ab94f6f628eba6ccab1ab1 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:47:42 +0300 Subject: [PATCH 045/261] Make report button a separate component --- osu.Game/Overlays/Comments/DrawableComment.cs | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 75f68782b8..a2b11bfc69 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -34,7 +34,8 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class DrawableComment : CompositeDrawable, IHasPopover + [Cached] + public class DrawableComment : CompositeDrawable { private const int avatar_size = 40; @@ -64,6 +65,7 @@ namespace osu.Game.Overlays.Comments private ShowRepliesButton showRepliesButton = null!; private ChevronButton chevronButton = null!; private LinkFlowContainer actionsContainer = null!; + private ReportButton? reportButton; private LoadingSpinner actionsLoading = null!; private DeletedCommentsCounter deletedCommentsCounter = null!; private OsuSpriteText deletedLabel = null!; @@ -334,12 +336,12 @@ namespace osu.Game.Overlays.Comments makeDeleted(); actionsContainer.AddLink("Copy link", copyUrl); - actionsContainer.AddArbitraryDrawable(new Container { Width = 10 }); + actionsContainer.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink("Delete", deleteComment); else - actionsContainer.AddLink(UsersStrings.ReportButtonText, this.ShowPopover); + actionsContainer.AddArbitraryDrawable(reportButton = new ReportButton()); if (Comment.IsTopLevel) { @@ -424,6 +426,8 @@ namespace osu.Game.Overlays.Comments request.Success += () => Schedule(() => { actionsLoading.Hide(); + reportButton?.Expire(); + actionsContainer.Show(); onScreenDisplay?.Display(new ReportToast()); }); request.Failure += _ => Schedule(() => @@ -582,8 +586,6 @@ namespace osu.Game.Overlays.Comments } } - public Popover GetPopover() => new ReportCommentPopover(this); - private class ReportToast : Toast { public ReportToast() @@ -591,5 +593,25 @@ namespace osu.Game.Overlays.Comments { } } + + private class ReportButton : LinkFlowContainer, IHasPopover + { + public ReportButton() + : base(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) + { + } + + [Resolved] + private DrawableComment comment { get; set; } = null!; + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + AddLink(UsersStrings.ReportButtonText, this.ShowPopover); + } + + public Popover GetPopover() => new ReportCommentPopover(comment); + } } } From 81bdf716ef41a8b9968cbe6e05b00dace996075b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 19:56:00 +0300 Subject: [PATCH 046/261] Change test --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 54c135ba15..a2e0c90c4c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -276,7 +276,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); - AddUntilStep("Buttons hidden", () => !targetComment.ChildrenOfType().Single(x => x.Name == @"Actions buttons").IsPresent); + AddUntilStep("Button expired", () => !targetComment.ChildrenOfType().Any()); } private void addTestComments() diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index a2b11bfc69..199f678be1 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -594,7 +594,7 @@ namespace osu.Game.Overlays.Comments } } - private class ReportButton : LinkFlowContainer, IHasPopover + internal class ReportButton : LinkFlowContainer, IHasPopover { public ReportButton() : base(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) From 15aeb4a137c91274b9e7d964917db3d0df576938 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 21 Oct 2022 17:25:41 +0300 Subject: [PATCH 047/261] Display text in buttons flow instead of toast --- .../Visual/Online/TestSceneCommentActions.cs | 1 - osu.Game/Overlays/Comments/DrawableComment.cs | 19 ++++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index a2e0c90c4c..b4ffcd42b5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -276,7 +276,6 @@ namespace osu.Game.Tests.Visual.Online AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); - AddUntilStep("Button expired", () => !targetComment.ChildrenOfType().Any()); } private void addTestComments() diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 199f678be1..4d4ed06200 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -24,7 +24,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Graphics.UserInterface; -using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Comments.Buttons; @@ -426,9 +425,8 @@ namespace osu.Game.Overlays.Comments request.Success += () => Schedule(() => { actionsLoading.Hide(); - reportButton?.Expire(); + reportButton?.MarkReported(); actionsContainer.Show(); - onScreenDisplay?.Display(new ReportToast()); }); request.Failure += _ => Schedule(() => { @@ -586,14 +584,6 @@ namespace osu.Game.Overlays.Comments } } - private class ReportToast : Toast - { - public ReportToast() - : base(UserInterfaceStrings.GeneralHeader, UsersStrings.ReportThanks, "") - { - } - } - internal class ReportButton : LinkFlowContainer, IHasPopover { public ReportButton() @@ -611,6 +601,13 @@ namespace osu.Game.Overlays.Comments AddLink(UsersStrings.ReportButtonText, this.ShowPopover); } + public void MarkReported() + { + Clear(true); + AddText(UsersStrings.ReportThanks); + this.Delay(3000).Then().FadeOut(2000); + } + public Popover GetPopover() => new ReportCommentPopover(comment); } } From 081cf1cc47c5ad775840ab1227bbb85808477ad1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:45:28 +0300 Subject: [PATCH 048/261] Adjust comment report popover design --- osu.Game/Overlays/Comments/ReportCommentPopover.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 202f27777d..f3d6e319bf 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -39,6 +39,13 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(7), Children = new Drawable[] { + new SpriteIcon + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Icon = FontAwesome.Solid.ExclamationTriangle, + Size = new Vector2(36), + }, new OsuSpriteText { Origin = Anchor.TopCentre, @@ -52,7 +59,6 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Text = UsersStrings.ReportReason, - Font = OsuFont.Torus.With(size: 20), }, new Container { @@ -68,7 +74,6 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Text = UsersStrings.ReportComments, - Font = OsuFont.Torus.With(size: 20), }, new OsuTextBox { From 9b5e35d5992985722ddf8576500c6d69040c3998 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:45:06 +0300 Subject: [PATCH 049/261] Remove dependency on `DrawableComment` from report popover and simplify logic Allows for testing the button and popover in isolation. --- .../Overlays/Comments/ReportCommentPopover.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index f3d6e319bf..39fd52aa2a 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -1,16 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; using osuTK; @@ -18,12 +20,15 @@ namespace osu.Game.Overlays.Comments { public class ReportCommentPopover : OsuPopover { - private readonly DrawableComment comment; - private OsuEnumDropdown reason = null!; - private readonly Bindable commentText = new Bindable(); + public Action? Action; + + private readonly Comment? comment; + + private OsuEnumDropdown reasonDropdown = null!; + private OsuTextBox commentsTextBox = null!; private RoundedButton submitButton = null!; - public ReportCommentPopover(DrawableComment comment) + public ReportCommentPopover(Comment? comment) { this.comment = comment; } @@ -50,7 +55,7 @@ namespace osu.Game.Overlays.Comments { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - Text = ReportStrings.CommentTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), + Text = ReportStrings.CommentTitle(comment?.User?.Username ?? comment?.LegacyName ?? @"Someone"), Font = OsuFont.Torus.With(size: 25), Margin = new MarginPadding { Bottom = 10 } }, @@ -64,7 +69,7 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, Height = 40, - Child = reason = new OsuEnumDropdown + Child = reasonDropdown = new OsuEnumDropdown { RelativeSizeAxes = Axes.X } @@ -75,11 +80,10 @@ namespace osu.Game.Overlays.Comments Anchor = Anchor.TopCentre, Text = UsersStrings.ReportComments, }, - new OsuTextBox + commentsTextBox = new OsuTextBox { RelativeSizeAxes = Axes.X, PlaceholderText = UsersStrings.ReportPlaceholder, - Current = commentText }, submitButton = new RoundedButton { @@ -88,24 +92,20 @@ namespace osu.Game.Overlays.Comments Width = 200, BackgroundColour = colours.Red3, Text = UsersStrings.ReportActionsSend, - Action = send, + Action = () => + { + Action?.Invoke(reasonDropdown.Current.Value, commentsTextBox.Text); + this.HidePopover(); + }, Margin = new MarginPadding { Bottom = 5, Top = 10 }, } } }; - commentText.BindValueChanged(e => + + commentsTextBox.Current.BindValueChanged(e => { submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); }, true); } - - private void send() - { - if (string.IsNullOrWhiteSpace(commentText.Value)) - return; - - this.HidePopover(); - comment.ReportComment(reason.Current.Value, commentText.Value); - } } } From 6c82bc36ed703bbfb6a4567baeea669375bfed0c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:47:11 +0300 Subject: [PATCH 050/261] Encapsulate report logic inside button implementation Avoids complicating the `DrawableComment` class, and allows for isolated testability. --- .../Overlays/Comments/CommentReportButton.cs | 91 +++++++++++++++++++ osu.Game/Overlays/Comments/DrawableComment.cs | 51 +---------- 2 files changed, 92 insertions(+), 50 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentReportButton.cs diff --git a/osu.Game/Overlays/Comments/CommentReportButton.cs b/osu.Game/Overlays/Comments/CommentReportButton.cs new file mode 100644 index 0000000000..4f5c5c6dcf --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentReportButton.cs @@ -0,0 +1,91 @@ +// 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.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Resources.Localisation.Web; +using osuTK; + +namespace osu.Game.Overlays.Comments +{ + public class CommentReportButton : CompositeDrawable, IHasPopover + { + private readonly Comment comment; + + private LinkFlowContainer link = null!; + private LoadingSpinner loading = null!; + + [Resolved] + private IAPIProvider api { get; set; } = null!; + + [Resolved] + private OverlayColourProvider? colourProvider { get; set; } + + public CommentReportButton(Comment comment) + { + this.comment = comment; + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + link = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) + { + AutoSizeAxes = Axes.Both, + }, + loading = new LoadingSpinner + { + Size = new Vector2(12f), + } + }; + + link.AddLink(UsersStrings.ReportButtonText, this.ShowPopover); + } + + private void report(CommentReportReason reason, string comments) + { + var request = new CommentReportRequest(comment.Id, reason, comments); + + link.Hide(); + loading.Show(); + + request.Success += () => Schedule(() => + { + loading.Hide(); + + link.Clear(true); + link.AddText(UsersStrings.ReportThanks, s => s.Colour = colourProvider?.Content2 ?? Colour4.White); + link.Show(); + + this.FadeOut(2000, Easing.InQuint).Expire(); + }); + + request.Failure += _ => Schedule(() => + { + loading.Hide(); + link.Show(); + }); + + api.Queue(request); + } + + public Popover GetPopover() => new ReportCommentPopover(comment) + { + Action = report + }; + } +} diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 4d4ed06200..aa08de798c 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -19,8 +19,6 @@ using System; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.IEnumerableExtensions; using System.Collections.Specialized; -using osu.Framework.Extensions; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Graphics.UserInterface; @@ -64,7 +62,6 @@ namespace osu.Game.Overlays.Comments private ShowRepliesButton showRepliesButton = null!; private ChevronButton chevronButton = null!; private LinkFlowContainer actionsContainer = null!; - private ReportButton? reportButton; private LoadingSpinner actionsLoading = null!; private DeletedCommentsCounter deletedCommentsCounter = null!; private OsuSpriteText deletedLabel = null!; @@ -340,7 +337,7 @@ namespace osu.Game.Overlays.Comments if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink("Delete", deleteComment); else - actionsContainer.AddArbitraryDrawable(reportButton = new ReportButton()); + actionsContainer.AddArbitraryDrawable(new CommentReportButton(Comment)); if (Comment.IsTopLevel) { @@ -417,25 +414,6 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } - public void ReportComment(CommentReportReason reason, string comment) - { - actionsContainer.Hide(); - actionsLoading.Show(); - var request = new CommentReportRequest(Comment.Id, reason, comment); - request.Success += () => Schedule(() => - { - actionsLoading.Hide(); - reportButton?.MarkReported(); - actionsContainer.Show(); - }); - request.Failure += _ => Schedule(() => - { - actionsLoading.Hide(); - actionsContainer.Show(); - }); - api.Queue(request); - } - private void copyUrl() { host.GetClipboard()?.SetText($@"{api.APIEndpointUrl}/comments/{Comment.Id}"); @@ -583,32 +561,5 @@ namespace osu.Game.Overlays.Comments return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? "deleted" : string.Empty; } } - - internal class ReportButton : LinkFlowContainer, IHasPopover - { - public ReportButton() - : base(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) - { - } - - [Resolved] - private DrawableComment comment { get; set; } = null!; - - [BackgroundDependencyLoader] - private void load() - { - AutoSizeAxes = Axes.Both; - AddLink(UsersStrings.ReportButtonText, this.ShowPopover); - } - - public void MarkReported() - { - Clear(true); - AddText(UsersStrings.ReportThanks); - this.Delay(3000).Then().FadeOut(2000); - } - - public Popover GetPopover() => new ReportCommentPopover(comment); - } } } From 90a9961a69655de48b05ecef8de33146c09c564d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:47:23 +0300 Subject: [PATCH 051/261] Add visual test case for report button Makes it much easier to test button/popover design changes --- .../Online/TestSceneCommentReportButton.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs new file mode 100644 index 0000000000..fb56a41507 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs @@ -0,0 +1,46 @@ +// 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; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Testing; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Comments; +using osu.Game.Tests.Visual.UserInterface; +using osuTK; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneCommentReportButton : ThemeComparisonTestScene + { + [SetUpSteps] + public void SetUpSteps() + { + AddStep("setup API", () => ((DummyAPIAccess)API).HandleRequest += req => + { + switch (req) + { + case CommentReportRequest report: + Scheduler.AddDelayed(report.TriggerSuccess, 1000); + return true; + } + + return false; + }); + } + + protected override Drawable CreateContent() => new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + Child = new CommentReportButton(new Comment { User = new APIUser { Username = "Someone" } }) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(2f), + }.With(b => Schedule(b.ShowPopover)), + }; + } +} From b0a4cd4f30e65ce7e04884f986c9d2c8f2501912 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 03:43:14 +0300 Subject: [PATCH 052/261] Inline content creation in base add method --- osu.Game/Overlays/Changelog/ChangelogContent.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index dca2f3b1b0..2b54df7226 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -23,13 +23,13 @@ namespace osu.Game.Overlays.Changelog { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Content = new FillFlowContainer + + base.Content.Add(Content = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical - }; - base.Content.Add(Content); + }); } } } From de881cc5cb44829ce9fdc1f468f28000869081bd Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 24 Oct 2022 23:17:28 +0900 Subject: [PATCH 053/261] useless #nullable disable --- osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs | 2 -- osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs | 2 -- osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs | 2 -- osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs | 2 -- 4 files changed, 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs index e14354222b..6af3ba908d 100644 --- a/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs index 8321fde171..20b8bba6da 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs index 1085f2c277..0a2c073dcd 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs index 6af3b99017..4e75a92e19 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Screens.Edit.Components.Menus { public class EditorMenuItemSpacer : EditorMenuItem From a2682b3ce39ddf9fc3e6c311206520c4e4d8472b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 24 Oct 2022 23:18:34 +0900 Subject: [PATCH 054/261] background dim settings for editor View -> Background Dim follow `DimLevel` and `BlurLevel` Co-Authored-By: Dead_Bush_Sanpai --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ osu.Game/Screens/Edit/Editor.cs | 23 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1378e1691a..f8c851757e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -122,6 +122,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); + SetDefault(OsuSetting.EditorUseDim, false); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); @@ -292,6 +293,7 @@ namespace osu.Game.Configuration GameplayCursorDuringTouch, DimLevel, BlurLevel, + EditorUseDim, LightenDuringBreaks, ShowStoryboard, KeyOverlay, diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3dfc7010f3..9cfd1badd1 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -176,6 +176,8 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + private Bindable useUserDim; + public Editor(EditorLoader loader = null) { this.loader = loader; @@ -260,6 +262,9 @@ namespace osu.Game.Screens.Edit OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; + TernaryStateRadioMenuItem backgroundDim; + useUserDim = config.GetBindable(OsuSetting.EditorUseDim); + AddInternal(new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, @@ -311,6 +316,7 @@ namespace osu.Game.Screens.Edit Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), + backgroundDim = new TernaryStateRadioMenuItem("Background Dim", MenuItemType.Standard, _ => useUserDim.Value = !useUserDim.Value), } } } @@ -330,6 +336,13 @@ namespace osu.Game.Screens.Edit changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); + + useUserDim.BindValueChanged(s => + { + dimBackground(); + backgroundDim.State.Value = s.NewValue ? TernaryState.True : TernaryState.False; + }); + backgroundDim.State.Value = useUserDim.Value ? TernaryState.True : TernaryState.False; } [Resolved] @@ -626,9 +639,9 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { // todo: temporary. we want to be applying dim using the UserDimContainer eventually. - b.FadeColour(Color4.DarkGray, 500); + if (!useUserDim.Value) b.FadeColour(Color4.DarkGray, 500); - b.IgnoreUserSettings.Value = true; + b.IgnoreUserSettings.Value = !useUserDim.Value; b.BlurAmount.Value = 0; }); } @@ -656,7 +669,11 @@ namespace osu.Game.Screens.Edit } } - ApplyToBackground(b => b.FadeColour(Color4.White, 500)); + ApplyToBackground(b => + { + b.FadeColour(Color4.White, 500); + b.IgnoreUserSettings.Value = true; + }); resetTrack(); refetchBeatmap(); From f9c61904262f30b9f6297bcee9737cc13c691021 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 25 Oct 2022 13:00:53 +0900 Subject: [PATCH 055/261] Add DimAmount for UserDimContainer --- osu.Game/Graphics/Containers/UserDimContainer.cs | 5 ++++- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index d52fb7c60a..296855522b 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -48,13 +48,15 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } + public Bindable DimAmount { get; set; } = new Bindable(); + protected Bindable LightenDuringBreaks { get; private set; } protected Bindable ShowStoryboard { get; private set; } private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; - protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : 0, 0); + protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : DimAmount.Value, 0); protected override Container Content => dimContent; @@ -76,6 +78,7 @@ namespace osu.Game.Graphics.Containers ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); UserDimLevel.ValueChanged += _ => UpdateVisuals(); + DimAmount.ValueChanged += _ => UpdateVisuals(); LightenDuringBreaks.ValueChanged += _ => UpdateVisuals(); IsBreakTime.ValueChanged += _ => UpdateVisuals(); ShowStoryboard.ValueChanged += _ => UpdateVisuals(); diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index ca05c8af46..053bcf2387 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -43,6 +43,8 @@ namespace osu.Game.Screens.Backgrounds /// public readonly Bindable BlurAmount = new BindableFloat(); + public readonly Bindable DimAmount = new Bindable(); + internal readonly IBindable IsBreakTime = new Bindable(); private readonly DimmableBackground dimmable; @@ -58,6 +60,7 @@ namespace osu.Game.Screens.Backgrounds dimmable.IgnoreUserSettings.BindTo(IgnoreUserSettings); dimmable.IsBreakTime.BindTo(IsBreakTime); dimmable.BlurAmount.BindTo(BlurAmount); + dimmable.DimAmount.BindTo(DimAmount); StoryboardReplacesBackground.BindTo(dimmable.StoryboardReplacesBackground); } From 6991195d69b6a444ec4aad8b5e915fc105ce6d99 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 25 Oct 2022 13:01:24 +0900 Subject: [PATCH 056/261] let editor dim different from gameplay dim --- .../Editing/TestSceneEditorTestGameplay.cs | 15 ++++-- osu.Game/Configuration/OsuConfigManager.cs | 4 +- .../Screens/Edit/BackgroundDimMenuItem.cs | 46 +++++++++++++++++++ osu.Game/Screens/Edit/Editor.cs | 25 ++++------ 4 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 osu.Game/Screens/Edit/BackgroundDimMenuItem.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index a5d115331d..9722c60cba 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -7,10 +7,12 @@ using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; @@ -21,7 +23,6 @@ using osu.Game.Screens.Edit.GameplayTest; using osu.Game.Screens.Play; using osu.Game.Storyboards; using osu.Game.Tests.Beatmaps.IO; -using osuTK.Graphics; using osuTK.Input; namespace osu.Game.Tests.Visual.Editing @@ -40,6 +41,14 @@ namespace osu.Game.Tests.Visual.Editing private BeatmapSetInfo importedBeatmapSet; + private Bindable editorDim; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + editorDim = config.GetBindable(OsuSetting.EditorDim); + } + public override void SetUpSteps() { AddStep("import test beatmap", () => importedBeatmapSet = BeatmapImportHelper.LoadOszIntoOsu(game).GetResultSafely()); @@ -77,7 +86,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0; + return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); } @@ -110,7 +119,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0; + return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddStep("start track", () => EditorClock.Start()); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index f8c851757e..30299eb062 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -122,7 +122,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); - SetDefault(OsuSetting.EditorUseDim, false); + SetDefault(OsuSetting.EditorDim, 0.25f); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); @@ -293,7 +293,7 @@ namespace osu.Game.Configuration GameplayCursorDuringTouch, DimLevel, BlurLevel, - EditorUseDim, + EditorDim, LightenDuringBreaks, ShowStoryboard, KeyOverlay, diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs new file mode 100644 index 0000000000..b8644ed690 --- /dev/null +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Bindables; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit +{ + internal class BackgroundDimMenuItem : MenuItem + { + private readonly Bindable backgroudDim; + + private readonly Dictionary menuItemLookup = new Dictionary(); + + public BackgroundDimMenuItem(Bindable backgroudDim) + : base("Background dim") + { + Items = new[] + { + createMenuItem(0f), + createMenuItem(0.25f), + createMenuItem(0.5f), + createMenuItem(0.75f), + createMenuItem(1f), + }; + + this.backgroudDim = backgroudDim; + backgroudDim.BindValueChanged(dim => + { + foreach (var kvp in menuItemLookup) + kvp.Value.State.Value = kvp.Key == dim.NewValue ? TernaryState.True : TernaryState.False; + }, true); + } + + private TernaryStateRadioMenuItem createMenuItem(float dim) + { + var item = new TernaryStateRadioMenuItem($"{dim * 100}%", MenuItemType.Standard, _ => updateOpacity(dim)); + menuItemLookup[dim] = item; + return item; + } + + private void updateOpacity(float dim) => backgroudDim.Value = dim; + } +} diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9cfd1badd1..3c91d302ae 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,7 +51,6 @@ using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; -using osuTK.Graphics; using osuTK.Input; using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; @@ -176,7 +175,7 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - private Bindable useUserDim; + private Bindable editorDim; public Editor(EditorLoader loader = null) { @@ -262,8 +261,7 @@ namespace osu.Game.Screens.Edit OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; - TernaryStateRadioMenuItem backgroundDim; - useUserDim = config.GetBindable(OsuSetting.EditorUseDim); + editorDim = config.GetBindable(OsuSetting.EditorDim); AddInternal(new OsuContextMenuContainer { @@ -316,7 +314,7 @@ namespace osu.Game.Screens.Edit Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), - backgroundDim = new TernaryStateRadioMenuItem("Background Dim", MenuItemType.Standard, _ => useUserDim.Value = !useUserDim.Value), + new BackgroundDimMenuItem(editorDim), } } } @@ -337,12 +335,7 @@ namespace osu.Game.Screens.Edit changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); - useUserDim.BindValueChanged(s => - { - dimBackground(); - backgroundDim.State.Value = s.NewValue ? TernaryState.True : TernaryState.False; - }); - backgroundDim.State.Value = useUserDim.Value ? TernaryState.True : TernaryState.False; + editorDim.BindValueChanged(_ => dimBackground()); } [Resolved] @@ -638,10 +631,8 @@ namespace osu.Game.Screens.Edit { ApplyToBackground(b => { - // todo: temporary. we want to be applying dim using the UserDimContainer eventually. - if (!useUserDim.Value) b.FadeColour(Color4.DarkGray, 500); - - b.IgnoreUserSettings.Value = !useUserDim.Value; + b.IgnoreUserSettings.Value = true; + b.DimAmount.Value = editorDim.Value; b.BlurAmount.Value = 0; }); } @@ -671,8 +662,8 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { - b.FadeColour(Color4.White, 500); - b.IgnoreUserSettings.Value = true; + //b.DimAmount.UnbindAll(); + b.DimAmount.Value = 0; }); resetTrack(); From 77dcd0fae284eff1a556ae28fc18498db961426d Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Oct 2022 17:21:20 +0200 Subject: [PATCH 057/261] Create BezierConverter.cs --- osu.Game/Rulesets/Objects/BezierConverter.cs | 352 +++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 osu.Game/Rulesets/Objects/BezierConverter.cs diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs new file mode 100644 index 0000000000..414341641f --- /dev/null +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -0,0 +1,352 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Utils; +using osu.Game.Rulesets.Objects.Types; +using osuTK; + +namespace osu.Game.Rulesets.Objects +{ + public static class BezierConverter + { + private struct CircleBezierPreset + { + public readonly double ArcLength; + public readonly Vector2d[] ControlPoints; + + public CircleBezierPreset(double arcLength, Vector2d[] controlPoints) + { + ArcLength = arcLength; + ControlPoints = controlPoints; + } + } + + // Extremely accurate a bezier anchor positions for approximating circles of several arc lengths + private static readonly CircleBezierPreset[] circle_presets = + { + new CircleBezierPreset(0.4993379862754501, + new[] { new Vector2d(1, 0), new Vector2d(1, 0.2549893626632736f), new Vector2d(0.8778997558480327f, 0.47884446188920726f) }), + new CircleBezierPreset(1.7579419829169447, + new[] { new Vector2d(1, 0), new Vector2d(1, 0.6263026f), new Vector2d(0.42931178f, 1.0990661f), new Vector2d(-0.18605515f, 0.9825393f) }), + new CircleBezierPreset(3.1385246920140215, + new[] { new Vector2d(1, 0), new Vector2d(1, 0.87084764f), new Vector2d(0.002304826f, 1.5033062f), new Vector2d(-0.9973236f, 0.8739115f), new Vector2d(-0.9999953f, 0.0030679568f) }), + new CircleBezierPreset(5.69720464620727, + new[] { new Vector2d(1, 0), new Vector2d(1, 1.4137783f), new Vector2d(-1.4305235f, 2.0779421f), new Vector2d(-2.3410065f, -0.94017583f), new Vector2d(0.05132711f, -1.7309346f), new Vector2d(0.8331702f, -0.5530167f) }), + new CircleBezierPreset(2 * Math.PI, + new[] { new Vector2d(1, 0), new Vector2d(1, 1.2447058f), new Vector2d(-0.8526471f, 2.118367f), new Vector2d(-2.6211002f, 7.854936e-06f), new Vector2d(-0.8526448f, -2.118357f), new Vector2d(1, -1.2447058f), new Vector2d(1, 0) }) + }; + + #region CircularArcProperties + + //TODO: Get this from osu!framework instead + public readonly struct CircularArcProperties + { + public readonly bool IsValid; + public readonly double ThetaStart; + public readonly double ThetaRange; + public readonly double Direction; + public readonly float Radius; + public readonly Vector2 Centre; + + public double ThetaEnd => ThetaStart + ThetaRange * Direction; + + public CircularArcProperties(double thetaStart, double thetaRange, double direction, float radius, Vector2 centre) + { + IsValid = true; + ThetaStart = thetaStart; + ThetaRange = thetaRange; + Direction = direction; + Radius = radius; + Centre = centre; + } + } + + /// + /// Computes various properties that can be used to approximate the circular arc. + /// + /// Three distinct points on the arc. + private static CircularArcProperties circularArcProperties(ReadOnlySpan controlPoints) + { + Vector2 a = controlPoints[0]; + Vector2 b = controlPoints[1]; + Vector2 c = controlPoints[2]; + + // If we have a degenerate triangle where a side-length is almost zero, then give up and fallback to a more numerically stable method. + if (Precision.AlmostEquals(0, (b.Y - a.Y) * (c.X - a.X) - (b.X - a.X) * (c.Y - a.Y))) + return default; // Implicitly sets `IsValid` to false + + // See: https://en.wikipedia.org/wiki/Circumscribed_circle#Cartesian_coordinates_2 + float d = 2 * (a.X * (b - c).Y + b.X * (c - a).Y + c.X * (a - b).Y); + float aSq = a.LengthSquared; + float bSq = b.LengthSquared; + float cSq = c.LengthSquared; + + Vector2 centre = new Vector2( + aSq * (b - c).Y + bSq * (c - a).Y + cSq * (a - b).Y, + aSq * (c - b).X + bSq * (a - c).X + cSq * (b - a).X) / d; + + Vector2 dA = a - centre; + Vector2 dC = c - centre; + + float r = dA.Length; + + double thetaStart = Math.Atan2(dA.Y, dA.X); + double thetaEnd = Math.Atan2(dC.Y, dC.X); + + while (thetaEnd < thetaStart) + thetaEnd += 2 * Math.PI; + + double dir = 1; + double thetaRange = thetaEnd - thetaStart; + + // Decide in which direction to draw the circle, depending on which side of + // AC B lies. + Vector2 orthoAtoC = c - a; + orthoAtoC = new Vector2(orthoAtoC.Y, -orthoAtoC.X); + + if (Vector2.Dot(orthoAtoC, b - a) < 0) + { + dir = -dir; + thetaRange = 2 * Math.PI - thetaRange; + } + + return new CircularArcProperties(thetaStart, thetaRange, dir, r, centre); + } + + #endregion + + public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) + { + Vector2[] vertices = new Vector2[controlPoints.Count]; + for (int i = 0; i < controlPoints.Count; i++) + vertices[i] = controlPoints[i].Position; + + var result = new List(); + int start = 0; + + for (int i = 0; i < controlPoints.Count; i++) + { + if (controlPoints[i].Type == null && i < controlPoints.Count - 1) + continue; + + // The current vertex ends the segment + var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); + var segmentType = controlPoints[start].Type ?? PathType.Linear; + + switch (segmentType) + { + case PathType.Catmull: + result.AddRange(from segment in ConvertCatmullToBezierAnchors(segmentVertices) from v in segment select v + position); + + break; + + case PathType.Linear: + result.AddRange(from segment in ConvertLinearToBezierAnchors(segmentVertices) from v in segment select v + position); + + break; + + case PathType.PerfectCurve: + result.AddRange(ConvertCircleToBezierAnchors(segmentVertices).Select(v => v + position)); + + break; + + default: + foreach (Vector2 v in segmentVertices) + { + result.Add(v + position); + } + + break; + } + + // Start the new segment at the current vertex + start = i; + } + + return result; + } + + public static List ConvertToModernBezier(IList controlPoints) + { + Vector2[] vertices = new Vector2[controlPoints.Count]; + for (int i = 0; i < controlPoints.Count; i++) + vertices[i] = controlPoints[i].Position; + + var result = new List(); + int start = 0; + + for (int i = 0; i < controlPoints.Count; i++) + { + if (controlPoints[i].Type == null && i < controlPoints.Count - 1) + continue; + + // The current vertex ends the segment + var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); + var segmentType = controlPoints[start].Type ?? PathType.Linear; + + switch (segmentType) + { + case PathType.Catmull: + foreach (var segment in ConvertCatmullToBezierAnchors(segmentVertices)) + { + for (int j = 0; j < segment.Length - 1; j++) + { + result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.Bezier : null)); + } + } + + break; + + case PathType.Linear: + foreach (var segment in ConvertLinearToBezierAnchors(segmentVertices)) + { + for (int j = 0; j < segment.Length - 1; j++) + { + result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.Bezier : null)); + } + } + + break; + + case PathType.PerfectCurve: + var circleResult = ConvertCircleToBezierAnchors(segmentVertices); + + for (int j = 0; j < circleResult.Length - 1; j++) + { + result.Add(new PathControlPoint(circleResult[j], j == 0 ? PathType.Bezier : null)); + } + + break; + + default: + for (int j = 0; j < segmentVertices.Length - 1; j++) + { + result.Add(new PathControlPoint(segmentVertices[j], j == 0 ? PathType.Bezier : null)); + } + + break; + } + + // Start the new segment at the current vertex + start = i; + } + + result.Add(new PathControlPoint(controlPoints[^1].Position)); + + return result; + } + + /// + /// Converts perfect curve anchors to bezier anchors. + /// + /// The control point positions to convert. + public static Vector2[] ConvertCircleToBezierAnchors(ReadOnlySpan controlPoints) + { + var pr = circularArcProperties(controlPoints); + if (!pr.IsValid) + return controlPoints.ToArray(); + + CircleBezierPreset preset = circle_presets.Last(); + + foreach (CircleBezierPreset cbp in circle_presets) + { + if (cbp.ArcLength < pr.ThetaRange) continue; + + preset = cbp; + break; + } + + double arcLength = preset.ArcLength; + var arc = new Vector2d[preset.ControlPoints.Length]; + preset.ControlPoints.CopyTo(arc, 0); + + // Converge on arcLength of thetaRange + int n = arc.Length - 1; + double tf = pr.ThetaRange / arcLength; + + while (Math.Abs(tf - 1) > 1E-7) + { + for (int j = 0; j < n; j++) + { + for (int i = n; i > j; i--) + { + arc[i] = arc[i] * tf + arc[i - 1] * (1 - tf); + } + } + + arcLength = Math.Atan2(arc.Last()[1], arc.Last()[0]); + + if (arcLength < 0) + { + arcLength += 2 * Math.PI; + } + + tf = pr.ThetaRange / arcLength; + } + + // Adjust rotation, radius, and position + var result = new Vector2[arc.Length]; + + for (int i = 0; i < arc.Length; i++) + { + result[i] = new Vector2( + (float)((Math.Cos(pr.ThetaStart) * arc[i].X + -Math.Sin(pr.ThetaStart) * pr.Direction * arc[i].Y) * pr.Radius + pr.Centre.X), + (float)((Math.Sin(pr.ThetaStart) * arc[i].X + Math.Cos(pr.ThetaStart) * pr.Direction * arc[i].Y) * pr.Radius + pr.Centre.Y)); + } + + return result; + } + + /// + /// Converts catmull anchors to bezier anchors. + /// + /// The control point positions to convert. + public static Vector2[][] ConvertCatmullToBezierAnchors(ReadOnlySpan controlPoints) + { + int iLen = controlPoints.Length; + var bezier = new Vector2[iLen - 1][]; + + for (int i = 0; i < iLen - 1; i++) + { + var v1 = i > 0 ? controlPoints[i - 1] : controlPoints[i]; + var v2 = controlPoints[i]; + var v3 = i < iLen - 1 ? controlPoints[i + 1] : v2 + v2 - v1; + var v4 = i < iLen - 2 ? controlPoints[i + 2] : v3 + v3 - v2; + + bezier[i] = new[] + { + v2, + (-v1 + 6 * v2 + v3) / 6, + (-v4 + 6 * v3 + v2) / 6, + v3 + }; + } + + return bezier; + } + + /// + /// Converts linear anchors to bezier anchors. + /// + /// The control point positions to convert. + public static Vector2[][] ConvertLinearToBezierAnchors(ReadOnlySpan controlPoints) + { + int iLen = controlPoints.Length; + var bezier = new Vector2[iLen - 1][]; + + for (int i = 0; i < iLen - 1; i++) + { + bezier[i] = new[] + { + controlPoints[i], + controlPoints[i + 1] + }; + } + + return bezier; + } + } +} From 86d5fcc26d6a86f7a57bf87285cb53d04da54959 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Oct 2022 19:30:42 +0200 Subject: [PATCH 058/261] Added tests --- .../Gameplay/TestSceneBezierConverter.cs | 172 ++++++++++++++++++ osu.Game/Rulesets/Objects/BezierConverter.cs | 3 + 2 files changed, 175 insertions(+) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs new file mode 100644 index 0000000000..c915ae0054 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -0,0 +1,172 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Lines; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osuTK; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public class TestSceneBezierConverter : OsuTestScene + { + private readonly SmoothPath drawablePath; + private readonly SmoothPath controlPointDrawablePath; + private readonly SmoothPath convertedDrawablePath; + private readonly SmoothPath convertedControlPointDrawablePath; + private SliderPath path; + private SliderPath convertedPath; + + public TestSceneBezierConverter() + { + Children = new Drawable[] + { + new Container + { + Children = + new Drawable[] + { + drawablePath = new SmoothPath(), + controlPointDrawablePath = new SmoothPath + { + Colour = Colour4.Magenta, + PathRadius = 1f + } + }, + Position = new Vector2(100) + }, + new Container + { + Children = + new Drawable[] + { + convertedDrawablePath = new SmoothPath(), + convertedControlPointDrawablePath = new SmoothPath + { + Colour = Colour4.Magenta, + PathRadius = 1f + } + }, + Position = new Vector2(100, 300) + } + }; + } + + [SetUp] + public void Setup() => Schedule(() => + { + path = new SliderPath(); + convertedPath = new SliderPath(); + + path.Version.ValueChanged += getConvertedControlPoints; + }); + + private void getConvertedControlPoints(ValueChangedEvent obj) + { + convertedPath.ControlPoints.Clear(); + convertedPath.ControlPoints.AddRange(BezierConverter.ConvertToModernBezier(path.ControlPoints)); + } + + protected override void Update() + { + base.Update(); + + if (path != null) + { + List vertices = new List(); + path.GetPathToProgress(vertices, 0, 1); + + drawablePath.Vertices = vertices; + controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList(); + if (controlPointDrawablePath.Vertices.Count > 0) + controlPointDrawablePath.Position = drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]); + } + + if (convertedPath != null) + { + List vertices = new List(); + convertedPath.GetPathToProgress(vertices, 0, 1); + + convertedDrawablePath.Vertices = vertices; + convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList(); + if (convertedControlPointDrawablePath.Vertices.Count > 0) + convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0]) - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]); + } + } + + [Test] + public void TestEmptyPath() + { + } + + [TestCase(PathType.Linear)] + [TestCase(PathType.Bezier)] + [TestCase(PathType.Catmull)] + [TestCase(PathType.PerfectCurve)] + public void TestSingleSegment(PathType type) + => AddStep("create path", () => path.ControlPoints.AddRange(createSegment(type, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + + [TestCase(PathType.Linear)] + [TestCase(PathType.Bezier)] + [TestCase(PathType.Catmull)] + [TestCase(PathType.PerfectCurve)] + public void TestMultipleSegment(PathType type) + { + AddStep("create path", () => + { + path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(type, new Vector2(0, 100), new Vector2(100), Vector2.Zero)); + }); + } + + [TestCase(0, 100)] + [TestCase(1, 100)] + [TestCase(5, 100)] + [TestCase(10, 100)] + [TestCase(30, 100)] + [TestCase(50, 100)] + [TestCase(100, 100)] + [TestCase(100, 1)] + public void TestPerfectCurveAngles(float height, float width) + { + AddStep("create path", () => + { + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(width / 2, height), new Vector2(width, 0))); + }); + } + + [TestCase(2)] + [TestCase(4)] + public void TestPerfectCurveFallbackScenarios(int points) + { + AddStep("create path", () => + { + switch (points) + { + case 2: + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100))); + break; + + case 4: + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); + break; + } + }); + } + + private List createSegment(PathType type, params Vector2[] controlPoints) + { + var points = controlPoints.Select(p => new PathControlPoint { Position = p }).ToList(); + points[0].Type = type; + return points; + } + } +} diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 414341641f..9220993559 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -245,6 +245,9 @@ namespace osu.Game.Rulesets.Objects /// The control point positions to convert. public static Vector2[] ConvertCircleToBezierAnchors(ReadOnlySpan controlPoints) { + if (controlPoints.Length != 3) + return controlPoints.ToArray(); + var pr = circularArcProperties(controlPoints); if (!pr.IsValid) return controlPoints.ToArray(); From 707b9eaa502368e085702387f90943780879db4e Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 13:07:44 +0900 Subject: [PATCH 059/261] Remove unnecessary null-forgiving --- .../Difficulty/Evaluators/ColourEvaluator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs index 36f8babc6b..9f63e84867 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs @@ -55,11 +55,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators double difficulty = 0.0d; if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak - difficulty += EvaluateDifficultyOf(colour.MonoStreak!); + difficulty += EvaluateDifficultyOf(colour.MonoStreak); if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern - difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern!); + difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern); if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern - difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern!); + difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern); return difficulty; } From 295c40581b766b14d2fe9d453a396608aeb142d7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 28 Oct 2022 20:18:11 +0300 Subject: [PATCH 060/261] Add a global popover container --- osu.Game/OsuGameBase.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 7d9ed7bf3e..2e2f6f0832 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,6 +18,7 @@ using osu.Framework.Development; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Handlers; @@ -350,9 +351,13 @@ namespace osu.Game (GlobalCursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both - }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) + }).WithChild(new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Child = content = new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + } }), // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything. globalBindings = new GlobalActionContainer(this) From 9df96aab38fa7e83ef2055af3c96189e24d7fb50 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 28 Oct 2022 22:17:45 +0300 Subject: [PATCH 061/261] Remove local popover containers --- osu.Game/Overlays/BeatmapSetOverlay.cs | 24 +++++++------------ .../Overlays/Changelog/ChangelogContent.cs | 17 +++---------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 904fd6ead6..207dc91ca5 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet; @@ -45,25 +44,20 @@ namespace osu.Game.Overlays Info info; CommentsSection comments; - Child = new PopoverContainer + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = new FillFlowContainer + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] + info = new Info(), + new ScoresContainer { - info = new Info(), - new ScoresContainer - { - Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } - }, - comments = new CommentsSection() - } + Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } + }, + comments = new CommentsSection() } }; diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index 2b54df7226..e04133f2e4 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -1,35 +1,24 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System; -using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Changelog { - public class ChangelogContent : PopoverContainer + public class ChangelogContent : FillFlowContainer { - public Action BuildSelected; + public Action? BuildSelected; public void SelectBuild(APIChangelogBuild build) => BuildSelected?.Invoke(build); - protected override Container Content { get; } - public ChangelogContent() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - - base.Content.Add(Content = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical - }); + Direction = FillDirection.Vertical; } } } From 24c27e62f6e9a45774b78cf44cbe0b9df21b10d0 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:25:15 +0800 Subject: [PATCH 062/261] Remove nullable disable annotation in the issue and issue template-related class. --- osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/Issue.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs | 2 -- 6 files changed, 12 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs b/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs index 3e2150fe0b..ae943cfda9 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit.Checks.Components { /// diff --git a/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs b/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs index 5c9021ba61..cebb2f5455 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit.Checks.Components { public class CheckMetadata diff --git a/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs b/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs index 333ec0a810..141de55f1d 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; namespace osu.Game.Rulesets.Edit.Checks.Components diff --git a/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs b/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs index b3f227f364..2bc9930e8f 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; diff --git a/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs b/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs index 9101d83fa7..97df79ecd8 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using Humanizer; using osu.Framework.Graphics; using osuTK.Graphics; diff --git a/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs b/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs index a957cbc296..1f708209fe 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit.Checks.Components { /// From db48a57fa7f52be8acee66942e92c118b6a23eb8 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:28:49 +0800 Subject: [PATCH 063/261] Remove nullable disable annotation in some checks class. --- osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs | 6 ++---- osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs | 2 -- 13 files changed, 6 insertions(+), 32 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs index a66c00d78b..f712a7867d 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using osu.Game.Beatmaps; @@ -45,7 +43,7 @@ namespace osu.Game.Rulesets.Edit.Checks foreach (string filename in videoPaths) { - string storagePath = beatmapSet?.GetPathForFile(filename); + string? storagePath = beatmapSet?.GetPathForFile(filename); if (storagePath == null) { diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs index fa3e114c55..94c48c300a 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs index 96254ba6fd..daa33fb0da 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; @@ -29,7 +27,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - string audioFile = context.Beatmap.Metadata?.AudioFile; + string? audioFile = context.Beatmap.Metadata?.AudioFile; if (string.IsNullOrEmpty(audioFile)) yield break; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs index 96840fd344..067800b409 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs index be0c4501e7..23fa28e7bc 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using osu.Game.Beatmaps; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - string backgroundFile = context.Beatmap.Metadata?.BackgroundFile; + string? backgroundFile = context.Beatmap.Metadata?.BackgroundFile; if (backgroundFile == null) yield break; @@ -51,7 +49,7 @@ namespace osu.Game.Rulesets.Edit.Checks else if (texture.Width < low_width || texture.Height < low_height) yield return new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height); - string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(backgroundFile); + string? storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(backgroundFile); using (Stream stream = context.WorkingBeatmap.GetStream(storagePath)) { diff --git a/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs index 02579b675d..ba5fbcf58d 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Objects; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs b/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs index b25abb0cfc..3358e81d5f 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Audio; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs index 67d480c28c..6b256d025a 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks } // If the file is set, also make sure it still exists. - string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(filename); + string? storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(filename); if (storagePath != null) yield break; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs index 00b1ca9dc9..d755b5bba5 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -59,7 +57,7 @@ namespace osu.Game.Rulesets.Edit.Checks } } - private IEnumerable getVolumeIssues(HitObject hitObject, HitObject sampledHitObject = null) + private IEnumerable getVolumeIssues(HitObject hitObject, HitObject? sampledHitObject = null) { sampledHitObject ??= hitObject; if (!sampledHitObject.Samples.Any()) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs b/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs index 2a222aece0..1c2ea36948 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs index a3c52cf547..ded1bb54ca 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs b/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs index 987711188e..75cb08002f 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using osu.Game.Extensions; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs index 3b30fab934..b9be94736b 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Objects; From 505ec800da7b55876099ceb63548d1428da51c7e Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:29:54 +0800 Subject: [PATCH 064/261] File name should be nullable. --- osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs | 2 +- osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs | 2 +- osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs index 94c48c300a..e922ddf023 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks { protected override CheckCategory Category => CheckCategory.Audio; protected override string TypeOfFile => "audio"; - protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.AudioFile; + protected override string? GetFilename(IBeatmap beatmap) => beatmap.Metadata?.AudioFile; } } diff --git a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs index 067800b409..4ca93a9807 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks { protected override CheckCategory Category => CheckCategory.Resources; protected override string TypeOfFile => "background"; - protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.BackgroundFile; + protected override string? GetFilename(IBeatmap beatmap) => beatmap.Metadata?.BackgroundFile; } } diff --git a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs index 6b256d025a..9a921ba808 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Edit.Checks { protected abstract CheckCategory Category { get; } protected abstract string TypeOfFile { get; } - protected abstract string GetFilename(IBeatmap beatmap); + protected abstract string? GetFilename(IBeatmap beatmap); public CheckMetadata Metadata => new CheckMetadata(Category, $"Missing {TypeOfFile}"); @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - string filename = GetFilename(context.Beatmap); + string? filename = GetFilename(context.Beatmap); if (string.IsNullOrEmpty(filename)) { From a1a9238bd161d553ece76851b62204c653f3c0d8 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:31:07 +0800 Subject: [PATCH 065/261] Use empty string instead of null because issue template not accept null. --- osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs index d755b5bba5..5b59a81f91 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Edit.Checks if (edgeType == EdgeType.None) yield break; - string postfix = hitObject is IHasDuration ? edgeType.ToString().ToLowerInvariant() : null; + string postfix = hitObject is IHasDuration ? edgeType.ToString().ToLowerInvariant() : string.Empty; if (maxVolume <= muted_threshold) { From 4c9c65856ca117dd34122e4987c3c0570902d077 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:51:56 +0800 Subject: [PATCH 066/261] Remove the nullable disable annotation in the testing beatmap and mark some of the properties as nullable. This class will be used in some check test cases. --- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 3d7ebad831..7d2aa99dbe 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using osu.Framework.Audio; using osu.Framework.Audio.Track; @@ -16,7 +14,7 @@ namespace osu.Game.Tests.Beatmaps public class TestWorkingBeatmap : WorkingBeatmap { private readonly IBeatmap beatmap; - private readonly Storyboard storyboard; + private readonly Storyboard? storyboard; /// /// Create an instance which provides the when requested. @@ -24,7 +22,7 @@ namespace osu.Game.Tests.Beatmaps /// The beatmap. /// An optional storyboard. /// The . - public TestWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null, AudioManager audioManager = null) + public TestWorkingBeatmap(IBeatmap beatmap, Storyboard? storyboard = null, AudioManager? audioManager = null) : base(beatmap.BeatmapInfo, audioManager) { this.beatmap = beatmap; @@ -37,12 +35,12 @@ namespace osu.Game.Tests.Beatmaps protected override Storyboard GetStoryboard() => storyboard ?? base.GetStoryboard(); - protected internal override ISkin GetSkin() => null; + protected internal override ISkin? GetSkin() => null; - public override Stream GetStream(string storagePath) => null; + public override Stream? GetStream(string storagePath) => null; - protected override Texture GetBackground() => null; + protected override Texture? GetBackground() => null; - protected override Track GetBeatmapTrack() => null; + protected override Track? GetBeatmapTrack() => null; } } From 6ce3841686bbbd6d2630e13d37ae1f1419c1e88b Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:36:22 +0800 Subject: [PATCH 067/261] Remove nullable disable annotation in the test case. --- .../Editing/Checks/CheckAudioInVideoTest.cs | 6 ++---- .../Editing/Checks/CheckAudioQualityTest.cs | 6 ++---- .../Editing/Checks/CheckBackgroundQualityTest.cs | 11 ++++------- .../Editing/Checks/CheckConcurrentObjectsTest.cs | 4 +--- .../Editing/Checks/CheckFewHitsoundsTest.cs | 8 +++----- .../Editing/Checks/CheckFilePresenceTest.cs | 6 ++---- .../Editing/Checks/CheckMutedObjectsTest.cs | 6 ++---- osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs | 2 -- .../Editing/Checks/CheckTooShortAudioFilesTest.cs | 6 ++---- .../Editing/Checks/CheckUnsnappedObjectsTest.cs | 6 ++---- .../Editing/Checks/CheckZeroByteFilesTest.cs | 6 ++---- .../Editing/Checks/CheckZeroLengthObjectsTest.cs | 4 +--- .../Editing/Checks/MockNestableHitObject.cs | 2 -- 13 files changed, 23 insertions(+), 50 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs index 947e884494..9f253527fc 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using System.Linq; using Moq; @@ -20,8 +18,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckAudioInVideoTest { - private CheckAudioInVideo check; - private IBeatmap beatmap; + private CheckAudioInVideo check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs index 50e6087526..3a2cdaf233 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using Moq; using NUnit.Framework; @@ -19,8 +17,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckAudioQualityTest { - private CheckAudioQuality check; - private IBeatmap beatmap; + private CheckAudioQuality check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index f91e83a556..d0dffb8fad 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.IO; using System.Linq; -using JetBrains.Annotations; using Moq; using NUnit.Framework; using osu.Framework.Graphics.Rendering.Dummy; @@ -21,8 +18,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckBackgroundQualityTest { - private CheckBackgroundQuality check; - private IBeatmap beatmap; + private CheckBackgroundQuality check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() @@ -118,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks stream.Verify(x => x.Close(), Times.Once()); } - private BeatmapVerifierContext getContext(Texture background, [CanBeNull] Stream stream = null) + private BeatmapVerifierContext getContext(Texture background, Stream? stream = null) { return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object); } @@ -128,7 +125,7 @@ namespace osu.Game.Tests.Editing.Checks /// /// The texture of the background. /// The stream representing the background file. - private Mock getMockWorkingBeatmap(Texture background, [CanBeNull] Stream stream = null) + private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null) { stream ??= new MemoryStream(new byte[1024 * 1024]); diff --git a/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs index 9c1dd2c1e8..b5c6568583 100644 --- a/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckConcurrentObjectsTest { - private CheckConcurrentObjects check; + private CheckConcurrentObjects check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs b/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs index 82bb2e59c9..01781b98ad 100644 --- a/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -20,10 +18,10 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckFewHitsoundsTest { - private CheckFewHitsounds check; + private CheckFewHitsounds check = null!; - private List notHitsounded; - private List hitsounded; + private List notHitsounded = null!; + private List hitsounded = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs b/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs index 2f18720a5b..89bb2f9396 100644 --- a/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using NUnit.Framework; using osu.Game.Beatmaps; @@ -16,8 +14,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckFilePresenceTest { - private CheckBackgroundPresence check; - private IBeatmap beatmap; + private CheckBackgroundPresence check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs index 622386405a..1e1c214c30 100644 --- a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -21,8 +19,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckMutedObjectsTest { - private CheckMutedObjects check; - private ControlPointInfo cpi; + private CheckMutedObjects check = null!; + private ControlPointInfo cpi = null!; private const int volume_regular = 50; private const int volume_low = 15; diff --git a/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs b/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs index 405738cd55..9067714ff9 100644 --- a/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs +++ b/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Models; namespace osu.Game.Tests.Editing.Checks diff --git a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs index 7d33b92dbe..05856de556 100644 --- a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using System.IO; using System.Linq; @@ -22,8 +20,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckTooShortAudioFilesTest { - private CheckTooShortAudioFiles check; - private IBeatmap beatmap; + private CheckTooShortAudioFiles check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs index f647bf8d8e..c9335dcda5 100644 --- a/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,8 +19,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckUnsnappedObjectsTest { - private CheckUnsnappedObjects check; - private ControlPointInfo cpi; + private CheckUnsnappedObjects check = null!; + private ControlPointInfo cpi = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs index 793cc70a3f..5c66e1beaa 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using System.Linq; using Moq; @@ -17,8 +15,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckZeroByteFilesTest { - private CheckZeroByteFiles check; - private IBeatmap beatmap; + private CheckZeroByteFiles check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs index 1c1965ab56..648f02839f 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckZeroLengthObjectsTest { - private CheckZeroLengthObjects check; + private CheckZeroLengthObjects check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs b/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs index 6c0306d63d..29938839d3 100644 --- a/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs +++ b/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Threading; using osu.Game.Rulesets.Objects; From 500bf90a34b1c02fa17255351b0f9582dbf3484e Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:58:16 +0800 Subject: [PATCH 068/261] Mark as accept the nullable stream. --- osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs | 2 +- osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs | 4 ++-- osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs index 9f253527fc..9774a8ebb6 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Editing.Checks Assert.That(issues.Single().Template is CheckAudioInVideo.IssueTemplateMissingFile); } - private BeatmapVerifierContext getContext(Stream resourceStream) + private BeatmapVerifierContext getContext(Stream? resourceStream) { var storyboard = new Storyboard(); var layer = storyboard.GetLayer("Video"); diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index d0dffb8fad..5d3fd9cd65 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks stream.Verify(x => x.Close(), Times.Once()); } - private BeatmapVerifierContext getContext(Texture background, Stream? stream = null) + private BeatmapVerifierContext getContext(Texture? background, Stream? stream = null) { return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object); } @@ -125,7 +125,7 @@ namespace osu.Game.Tests.Editing.Checks /// /// The texture of the background. /// The stream representing the background file. - private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null) + private Mock getMockWorkingBeatmap(Texture? background, Stream? stream = null) { stream ??= new MemoryStream(new byte[1024 * 1024]); diff --git a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs index 05856de556..4918369460 100644 --- a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Editing.Checks } } - private BeatmapVerifierContext getContext(Stream resourceStream) + private BeatmapVerifierContext getContext(Stream? resourceStream) { var mockWorkingBeatmap = new Mock(beatmap, null, null); mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(resourceStream); From c8c76f23513f91f7d8d2ace60487eca351f77444 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:55:53 +0800 Subject: [PATCH 069/261] Use AsNonNull() because the type does not accept the null case. --- osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs | 3 ++- osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs | 3 ++- osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs index 3a2cdaf233..8e269cbab2 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs @@ -5,6 +5,7 @@ using System.Linq; using Moq; using NUnit.Framework; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; @@ -41,7 +42,7 @@ namespace osu.Game.Tests.Editing.Checks var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Track).Returns((Track)null); + mock.SetupGet(w => w.Track).Returns(default(Track?).AsNonNull()); Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty); } diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index 5d3fd9cd65..1aead6d78c 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Rendering.Dummy; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -131,7 +132,7 @@ namespace osu.Game.Tests.Editing.Checks var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Background).Returns(background); + mock.SetupGet(w => w.Background).Returns(background.AsNonNull()); mock.Setup(w => w.GetStream(It.IsAny())).Returns(stream); return mock; diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs index 5c66e1beaa..7c2b1690af 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks; @@ -72,7 +73,7 @@ namespace osu.Game.Tests.Editing.Checks private BeatmapVerifierContext getContextMissing() { var mockWorkingBeatmap = new Mock(); - mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns((Stream)null); + mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(default(Stream?).AsNonNull()); return new BeatmapVerifierContext(beatmap, mockWorkingBeatmap.Object); } From 94dd4045f1ff6d9ac1324720725047df6538a9f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Oct 2022 15:42:17 +0900 Subject: [PATCH 070/261] Remove borrowed framework code --- osu.Game/Rulesets/Objects/BezierConverter.cs | 81 +------------------- 1 file changed, 1 insertion(+), 80 deletions(-) diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 9220993559..9c3ea5cf6e 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -39,85 +39,6 @@ namespace osu.Game.Rulesets.Objects new[] { new Vector2d(1, 0), new Vector2d(1, 1.2447058f), new Vector2d(-0.8526471f, 2.118367f), new Vector2d(-2.6211002f, 7.854936e-06f), new Vector2d(-0.8526448f, -2.118357f), new Vector2d(1, -1.2447058f), new Vector2d(1, 0) }) }; - #region CircularArcProperties - - //TODO: Get this from osu!framework instead - public readonly struct CircularArcProperties - { - public readonly bool IsValid; - public readonly double ThetaStart; - public readonly double ThetaRange; - public readonly double Direction; - public readonly float Radius; - public readonly Vector2 Centre; - - public double ThetaEnd => ThetaStart + ThetaRange * Direction; - - public CircularArcProperties(double thetaStart, double thetaRange, double direction, float radius, Vector2 centre) - { - IsValid = true; - ThetaStart = thetaStart; - ThetaRange = thetaRange; - Direction = direction; - Radius = radius; - Centre = centre; - } - } - - /// - /// Computes various properties that can be used to approximate the circular arc. - /// - /// Three distinct points on the arc. - private static CircularArcProperties circularArcProperties(ReadOnlySpan controlPoints) - { - Vector2 a = controlPoints[0]; - Vector2 b = controlPoints[1]; - Vector2 c = controlPoints[2]; - - // If we have a degenerate triangle where a side-length is almost zero, then give up and fallback to a more numerically stable method. - if (Precision.AlmostEquals(0, (b.Y - a.Y) * (c.X - a.X) - (b.X - a.X) * (c.Y - a.Y))) - return default; // Implicitly sets `IsValid` to false - - // See: https://en.wikipedia.org/wiki/Circumscribed_circle#Cartesian_coordinates_2 - float d = 2 * (a.X * (b - c).Y + b.X * (c - a).Y + c.X * (a - b).Y); - float aSq = a.LengthSquared; - float bSq = b.LengthSquared; - float cSq = c.LengthSquared; - - Vector2 centre = new Vector2( - aSq * (b - c).Y + bSq * (c - a).Y + cSq * (a - b).Y, - aSq * (c - b).X + bSq * (a - c).X + cSq * (b - a).X) / d; - - Vector2 dA = a - centre; - Vector2 dC = c - centre; - - float r = dA.Length; - - double thetaStart = Math.Atan2(dA.Y, dA.X); - double thetaEnd = Math.Atan2(dC.Y, dC.X); - - while (thetaEnd < thetaStart) - thetaEnd += 2 * Math.PI; - - double dir = 1; - double thetaRange = thetaEnd - thetaStart; - - // Decide in which direction to draw the circle, depending on which side of - // AC B lies. - Vector2 orthoAtoC = c - a; - orthoAtoC = new Vector2(orthoAtoC.Y, -orthoAtoC.X); - - if (Vector2.Dot(orthoAtoC, b - a) < 0) - { - dir = -dir; - thetaRange = 2 * Math.PI - thetaRange; - } - - return new CircularArcProperties(thetaStart, thetaRange, dir, r, centre); - } - - #endregion - public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) { Vector2[] vertices = new Vector2[controlPoints.Count]; @@ -248,7 +169,7 @@ namespace osu.Game.Rulesets.Objects if (controlPoints.Length != 3) return controlPoints.ToArray(); - var pr = circularArcProperties(controlPoints); + var pr = new CircularArcProperties(controlPoints); if (!pr.IsValid) return controlPoints.ToArray(); From e38ba5e4c620d986dbae99c83137f183efd6cc9f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Oct 2022 15:46:57 +0900 Subject: [PATCH 071/261] Apply nullability to new test scene --- .../Gameplay/TestSceneBezierConverter.cs | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs index c915ae0054..701f30bfd4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -22,8 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly SmoothPath controlPointDrawablePath; private readonly SmoothPath convertedDrawablePath; private readonly SmoothPath convertedControlPointDrawablePath; - private SliderPath path; - private SliderPath convertedPath; + + private SliderPath path = null!; + private SliderPath convertedPath = null!; public TestSceneBezierConverter() { @@ -58,16 +57,20 @@ namespace osu.Game.Tests.Visual.Gameplay Position = new Vector2(100, 300) } }; + + resetPath(); } [SetUp] - public void Setup() => Schedule(() => + public void Setup() => Schedule(resetPath); + + private void resetPath() { path = new SliderPath(); convertedPath = new SliderPath(); path.Version.ValueChanged += getConvertedControlPoints; - }); + } private void getConvertedControlPoints(ValueChangedEvent obj) { @@ -79,26 +82,30 @@ namespace osu.Game.Tests.Visual.Gameplay { base.Update(); - if (path != null) - { - List vertices = new List(); - path.GetPathToProgress(vertices, 0, 1); + List vertices = new List(); - drawablePath.Vertices = vertices; - controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList(); - if (controlPointDrawablePath.Vertices.Count > 0) - controlPointDrawablePath.Position = drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]); + path.GetPathToProgress(vertices, 0, 1); + + drawablePath.Vertices = vertices; + controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList(); + + if (controlPointDrawablePath.Vertices.Count > 0) + { + controlPointDrawablePath.Position = + drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]); } - if (convertedPath != null) - { - List vertices = new List(); - convertedPath.GetPathToProgress(vertices, 0, 1); + vertices.Clear(); - convertedDrawablePath.Vertices = vertices; - convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList(); - if (convertedControlPointDrawablePath.Vertices.Count > 0) - convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0]) - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]); + convertedPath.GetPathToProgress(vertices, 0, 1); + + convertedDrawablePath.Vertices = vertices; + convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList(); + + if (convertedControlPointDrawablePath.Vertices.Count > 0) + { + convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0]) + - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]); } } From 414e21c65758beaf70beb0a75aec0edfb2f49407 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 31 Oct 2022 11:39:14 +0100 Subject: [PATCH 072/261] Added xmldoc to public methods --- osu.Game/Rulesets/Objects/BezierConverter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 9c3ea5cf6e..1ea79f8fd4 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -40,6 +40,12 @@ namespace osu.Game.Rulesets.Objects }; public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) + /// + /// Converts a slider path to bezier control point positions compatible with the legacy osu! client. + /// + /// The control points of the path. + /// The offset for the whole path. + /// The list of legacy bezier control point positions. { Vector2[] vertices = new Vector2[controlPoints.Count]; for (int i = 0; i < controlPoints.Count; i++) @@ -90,6 +96,11 @@ namespace osu.Game.Rulesets.Objects return result; } + /// + /// Converts a path of control points to an identical path using only Bezier type control points. + /// + /// The control points of the path. + /// The list of bezier control points. public static List ConvertToModernBezier(IList controlPoints) { Vector2[] vertices = new Vector2[controlPoints.Count]; From 04613038954cf4a977f4e7d91b7e0f3fad2edbce Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 31 Oct 2022 11:39:41 +0100 Subject: [PATCH 073/261] Change return type to List --- osu.Game/Rulesets/Objects/BezierConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 1ea79f8fd4..ebee36a7db 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -39,13 +39,13 @@ namespace osu.Game.Rulesets.Objects new[] { new Vector2d(1, 0), new Vector2d(1, 1.2447058f), new Vector2d(-0.8526471f, 2.118367f), new Vector2d(-2.6211002f, 7.854936e-06f), new Vector2d(-0.8526448f, -2.118357f), new Vector2d(1, -1.2447058f), new Vector2d(1, 0) }) }; - public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) /// /// Converts a slider path to bezier control point positions compatible with the legacy osu! client. /// /// The control points of the path. /// The offset for the whole path. /// The list of legacy bezier control point positions. + public static List ConvertToLegacyBezier(IList controlPoints, Vector2 position) { Vector2[] vertices = new Vector2[controlPoints.Count]; for (int i = 0; i < controlPoints.Count; i++) From 706adfb28c290eda95bda8e982e062ad79760c18 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 13:57:34 +0900 Subject: [PATCH 074/261] Improve messaging when ruleset load fails --- osu.Game/Rulesets/RulesetStore.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index fdbcd0ed1e..e2b8cd2c4e 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -158,7 +158,7 @@ namespace osu.Game.Rulesets } catch (Exception e) { - LogFailedLoad(assembly.FullName, e); + LogFailedLoad(assembly.GetName().Name.Split('.').Last(), e); } } @@ -168,14 +168,14 @@ namespace osu.Game.Rulesets GC.SuppressFinalize(this); } - protected virtual void Dispose(bool disposing) + protected void Dispose(bool disposing) { AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly; } protected void LogFailedLoad(string name, Exception exception) { - Logger.Log($"Could not load ruleset {name}. Please check for an update from the developer.", level: LogLevel.Error); + Logger.Log($"Could not load ruleset \"{name}\". Please check for an update from the developer.", level: LogLevel.Error); Logger.Log($"Ruleset load failed: {exception}"); } From 2a88409dfe65fd5e48c52bbfdb0397e8d8b4f575 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 15:00:23 +0900 Subject: [PATCH 075/261] Fix time snap of sliders not matching when SV is not 1.0x This regressed with https://github.com/ppy/osu/pull/20850 because the function was used in other places which expect it to factor slider velocity into the equation. Rather than reverting, I've added a new argument, as based on the method naming alone it was hard to discern whether SV should actually be considered. The reason for the change in #20850 was to avoid the SV coming in from a reference object which may not have a correct SV in the first place. In such cases, passing `false` to the function will give the expected behaviour. --- osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs | 2 +- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 6 +++--- osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs | 3 ++- .../Screens/Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 53b6db2277..01a49c7dea 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -193,7 +193,7 @@ namespace osu.Game.Tests.Visual.Editing IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; - public float GetBeatSnapDistanceAt(HitObject referenceObject) => beat_snap_distance; + public float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) => beat_snap_distance; public float DurationToDistance(HitObject referenceObject, double duration) => (float)duration; diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index ca7ca79813..840ed7682a 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -259,9 +259,9 @@ namespace osu.Game.Rulesets.Edit return true; } - public virtual float GetBeatSnapDistanceAt(HitObject referenceObject) + public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) { - return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); + return (float)(100 * (useReferenceSliderVelocity ? referenceObject.DifficultyControlPoint.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); } public virtual float DurationToDistance(HitObject referenceObject, double duration) @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Edit public virtual double DistanceToDuration(HitObject referenceObject, float distance) { double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); - return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength; + return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength * referenceObject.DifficultyControlPoint.SliderVelocity; } public virtual double FindSnappedDuration(HitObject referenceObject, float distance) diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs index 5ad1cc78ff..6fbd994e23 100644 --- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -27,8 +27,9 @@ namespace osu.Game.Rulesets.Edit /// Retrieves the distance between two points within a timing point that are one beat length apart. /// /// An object to be used as a reference point for this operation. + /// Whether the 's slider velocity should be factored into the returned distance. /// The distance between two points residing in the timing point that are one beat length apart. - float GetBeatSnapDistanceAt(HitObject referenceObject); + float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true); /// /// Converts a duration to a distance without applying any snapping. diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 69c7fc2775..c179e7f0c2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void updateSpacing() { float distanceSpacingMultiplier = (float)DistanceSpacingMultiplier.Value; - float beatSnapDistance = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject); + float beatSnapDistance = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject, false); DistanceBetweenTicks = beatSnapDistance * distanceSpacingMultiplier; From e8b791429569d3f9513265ae7ae4f23c2754aba7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 15:13:05 +0900 Subject: [PATCH 076/261] Add test coverage of new parameter --- ...tSceneHitObjectComposerDistanceSnapping.cs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index a98f931e7a..6fb21e38b0 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Editing { AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier); - assertSnapDistance(100 * multiplier); + assertSnapDistance(100 * multiplier, null, true); } [TestCase(1)] @@ -79,7 +79,20 @@ namespace osu.Game.Tests.Editing { SliderVelocity = multiplier } - }); + }, false); + } + + [TestCase(1)] + [TestCase(2)] + public void TestSpeedMultiplierDoesChangeDistanceSnap(float multiplier) + { + assertSnapDistance(100 * multiplier, new HitObject + { + DifficultyControlPoint = new DifficultyControlPoint + { + SliderVelocity = multiplier + } + }, true); } [TestCase(1)] @@ -88,7 +101,7 @@ namespace osu.Game.Tests.Editing { AddStep($"set divisor = {divisor}", () => BeatDivisor.Value = divisor); - assertSnapDistance(100f / divisor); + assertSnapDistance(100f / divisor, null, true); } [Test] @@ -197,8 +210,8 @@ namespace osu.Game.Tests.Editing assertSnappedDistance(400, 400); } - private void assertSnapDistance(float expectedDistance, HitObject? hitObject = null) - => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(hitObject ?? new HitObject()), () => Is.EqualTo(expectedDistance)); + private void assertSnapDistance(float expectedDistance, HitObject? refereneObject, bool includeSliderVelocity) + => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(refereneObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance)); private void assertDurationToDistance(double duration, float expectedDistance) => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(new HitObject(), duration) == expectedDistance); From d807d9d82299c85e13405472394061668e1f1698 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 15:21:17 +0900 Subject: [PATCH 077/261] Add failing test covering snap calculations with SV applied --- ...tSceneHitObjectComposerDistanceSnapping.cs | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 6fb21e38b0..f759ed5dcf 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; +using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; @@ -104,6 +105,28 @@ namespace osu.Game.Tests.Editing assertSnapDistance(100f / divisor, null, true); } + /// + /// The basic distance-duration functions should always include slider velocity of the reference object. + /// + [Test] + public void TestConversionsWithSliderVelocity() + { + const float base_distance = 100; + const float slider_velocity = 1.2f; + + var referenceObject = new HitObject + { + DifficultyControlPoint = new DifficultyControlPoint + { + SliderVelocity = slider_velocity + } + }; + + assertSnapDistance(base_distance * slider_velocity, referenceObject, true); + assertSnappedDistance(base_distance * slider_velocity + 10, base_distance * slider_velocity, referenceObject); + assertSnappedDuration(base_distance * slider_velocity + 10, 1000, referenceObject); + } + [Test] public void TestConvertDurationToDistance() { @@ -210,20 +233,20 @@ namespace osu.Game.Tests.Editing assertSnappedDistance(400, 400); } - private void assertSnapDistance(float expectedDistance, HitObject? refereneObject, bool includeSliderVelocity) - => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(refereneObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance)); + private void assertSnapDistance(float expectedDistance, HitObject? referenceObject, bool includeSliderVelocity) + => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(referenceObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); - private void assertDurationToDistance(double duration, float expectedDistance) - => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(new HitObject(), duration) == expectedDistance); + private void assertDurationToDistance(double duration, float expectedDistance, HitObject? referenceObject = null) + => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(referenceObject ?? new HitObject(), duration), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); - private void assertDistanceToDuration(float distance, double expectedDuration) - => AddAssert($"distance = {distance} -> duration = {expectedDuration}", () => composer.DistanceToDuration(new HitObject(), distance) == expectedDuration); + private void assertDistanceToDuration(float distance, double expectedDuration, HitObject? referenceObject = null) + => AddAssert($"distance = {distance} -> duration = {expectedDuration}", () => composer.DistanceToDuration(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDuration).Within(Precision.FLOAT_EPSILON)); - private void assertSnappedDuration(float distance, double expectedDuration) - => AddAssert($"distance = {distance} -> duration = {expectedDuration} (snapped)", () => composer.FindSnappedDuration(new HitObject(), distance) == expectedDuration); + private void assertSnappedDuration(float distance, double expectedDuration, HitObject? referenceObject = null) + => AddAssert($"distance = {distance} -> duration = {expectedDuration} (snapped)", () => composer.FindSnappedDuration(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDuration).Within(Precision.FLOAT_EPSILON)); - private void assertSnappedDistance(float distance, float expectedDistance) - => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(new HitObject(), distance) == expectedDistance); + private void assertSnappedDistance(float distance, float expectedDistance, HitObject? referenceObject = null) + => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); private class TestHitObjectComposer : OsuHitObjectComposer { From 8280605e92f6ab0d8220531a22b50895bf52ef27 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 16:31:09 +0900 Subject: [PATCH 078/261] Fix notch toggle not applying correctly after restart --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2ac2edd3fc..4f8098136f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -313,7 +313,7 @@ namespace osu.Game Beatmap.BindValueChanged(beatmapChanged, true); applySafeAreaConsiderations = LocalConfig.GetBindable(OsuSetting.SafeAreaConsiderations); - applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All); + applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All, true); } private ExternalLinkOpener externalLinkOpener; From d15585153daf759289013bce8f06e32ada67a501 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 17:07:58 +0900 Subject: [PATCH 079/261] Fix breadcrumb display in directory selector overlapping new "show hidden" button Closes #21034. --- .../UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs index 0833c7eb8b..08a569269e 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs @@ -25,10 +25,9 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override DirectorySelectorDirectory CreateDirectoryItem(DirectoryInfo directory, string displayName = null) => new OsuBreadcrumbDisplayDirectory(directory, displayName); - [BackgroundDependencyLoader] - private void load() + public OsuDirectorySelectorBreadcrumbDisplay() { - Height = 50; + Padding = new MarginPadding(15); } private class OsuBreadcrumbDisplayComputer : OsuBreadcrumbDisplayDirectory From 29bc653d24caaf65038ee39c75b7dab1bfc5307b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 17:14:30 +0900 Subject: [PATCH 080/261] Remove incorrect double multiplication and add missing test coverage --- .../Editing/TestSceneHitObjectComposerDistanceSnapping.cs | 3 +++ osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index f759ed5dcf..495a221159 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -125,6 +125,9 @@ namespace osu.Game.Tests.Editing assertSnapDistance(base_distance * slider_velocity, referenceObject, true); assertSnappedDistance(base_distance * slider_velocity + 10, base_distance * slider_velocity, referenceObject); assertSnappedDuration(base_distance * slider_velocity + 10, 1000, referenceObject); + + assertDistanceToDuration(base_distance * slider_velocity, 1000, referenceObject); + assertDurationToDistance(1000, base_distance * slider_velocity, referenceObject); } [Test] diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 840ed7682a..b0a2694a0a 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Edit public virtual double DistanceToDuration(HitObject referenceObject, float distance) { double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); - return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength * referenceObject.DifficultyControlPoint.SliderVelocity; + return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength; } public virtual double FindSnappedDuration(HitObject referenceObject, float distance) From 978d15955c911bf4eeef844a3eefabb71a6cb974 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 17:37:32 +0900 Subject: [PATCH 081/261] Fix control points not being cloned when running beatmap conversion Closes #20994. I haven't considered how this affects performance of difficulty calculation or otherwise. Seems like a sane initial fix which we can iterate on going forward. I've tested using the scenario in the linked issue. I'm not going to add test coverage because [BeatmapConversionTest](https://github.com/ppy/osu/blob/master/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs) should correctly cover this scenario once we are serialising control points as well. --- 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 4419791e43..c7c244bf0e 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -47,6 +47,7 @@ namespace osu.Game.Beatmaps // Shallow clone isn't enough to ensure we don't mutate beatmap info unexpectedly. // Can potentially be removed after `Beatmap.Difficulty` doesn't save back to `Beatmap.BeatmapInfo`. original.BeatmapInfo = original.BeatmapInfo.Clone(); + original.ControlPointInfo = original.ControlPointInfo.DeepClone(); return ConvertBeatmap(original, cancellationToken); } From 37407293aa516363a2f4290311db371bebdbd96f Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 1 Nov 2022 17:57:20 +0900 Subject: [PATCH 082/261] Adjust target and hold off mod multipliers --- osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs index ca9bc89473..2b0098744f 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override string Acronym => "HO"; - public override double ScoreMultiplier => 1; + public override double ScoreMultiplier => 0.9; public override LocalisableString Description => @"Replaces all hold notes with normal notes."; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs index 406968ba08..dc64918e03 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Conversion; public override IconUsage? Icon => OsuIcon.ModTarget; public override LocalisableString Description => @"Practice keeping up with the beat of the song."; - public override double ScoreMultiplier => 1; + public override double ScoreMultiplier => 0.1; public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { From c179f0bb521bdc6c757a39fe8cff8955b5d09864 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 18:31:30 +0900 Subject: [PATCH 083/261] Fix argon hit circle outer gradient getting smaller each state application --- osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index 36dc8c801d..4b4860e789 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon // This is to give it a bomb-like effect, with the border "triggering" its animation when getting close. using (BeginDelayedSequence(flash_in_duration / 12)) { - outerGradient.ResizeTo(outerGradient.Size * shrink_size, resize_duration, Easing.OutElasticHalf); + outerGradient.ResizeTo(OUTER_GRADIENT_SIZE * shrink_size, resize_duration, Easing.OutElasticHalf); outerGradient .FadeColour(Color4.White, 80) .Then() From ff60eebe216618e9f2e7ac1ca4fd114f0632c847 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 19:12:59 +0900 Subject: [PATCH 084/261] Fix large transform retention when adjusting accent colour of hitobject during pause --- .../Skinning/Argon/ArgonMainCirclePiece.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index 36dc8c801d..7269c7b151 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -121,12 +121,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f)); flash.Colour = colour.NewValue; - updateStateTransforms(drawableObject, drawableObject.State.Value); + // Accent colour may be changed many times during a paused gameplay state. + // Schedule the change to avoid transforms piling up. + Scheduler.AddOnce(updateStateTransforms); }, true); drawableObject.ApplyCustomUpdateState += updateStateTransforms; } + private void updateStateTransforms() => updateStateTransforms(drawableObject, drawableObject.State.Value); + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) { using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) From f014acfc8d54c453a50b0f9b22862f6c29204761 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 19:34:53 +0900 Subject: [PATCH 085/261] Fix `DrawableHitObject.AccentColour` not being updated if object entry is not attached --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d624164013..e5150576f2 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -266,6 +266,10 @@ namespace osu.Game.Rulesets.Objects.Drawables updateState(ArmedState.Miss, true); else updateState(ArmedState.Idle, true); + + // Combo colour may have been applied via a bindable flow while no object entry was attached. + // Update here to ensure we're in a good state. + UpdateComboColour(); } } From cd8dc9b17bbfb43e30a28ce4e765885380b494b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 19:47:20 +0900 Subject: [PATCH 086/261] Rename "Target" to "Target Practice" --- osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs | 2 +- .../Mods/{OsuModTarget.cs => OsuModTargetPractice.cs} | 7 +++---- osu.Game.Rulesets.Osu/OsuRuleset.cs | 6 +++--- 7 files changed, 11 insertions(+), 12 deletions(-) rename osu.Game.Rulesets.Osu/Mods/{OsuModTarget.cs => OsuModTargetPractice.cs} (98%) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs index 01d83b55e6..b4727b3c02 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests new object[] { LegacyMods.Autoplay, new[] { typeof(OsuModAutoplay) } }, new object[] { LegacyMods.SpunOut, new[] { typeof(OsuModSpunOut) } }, new object[] { LegacyMods.Autopilot, new[] { typeof(OsuModAutopilot) } }, - new object[] { LegacyMods.Target, new[] { typeof(OsuModTarget) } }, + new object[] { LegacyMods.Target, new[] { typeof(OsuModTargetPractice) } }, new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(OsuModHardRock), typeof(OsuModDoubleTime) } } }; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 618fcfe05d..1621bb50b1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public override LocalisableString Description => "It never gets boring!"; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTarget)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray(); [SettingSource("Angle sharpness", "How sharp angles should be", SettingControlType = typeof(SettingsSlider))] public BindableFloat AngleSharpness { get; } = new BindableFloat(7) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 9708800daa..f691731afe 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Automation; public override LocalisableString Description => @"Spinners will be automatically completed."; public override double ScoreMultiplier => 0.9; - public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTarget) }; + public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) }; public void ApplyToDrawableHitObject(DrawableHitObject hitObject) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs index 67b19124e1..af37f1e2e5 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.DifficultyIncrease; public override LocalisableString Description => @"Once you start a slider, follow precisely or get a miss."; public override double ScoreMultiplier => 1.0; - public override Type[] IncompatibleMods => new[] { typeof(ModClassic), typeof(OsuModTarget) }; + public override Type[] IncompatibleMods => new[] { typeof(ModClassic), typeof(OsuModTargetPractice) }; public void ApplyToDrawableHitObject(DrawableHitObject drawable) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs index 429fe30fc5..b4edb1581e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), - typeof(OsuModTarget), + typeof(OsuModTargetPractice), }).ToArray(); } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs similarity index 98% rename from osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs rename to osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs index dc64918e03..55c20eebe9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs @@ -32,11 +32,10 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModTarget : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset, - IApplicableToHealthProcessor, IApplicableToDifficulty, IApplicableFailOverride, - IHasSeed, IHidesApproachCircles + public class OsuModTargetPractice : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset, + IApplicableToHealthProcessor, IApplicableToDifficulty, IApplicableFailOverride, IHasSeed, IHidesApproachCircles { - public override string Name => "Target"; + public override string Name => "Target Practice"; public override string Acronym => "TP"; public override ModType Type => ModType.Conversion; public override IconUsage? Icon => OsuIcon.ModTarget; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 69df12ff6d..79a566e33c 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Osu yield return new OsuModSpunOut(); if (mods.HasFlagFast(LegacyMods.Target)) - yield return new OsuModTarget(); + yield return new OsuModTargetPractice(); if (mods.HasFlagFast(LegacyMods.TouchDevice)) yield return new OsuModTouchDevice(); @@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Osu value |= LegacyMods.SpunOut; break; - case OsuModTarget: + case OsuModTargetPractice: value |= LegacyMods.Target; break; @@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu case ModType.Conversion: return new Mod[] { - new OsuModTarget(), + new OsuModTargetPractice(), new OsuModDifficultyAdjust(), new OsuModClassic(), new OsuModRandom(), From e10424286448cc962a346234d0eea9ac2bad4c1e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 22:28:06 +0900 Subject: [PATCH 087/261] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b691751f13..8711ceec64 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9dd0d18817..8d45ebec57 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 6dce938ebf..76d2e727c8 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 5448c0209e0a824a0d6a75d1ae5577c79f03c549 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 10:14:40 +0900 Subject: [PATCH 088/261] Rename var --- .../Difficulty/TaikoPerformanceCalculator.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 4839a89646..317e4a2f72 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked. - bool rulesetTaiko = score.BeatmapInfo.Ruleset.OnlineID == 1; + bool taikoSpecificBeatmap = score.BeatmapInfo.Ruleset.OnlineID == 1; double multiplier = 1.13; @@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes, rulesetTaiko); - double accuracyValue = computeAccuracyValue(score, taikoAttributes, rulesetTaiko); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, taikoSpecificBeatmap); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, taikoSpecificBeatmap); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden) && rulesetTaiko) + if (score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficultyValue * Math.Pow(accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) { if (attributes.GreatHitWindow <= 0) return 0; @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty accuracyValue *= lengthBonus; // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && rulesetTaiko) + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus); return accuracyValue; From 2f3c80f884abd31f0b801a8b2c3193d619adfa60 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:08:29 +0900 Subject: [PATCH 089/261] Remove toggle and change method of application to blend with original colour --- osu.Game/Configuration/OsuConfigManager.cs | 4 +--- .../Settings/Sections/Gameplay/BeatmapSettings.cs | 14 -------------- .../Objects/Drawables/DrawableHitObject.cs | 10 +++++++--- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 08724aab4b..0d56ab8962 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,8 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.LastProcessedMetadataId, -1); - SetDefault(OsuSetting.NormaliseComboColourBrightness, false); - SetDefault(OsuSetting.ComboColourBrightness, 0.7f, 0f, 1f); + SetDefault(OsuSetting.ComboColourBrightness, 0f, -1f, 1f, 1f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -367,7 +366,6 @@ namespace osu.Game.Configuration AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, LastProcessedMetadataId, - NormaliseComboColourBrightness, SafeAreaConsiderations, ComboColourBrightness, } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 0de8f6509f..8bfa3e502c 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -17,13 +17,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; private readonly BindableFloat comboColourBrightness = new BindableFloat(); - private readonly BindableBool normaliseComboColourBrightness = new BindableBool(); [BackgroundDependencyLoader] private void load(OsuConfigManager config) { config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); - config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); Children = new Drawable[] { @@ -47,11 +45,6 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, - new SettingsCheckbox - { - LabelText = "Normalise combo colour brightness", - Current = normaliseComboColourBrightness - }, new SettingsSlider { LabelText = "Combo colour brightness", @@ -60,12 +53,5 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay } }; } - - protected override void LoadComplete() - { - base.LoadComplete(); - - normaliseComboColourBrightness.BindValueChanged(normalise => comboColourBrightness.Disabled = !normalise.NewValue, true); - } } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 8a32c015a3..077606cb3a 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -15,6 +15,7 @@ using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Primitives; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Configuration; using osu.Game.Graphics; @@ -174,7 +175,6 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. @@ -522,8 +522,12 @@ namespace osu.Game.Rulesets.Objects.Drawables Color4 colour = combo.GetComboColour(CurrentSkin); // Normalise the combo colour to the given brightness level. - if (normaliseComboColourBrightness.Value) - colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); + if (comboColourBrightness.Value != 0) + { + float pAdjust = 0.6f + 0.4f * comboColourBrightness.Value; + + colour = Interpolation.ValueAt(Math.Abs(comboColourBrightness.Value), colour, new HSPAColour(colour) { P = pAdjust }.ToColor4(), 0, 1, Easing.Out); + } AccentColour.Value = colour; } From 30800c925299a7701e3f83853f47ee22afeb8386 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 13:15:34 +0900 Subject: [PATCH 090/261] Add/adjust xmldocs --- osu.Game/Online/PersistentEndpointClient.cs | 11 +++++++++++ osu.Game/Online/PersistentEndpointClientConnector.cs | 8 ++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/PersistentEndpointClient.cs b/osu.Game/Online/PersistentEndpointClient.cs index e0307f7c6a..32c243fbbb 100644 --- a/osu.Game/Online/PersistentEndpointClient.cs +++ b/osu.Game/Online/PersistentEndpointClient.cs @@ -9,10 +9,21 @@ namespace osu.Game.Online { public abstract class PersistentEndpointClient : IAsyncDisposable { + /// + /// An event notifying the that the connection has been closed + /// public event Func? Closed; + /// + /// Notifies the that the connection has been closed. + /// + /// The exception that the connection closed with. protected Task InvokeClosed(Exception? exception) => Closed?.Invoke(exception) ?? Task.CompletedTask; + /// + /// Connects the client to the remote service to begin processing messages. + /// + /// A cancellation token to stop processing messages. public abstract Task ConnectAsync(CancellationToken cancellationToken); public virtual ValueTask DisposeAsync() diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 2ea0c95ec1..70e10c6c7d 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -14,7 +14,7 @@ namespace osu.Game.Online public abstract class PersistentEndpointClientConnector : IDisposable { /// - /// Whether this is connected to the hub, use to access the connection, if this is true. + /// Whether the managed connection is currently connected. When true use to access the connection. /// public IBindable IsConnected => isConnected; @@ -30,7 +30,7 @@ namespace osu.Game.Online private readonly IBindable apiState = new Bindable(); /// - /// Constructs a new . + /// Constructs a new . /// /// An API provider used to react to connection state changes. protected PersistentEndpointClientConnector(IAPIProvider api) @@ -123,6 +123,10 @@ namespace osu.Game.Online await Task.Delay(5000, cancellationToken).ConfigureAwait(false); } + /// + /// Creates a new . + /// + /// A cancellation token to stop the process. protected abstract Task BuildConnectionAsync(CancellationToken cancellationToken); private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken) From 99ba7c29dd99c92bd29396e276558206bc62076b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:46:50 +0900 Subject: [PATCH 091/261] Change range to 0-100% and rename to "normalisation" --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Settings/Sections/Gameplay/BeatmapSettings.cs | 8 ++++---- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 6 ++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 0d56ab8962..98776c7487 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,7 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.LastProcessedMetadataId, -1); - SetDefault(OsuSetting.ComboColourBrightness, 0f, -1f, 1f, 1f); + SetDefault(OsuSetting.ComboColourNormalisation, 0.2f, 0f, 1f, 0.01f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -367,6 +367,6 @@ namespace osu.Game.Configuration ShowOnlineExplicitContent, LastProcessedMetadataId, SafeAreaConsiderations, - ComboColourBrightness, + ComboColourNormalisation, } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 8bfa3e502c..ab9be70a5b 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -16,12 +16,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; - private readonly BindableFloat comboColourBrightness = new BindableFloat(); + private readonly BindableFloat comboColourNormalisation = new BindableFloat(); [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); + config.BindWith(OsuSetting.ComboColourNormalisation, comboColourNormalisation); Children = new Drawable[] { @@ -47,8 +47,8 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsSlider { - LabelText = "Combo colour brightness", - Current = comboColourBrightness, + LabelText = "Combo colour normalisation", + Current = comboColourNormalisation, DisplayAsPercentage = true, } }; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 077606cb3a..98fd73c8e9 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); + config.BindWith(OsuSetting.ComboColourNormalisation, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); @@ -524,9 +524,7 @@ namespace osu.Game.Rulesets.Objects.Drawables // Normalise the combo colour to the given brightness level. if (comboColourBrightness.Value != 0) { - float pAdjust = 0.6f + 0.4f * comboColourBrightness.Value; - - colour = Interpolation.ValueAt(Math.Abs(comboColourBrightness.Value), colour, new HSPAColour(colour) { P = pAdjust }.ToColor4(), 0, 1, Easing.Out); + colour = Interpolation.ValueAt(Math.Abs(comboColourBrightness.Value), colour, new HSPAColour(colour) { P = 0.6f }.ToColor4(), 0, 1); } AccentColour.Value = colour; From d8aa06ea92fa5a73c23b9305838efbd486aaaa55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:55:01 +0900 Subject: [PATCH 092/261] Standardise "Visual Settings" components to fix mismatched paddings and labels --- .../Play/PlayerSettings/PlayerCheckbox.cs | 21 ++++++++++++------- .../Play/PlayerSettings/VisualSettings.cs | 16 ++------------ 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs index dc09676254..cea03d2155 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs @@ -1,22 +1,27 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerCheckbox : OsuCheckbox + public class PlayerCheckbox : SettingsCheckbox { - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override Drawable CreateControl() => new PlayerCheckboxControl(); + + public class PlayerCheckboxControl : OsuCheckbox { - Nub.AccentColour = colours.Yellow; - Nub.GlowingAccentColour = colours.YellowLighter; - Nub.GlowColour = colours.YellowDark; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Nub.AccentColour = colours.Yellow; + Nub.GlowingAccentColour = colours.YellowLighter; + Nub.GlowColour = colours.YellowDark; + } } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index e55af0bba7..72a57f658c 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; @@ -24,26 +22,16 @@ namespace osu.Game.Screens.Play.PlayerSettings { Children = new Drawable[] { - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundDim - }, dimSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundDim, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundBlur - }, blurSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundBlur, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = "Toggles:" - }, showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins }, beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, From 61fc3c8cc0878dab7cea7a4dbc7d0bb26e6e6fab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:48:03 +0900 Subject: [PATCH 093/261] Add setting to visual settings toolbox --- osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 72a57f658c..10d132fc4d 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; -using osu.Game.Graphics.Sprites; using osu.Game.Localisation; namespace osu.Game.Screens.Play.PlayerSettings @@ -13,6 +12,7 @@ namespace osu.Game.Screens.Play.PlayerSettings { private readonly PlayerSliderBar dimSliderBar; private readonly PlayerSliderBar blurSliderBar; + private readonly PlayerSliderBar comboColourNormalisationSliderBar; private readonly PlayerCheckbox showStoryboardToggle; private readonly PlayerCheckbox beatmapSkinsToggle; private readonly PlayerCheckbox beatmapColorsToggle; @@ -35,6 +35,11 @@ namespace osu.Game.Screens.Play.PlayerSettings showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins }, beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, + comboColourNormalisationSliderBar = new PlayerSliderBar + { + LabelText = "Combo colour normalisation", + DisplayAsPercentage = true, + }, }; } @@ -46,6 +51,7 @@ namespace osu.Game.Screens.Play.PlayerSettings showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); beatmapColorsToggle.Current = config.GetBindable(OsuSetting.BeatmapColours); + comboColourNormalisationSliderBar.Current = config.GetBindable(OsuSetting.ComboColourNormalisation); } } } From 50b6fe4acb24e5fa9794d9653489c84d78989d12 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 14:01:03 +0900 Subject: [PATCH 094/261] Localise new label --- osu.Game/Localisation/GraphicsSettingsStrings.cs | 5 +++++ .../Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs | 2 +- osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index 2ab9d9de87..6e05929d81 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -99,6 +99,11 @@ namespace osu.Game.Localisation /// public static LocalisableString StoryboardVideo => new TranslatableString(getKey(@"storyboard_video"), @"Storyboard / video"); + /// + /// "Combo colour normalisation" + /// + public static LocalisableString ComboColourNormalisation => new TranslatableString(getKey(@"combo_colour_normalisation"), @"Combo colour normalisation"); + /// /// "Hit lighting" /// diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index ab9be70a5b..8d64337eab 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsSlider { - LabelText = "Combo colour normalisation", + LabelText = GraphicsSettingsStrings.ComboColourNormalisation, Current = comboColourNormalisation, DisplayAsPercentage = true, } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 10d132fc4d..c837f61a09 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Play.PlayerSettings beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, comboColourNormalisationSliderBar = new PlayerSliderBar { - LabelText = "Combo colour normalisation", + LabelText = GraphicsSettingsStrings.ComboColourNormalisation, DisplayAsPercentage = true, }, }; From 37300ba9e25ae1d2e3f6e9dd747d27b5fa4d18c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:55:01 +0900 Subject: [PATCH 095/261] Standardise "Visual Settings" components to fix mismatched paddings and labels --- .../Play/PlayerSettings/PlayerCheckbox.cs | 21 ++++++++++++------- .../Play/PlayerSettings/VisualSettings.cs | 17 ++------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs index dc09676254..cea03d2155 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs @@ -1,22 +1,27 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerCheckbox : OsuCheckbox + public class PlayerCheckbox : SettingsCheckbox { - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override Drawable CreateControl() => new PlayerCheckboxControl(); + + public class PlayerCheckboxControl : OsuCheckbox { - Nub.AccentColour = colours.Yellow; - Nub.GlowingAccentColour = colours.YellowLighter; - Nub.GlowColour = colours.YellowDark; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Nub.AccentColour = colours.Yellow; + Nub.GlowingAccentColour = colours.YellowLighter; + Nub.GlowColour = colours.YellowDark; + } } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index e55af0bba7..bb3360acec 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; -using osu.Game.Graphics.Sprites; using osu.Game.Localisation; namespace osu.Game.Screens.Play.PlayerSettings @@ -24,26 +21,16 @@ namespace osu.Game.Screens.Play.PlayerSettings { Children = new Drawable[] { - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundDim - }, dimSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundDim, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundBlur - }, blurSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundBlur, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = "Toggles:" - }, showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins }, beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, From e761c0395d411aadc40e565f8deeff43c641c4a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 14:47:56 +0900 Subject: [PATCH 096/261] Fix multiple notifications arriving for imports in edge cases --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 4cf47013bd..7b62c95179 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Notifications } } - private bool completionSent; + private int completionSent; /// /// Attempt to post a completion notification. @@ -162,11 +162,11 @@ namespace osu.Game.Overlays.Notifications if (CompletionTarget == null) return; - if (completionSent) + // Thread-safe barrier, as this may be called by a web request and also scheduled to the update thread at the same time. + if (Interlocked.Increment(ref completionSent) == 0) return; CompletionTarget.Invoke(CreateCompletionNotification()); - completionSent = true; Close(false); } From df1f7e2b13192efc811594d8bbfbf6b2eaab607f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 15:09:40 +0900 Subject: [PATCH 097/261] remove `#nullable disable` --- osu.Game/Graphics/Containers/UserDimContainer.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 296855522b..a6a8f341b6 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -46,13 +44,13 @@ namespace osu.Game.Graphics.Containers /// public bool ContentDisplayed { get; private set; } - protected Bindable UserDimLevel { get; private set; } + protected Bindable UserDimLevel { get; private set; } = null!; public Bindable DimAmount { get; set; } = new Bindable(); - protected Bindable LightenDuringBreaks { get; private set; } + protected Bindable LightenDuringBreaks { get; private set; } = null!; - protected Bindable ShowStoryboard { get; private set; } + protected Bindable ShowStoryboard { get; private set; } = null!; private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; From d6b8439121ce20ec11c8ad2bfae9892394ba9523 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 15:11:49 +0900 Subject: [PATCH 098/261] add xmldoc for DimAmount --- osu.Game/Graphics/Containers/UserDimContainer.cs | 3 +++ osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index a6a8f341b6..62dd4e19b0 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -46,6 +46,9 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } = null!; + /// + /// The amount of dim to be override if is true. + /// public Bindable DimAmount { get; set; } = new Bindable(); protected Bindable LightenDuringBreaks { get; private set; } = null!; diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 053bcf2387..9f3e99d793 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -43,6 +43,9 @@ namespace osu.Game.Screens.Backgrounds /// public readonly Bindable BlurAmount = new BindableFloat(); + /// + /// The amount of dim to be override if is true. + /// public readonly Bindable DimAmount = new Bindable(); internal readonly IBindable IsBreakTime = new Bindable(); From 98846182909f5be197ce44c413ccdc05cfa79e48 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 15:12:15 +0900 Subject: [PATCH 099/261] rename `editorDim` to `editorBackgroundDim` --- osu.Game/Screens/Edit/Editor.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3c91d302ae..04fa96171d 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -175,7 +175,7 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - private Bindable editorDim; + private Bindable editorBackgroundDim; public Editor(EditorLoader loader = null) { @@ -261,7 +261,7 @@ namespace osu.Game.Screens.Edit OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; - editorDim = config.GetBindable(OsuSetting.EditorDim); + editorBackgroundDim = config.GetBindable(OsuSetting.EditorDim); AddInternal(new OsuContextMenuContainer { @@ -314,7 +314,7 @@ namespace osu.Game.Screens.Edit Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), - new BackgroundDimMenuItem(editorDim), + new BackgroundDimMenuItem(editorBackgroundDim), } } } @@ -335,7 +335,7 @@ namespace osu.Game.Screens.Edit changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); - editorDim.BindValueChanged(_ => dimBackground()); + editorBackgroundDim.BindValueChanged(_ => dimBackground()); } [Resolved] @@ -632,7 +632,7 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { b.IgnoreUserSettings.Value = true; - b.DimAmount.Value = editorDim.Value; + b.DimAmount.Value = editorBackgroundDim.Value; b.BlurAmount.Value = 0; }); } From e5f53b1ad8346c3d0e9241bfd79138df2aae3121 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:18:47 +0900 Subject: [PATCH 100/261] Use Interlocked.Exhange() instead Increment isn't correct since it returns the post-incremented value. It also always increments. --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 7b62c95179..54a1d69a9e 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Notifications return; // Thread-safe barrier, as this may be called by a web request and also scheduled to the update thread at the same time. - if (Interlocked.Increment(ref completionSent) == 0) + if (Interlocked.Exchange(ref completionSent, 1) == 0) return; CompletionTarget.Invoke(CreateCompletionNotification()); From fe66b207020fb816b1395fc50d507717ef8bcf16 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:22:46 +0900 Subject: [PATCH 101/261] Fix one more case of constructing connector directly --- osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 99cd9beecf..04dfe5f7c2 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -49,7 +49,7 @@ namespace osu.Game.Tournament.Components if (manager == null) { - AddInternal(manager = new ChannelManager(api, new WebSocketNotificationsClientConnector(api))); + AddInternal(manager = new ChannelManager(api, api.GetNotificationsConnector())); Channel.BindTo(manager.CurrentChannel); } From 58c6b026ae503097b86f8c8f139912042fa3360a Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:23:11 +0900 Subject: [PATCH 102/261] Remove unused using --- osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 04dfe5f7c2..48ff45974d 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications.WebSocket; using osu.Game.Overlays.Chat; using osu.Game.Tournament.IPC; using osu.Game.Tournament.Models; From db34f238c09597748ff5c9e6c22211d8b8346641 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:47:30 +0900 Subject: [PATCH 103/261] Fix inverted condition --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 54a1d69a9e..9812feb4a1 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Notifications return; // Thread-safe barrier, as this may be called by a web request and also scheduled to the update thread at the same time. - if (Interlocked.Exchange(ref completionSent, 1) == 0) + if (Interlocked.Exchange(ref completionSent, 1) == 1) return; CompletionTarget.Invoke(CreateCompletionNotification()); From c66064872a18d1bd75cdcdde80fa4242f5054978 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 15:45:23 +0900 Subject: [PATCH 104/261] Fix `DrawableHit` test scene not showing rim hits correctly --- .../Skinning/TestSceneDrawableHit.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index 8e9c487c2f..eb2b6c1d74 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -30,23 +30,24 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning Origin = Anchor.Centre, })); - AddStep("Rim hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime()) + AddStep("Rim hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(rim: true)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, })); - AddStep("Rim hit (strong)", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(true)) + AddStep("Rim hit (strong)", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(true, true)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, })); } - private Hit createHitAtCurrentTime(bool strong = false) + private Hit createHitAtCurrentTime(bool strong = false, bool rim = false) { var hit = new Hit { + Type = rim ? HitType.Rim : HitType.Centre, IsStrong = strong, StartTime = Time.Current + 3000, }; From 0689d3845ff82fcae11f5e35e65f72b0e1e6be7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 16:55:17 +0900 Subject: [PATCH 105/261] Fix `TestSceneHitExplosion` not maintaining aspect ratio --- .../Skinning/TestSceneHitExplosion.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs index f87e0355ad..0ddc607336 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; +using osu.Game.Screens.Ranking; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { @@ -49,11 +50,19 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning // the hit needs to be added to hierarchy in order for nested objects to be created correctly. // setting zero alpha is supposed to prevent the test from looking broken. hit.With(h => h.Alpha = 0), - new HitExplosion(hit.Type) + + new AspectContainer { + RelativeSizeAxes = Axes.X, Anchor = Anchor.Centre, Origin = Anchor.Centre, - }.With(explosion => explosion.Apply(hit)) + Child = + new HitExplosion(hit.Type) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }.With(explosion => explosion.Apply(hit)) + } } }; } From 9c758e542505adc7e64049993d843e359c0c0410 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:00:39 +0900 Subject: [PATCH 106/261] Move `DefaultInputDrum` to correct location --- .../Skinning/Default/DefaultInputDrum.cs | 181 ++++++++++++++++++ osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 172 +---------------- 2 files changed, 182 insertions(+), 171 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs new file mode 100644 index 0000000000..fa60d209e7 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs @@ -0,0 +1,181 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Screens.Ranking; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Default +{ + public class DefaultInputDrum : AspectContainer + { + public DefaultInputDrum() + { + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + const float middle_split = 0.025f; + + InternalChild = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.9f), + Children = new[] + { + new TaikoHalfDrum(false) + { + Name = "Left Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = -middle_split / 2, + RimAction = TaikoAction.LeftRim, + CentreAction = TaikoAction.LeftCentre + }, + new TaikoHalfDrum(true) + { + Name = "Right Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = middle_split / 2, + RimAction = TaikoAction.RightRim, + CentreAction = TaikoAction.RightCentre + } + } + }; + } + + /// + /// A half-drum. Contains one centre and one rim hit. + /// + private class TaikoHalfDrum : Container, IKeyBindingHandler + { + /// + /// The key to be used for the rim of the half-drum. + /// + public TaikoAction RimAction; + + /// + /// The key to be used for the centre of the half-drum. + /// + public TaikoAction CentreAction; + + private readonly Sprite rim; + private readonly Sprite rimHit; + private readonly Sprite centre; + private readonly Sprite centreHit; + + public TaikoHalfDrum(bool flipped) + { + Masking = true; + + Children = new Drawable[] + { + rim = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + }, + rimHit = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Blending = BlendingParameters.Additive, + }, + centre = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.7f) + }, + centreHit = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.7f), + Alpha = 0, + Blending = BlendingParameters.Additive + } + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures, OsuColour colours) + { + rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer"); + rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit"); + centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner"); + centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit"); + + rimHit.Colour = colours.Blue; + centreHit.Colour = colours.Pink; + } + + public bool OnPressed(KeyBindingPressEvent e) + { + Drawable target = null; + Drawable back = null; + + if (e.Action == CentreAction) + { + target = centreHit; + back = centre; + } + else if (e.Action == RimAction) + { + target = rimHit; + back = rim; + } + + if (target != null) + { + const float scale_amount = 0.05f; + const float alpha_amount = 0.5f; + + const float down_time = 40; + const float up_time = 1000; + + back.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint) + .Then() + .ScaleTo(1, up_time, Easing.OutQuint); + + target.Animate( + t => t.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint), + t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint) + ).Then( + t => t.ScaleTo(1, up_time, Easing.OutQuint), + t => t.FadeOut(up_time, Easing.OutQuint) + ); + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 054f98e18f..94e7138142 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -3,18 +3,11 @@ #nullable disable -using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Bindings; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Screens.Ranking; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; -using osuTK; namespace osu.Game.Rulesets.Taiko.UI { @@ -23,8 +16,6 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class InputDrum : Container { - private const float middle_split = 0.025f; - public InputDrum() { AutoSizeAxes = Axes.X; @@ -43,166 +34,5 @@ namespace osu.Game.Rulesets.Taiko.UI }, }; } - - private class DefaultInputDrum : AspectContainer - { - public DefaultInputDrum() - { - RelativeSizeAxes = Axes.Y; - } - - [BackgroundDependencyLoader] - private void load() - { - InternalChild = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.9f), - Children = new[] - { - new TaikoHalfDrum(false) - { - Name = "Left Half", - Anchor = Anchor.Centre, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = -middle_split / 2, - RimAction = TaikoAction.LeftRim, - CentreAction = TaikoAction.LeftCentre - }, - new TaikoHalfDrum(true) - { - Name = "Right Half", - Anchor = Anchor.Centre, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = middle_split / 2, - RimAction = TaikoAction.RightRim, - CentreAction = TaikoAction.RightCentre - } - } - }; - } - - /// - /// A half-drum. Contains one centre and one rim hit. - /// - private class TaikoHalfDrum : Container, IKeyBindingHandler - { - /// - /// The key to be used for the rim of the half-drum. - /// - public TaikoAction RimAction; - - /// - /// The key to be used for the centre of the half-drum. - /// - public TaikoAction CentreAction; - - private readonly Sprite rim; - private readonly Sprite rimHit; - private readonly Sprite centre; - private readonly Sprite centreHit; - - public TaikoHalfDrum(bool flipped) - { - Masking = true; - - Children = new Drawable[] - { - rim = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both - }, - rimHit = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Alpha = 0, - Blending = BlendingParameters.Additive, - }, - centre = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.7f) - }, - centreHit = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.7f), - Alpha = 0, - Blending = BlendingParameters.Additive - } - }; - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures, OsuColour colours) - { - rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer"); - rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit"); - centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner"); - centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit"); - - rimHit.Colour = colours.Blue; - centreHit.Colour = colours.Pink; - } - - public bool OnPressed(KeyBindingPressEvent e) - { - Drawable target = null; - Drawable back = null; - - if (e.Action == CentreAction) - { - target = centreHit; - back = centre; - } - else if (e.Action == RimAction) - { - target = rimHit; - back = rim; - } - - if (target != null) - { - const float scale_amount = 0.05f; - const float alpha_amount = 0.5f; - - const float down_time = 40; - const float up_time = 1000; - - back.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint) - .Then() - .ScaleTo(1, up_time, Easing.OutQuint); - - target.Animate( - t => t.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint), - t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint) - ).Then( - t => t.ScaleTo(1, up_time, Easing.OutQuint), - t => t.FadeOut(up_time, Easing.OutQuint) - ); - } - - return false; - } - - public void OnReleased(KeyBindingReleaseEvent e) - { - } - } - } } } From 2407eb063d4850f23d29b9fa9364722a7a84e744 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 16:51:55 +0900 Subject: [PATCH 107/261] Simplify `Circle` usage in default `CentreHitCirclePiece` --- .../Skinning/Default/CentreHitCirclePiece.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs index b91d5cfe8d..958f4b3a17 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs @@ -41,12 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default Children = new[] { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] { new Box { RelativeSizeAxes = Axes.Both } } - } + new Circle { RelativeSizeAxes = Axes.Both } }; } } From 910dd3ad01ed44be94c0bc5503134b214e19bc08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:04:45 +0900 Subject: [PATCH 108/261] Move more default classes to correct namespace --- .../Default}/DefaultHitExplosion.cs | 14 ++++++-------- .../Default}/DefaultKiaiHitExplosion.cs | 6 ++---- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 1 + osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 1 + 4 files changed, 10 insertions(+), 12 deletions(-) rename osu.Game.Rulesets.Taiko/{UI => Skinning/Default}/DefaultHitExplosion.cs (87%) rename osu.Game.Rulesets.Taiko/{UI => Skinning/Default}/DefaultKiaiHitExplosion.cs (96%) diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs similarity index 87% rename from osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs rename to osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index 687c8f788f..58f45fda7c 100644 --- a/osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -1,9 +1,7 @@ +#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,19 +10,19 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.UI; using osuTK.Graphics; -namespace osu.Game.Rulesets.Taiko.UI +namespace osu.Game.Rulesets.Taiko.Skinning.Default { internal class DefaultHitExplosion : CircularContainer, IAnimatableHitExplosion { private readonly HitResult result; - [CanBeNull] - private Box body; + private Box? body; [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; public DefaultHitExplosion(HitResult result) { @@ -58,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.UI updateColour(); } - private void updateColour([CanBeNull] DrawableHitObject judgedObject = null) + private void updateColour(DrawableHitObject? judgedObject = null) { if (body == null) return; diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs similarity index 96% rename from osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs rename to osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs index e91475d87b..ae68d63d97 100644 --- a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,8 +8,9 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Objects; +using osuTK; -namespace osu.Game.Rulesets.Taiko.UI +namespace osu.Game.Rulesets.Taiko.Skinning.Default { public class DefaultKiaiHitExplosion : CircularContainer { diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 046b3a6fd0..d8cdf50d75 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.UI diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index 319d8979ae..36d2e32984 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; using osuTK; From bc3382f373c83091d316b73c45cc9919952c68e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:07:19 +0900 Subject: [PATCH 109/261] Apply NRT to many taiko classes --- .../Skinning/Default/ElongatedCirclePiece.cs | 2 -- .../Skinning/Default/RimHitCirclePiece.cs | 2 -- .../Skinning/Default/SwellSymbolPiece.cs | 2 -- .../Skinning/Default/TickPiece.cs | 2 -- .../Skinning/Legacy/LegacyBarLine.cs | 2 -- .../Skinning/Legacy/LegacyCirclePiece.cs | 6 ++---- .../Skinning/Legacy/LegacyDrumRoll.cs | 8 +++----- .../Skinning/Legacy/LegacyHit.cs | 2 -- .../Skinning/Legacy/LegacyHitExplosion.cs | 9 +++------ .../Skinning/Legacy/LegacyInputDrum.cs | 10 ++++------ .../Skinning/Legacy/LegacyTaikoScroller.cs | 8 +++----- .../Skinning/Legacy/TaikoLegacyHitTarget.cs | 4 +--- .../Legacy/TaikoLegacyPlayfieldBackgroundRight.cs | 4 +--- osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs | 2 -- osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs | 2 -- osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs | 2 -- .../UI/DrawableTaikoJudgement.cs | 2 -- osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs | 7 +++---- osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs | 2 -- .../UI/DrumSampleTriggerSource.cs | 2 -- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 13 +++++-------- osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs | 2 -- .../UI/IAnimatableHitExplosion.cs | 2 -- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 -- osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 4 +--- .../UI/PlayfieldBackgroundLeft.cs | 2 -- .../UI/PlayfieldBackgroundRight.cs | 2 -- osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs | 2 -- osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs | 6 ++---- .../UI/TaikoMascotAnimationState.cs | 2 -- .../UI/TaikoPlayfieldAdjustmentContainer.cs | 2 -- osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs | 2 -- 32 files changed, 28 insertions(+), 93 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs index ba2679fe97..210841bca0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs index 63269f1267..c6165495d8 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs index d19dc4c887..2f59cac3ff 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs index 7d3268f777..09c8243aac 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs index 97e0a340dd..2b528ae8ce 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index 6bbeb0ed4c..6b2576a564 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { public class LegacyCirclePiece : CompositeDrawable, IHasAccentColour { - private Drawable backgroundLayer; + private Drawable backgroundLayer = null!; // required for editor blueprints (not sure why these circle pieces are zero size). public override Quad ScreenSpaceDrawQuad => backgroundLayer.ScreenSpaceDrawQuad; @@ -32,7 +30,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy [BackgroundDependencyLoader] private void load(ISkinSource skin, DrawableHitObject drawableHitObject) { - Drawable getDrawableFor(string lookup) + Drawable? getDrawableFor(string lookup) { const string normal_hit = "taikohit"; const string big_hit = "taikobig"; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs index 040d8ff965..1249231d92 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -28,11 +26,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } } - private LegacyCirclePiece headCircle; + private LegacyCirclePiece headCircle = null!; - private Sprite body; + private Sprite body = null!; - private Sprite tailCircle; + private Sprite tailCircle = null!; public LegacyDrumRoll() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs index b4277f86bb..d93317f0e2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Skinning; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs index 87ed2e2e60..ea45b69999 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,9 +1,7 @@ +#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -17,8 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { private readonly Drawable sprite; - [CanBeNull] - private readonly Drawable strongSprite; + private readonly Drawable? strongSprite; /// /// Creates a new legacy hit explosion. @@ -29,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy /// /// The normal legacy explosion sprite. /// The strong legacy explosion sprite. - public LegacyHitExplosion(Drawable sprite, [CanBeNull] Drawable strongSprite = null) + public LegacyHitExplosion(Drawable sprite, Drawable? strongSprite = null) { this.sprite = sprite; this.strongSprite = strongSprite; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs index 101f70b97a..0abb365750 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -20,9 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy /// internal class LegacyInputDrum : Container { - private Container content; - private LegacyHalfDrum left; - private LegacyHalfDrum right; + private Container content = null!; + private LegacyHalfDrum left = null!; + private LegacyHalfDrum right = null!; public LegacyInputDrum() { @@ -142,7 +140,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy public bool OnPressed(KeyBindingPressEvent e) { - Drawable target = null; + Drawable? target = null; if (e.Action == CentreAction) { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs index bd4a2f8935..4a2426bff5 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } [BackgroundDependencyLoader(true)] - private void load(GameplayState gameplayState) + private void load(GameplayState? gameplayState) { if (gameplayState != null) ((IBindable)LastResult).BindTo(gameplayState.LastJudgementResult); @@ -91,8 +89,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy private class ScrollerSprite : CompositeDrawable { - private Sprite passingSprite; - private Sprite failingSprite; + private Sprite passingSprite = null!; + private Sprite failingSprite = null!; private bool passing = true; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs index a48cdf47f6..21102f6eec 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { public class TaikoLegacyHitTarget : CompositeDrawable { - private Container content; + private Container content = null!; [BackgroundDependencyLoader] private void load(ISkinSource skin) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs index f425a410a4..3186f615a7 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; @@ -16,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { public class TaikoLegacyPlayfieldBackgroundRight : BeatSyncedContainer { - private Sprite kiai; + private Sprite kiai = null!; private bool kiaiDisplayed; diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs index 63314a6822..30bfb605aa 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs index d231dc7e4f..bf48898dd2 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Taiko { public enum TaikoSkinComponents diff --git a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs index 071808a044..cb878e8ea0 100644 --- a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index 264e4db54e..876fa207bf 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs index 8bedca19d8..dd0b61cdf5 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Track; @@ -24,7 +22,8 @@ namespace osu.Game.Rulesets.Taiko.UI public readonly Bindable LastResult; private readonly Dictionary animations; - private TaikoMascotAnimation currentAnimation; + + private TaikoMascotAnimation? currentAnimation; private bool lastObjectHit = true; private bool kiaiMode; @@ -40,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.UI } [BackgroundDependencyLoader(true)] - private void load(GameplayState gameplayState) + private void load(GameplayState? gameplayState) { InternalChildren = new[] { diff --git a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs index e0d5a3c680..ae37840825 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; diff --git a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs index ef5bd1d7f0..3279d128d3 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Audio; using osu.Game.Rulesets.Taiko.Objects; diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index d8cdf50d75..4836984eac 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -1,10 +1,8 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +#nullable enable +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -30,10 +28,9 @@ namespace osu.Game.Rulesets.Taiko.UI private double? secondHitTime; - [CanBeNull] - public DrawableHitObject JudgedObject; + public DrawableHitObject? JudgedObject; - private SkinnableDrawable skinnable; + private SkinnableDrawable skinnable = null!; /// /// This constructor only exists to meet the new() type constraint of . @@ -63,7 +60,7 @@ namespace osu.Game.Rulesets.Taiko.UI skinnable.OnSkinChanged += runAnimation; } - public void Apply([CanBeNull] DrawableHitObject drawableHitObject) + public void Apply(DrawableHitObject? drawableHitObject) { JudgedObject = drawableHitObject; secondHitTime = null; diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs index 8707f7e840..badf34554c 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Pooling; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs index 6a9d43a0ab..cf0f5f9fb6 100644 --- a/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 94e7138142..6d5b6c5f5d 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index 36d2e32984..c4cff00d2a 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly HitType hitType; - private SkinnableDrawable skinnable; + private SkinnableDrawable skinnable = null!; public override double LifetimeStart => skinnable.Drawable.LifetimeStart; diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs index db1094e100..2a8890a95d 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs +++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs index 43252e2e77..44bfdacf37 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs index f48ed2c941..6401c6d09f 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs index 26a37fc464..de539b3cf0 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; @@ -120,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(ISkinSource source) { - ISkin skin = source.FindProvider(s => getAnimationFrame(s, TaikoMascotAnimationState.Clear, 0) != null); + ISkin? skin = source.FindProvider(s => getAnimationFrame(s, TaikoMascotAnimationState.Clear, 0) != null); if (skin == null) return; @@ -137,7 +135,7 @@ namespace osu.Game.Rulesets.Taiko.UI } } - private static Texture getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex) + private static Texture? getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex) { var texture = skin.GetTexture($"pippidon{state.ToString().ToLowerInvariant()}{frameIndex}"); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs index 717f0d725a..02bf245b7b 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Taiko.UI { public enum TaikoMascotAnimationState diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 8e99a82b1b..9cf530e903 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs index a76adc495d..e6391d1386 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Taiko.Replays; From 5dfaf277229566c930d0cbedc9d970d0c2b3c507 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 17:23:45 +0900 Subject: [PATCH 110/261] A bit more cleanup --- osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs | 1 - osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs index ea45b69999..ff1546381b 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,4 +1,3 @@ -#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 4836984eac..10a7495c62 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -1,5 +1,4 @@ -#nullable enable -// 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 System; From bfa5d41d89a64ec1a559cc4d5cc5975563d95335 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:39:45 +0900 Subject: [PATCH 111/261] Fix one more case --- osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index 58f45fda7c..b7ba76effa 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -1,4 +1,3 @@ -#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. From 4f8e912f063b08ed8be5afb2a513d8c804092685 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:53:19 +0900 Subject: [PATCH 112/261] Fix `APINotification` parsing failing --- osu.Game/Online/API/Requests/Responses/APINotification.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APINotification.cs b/osu.Game/Online/API/Requests/Responses/APINotification.cs index 2d9122c04b..de856c0333 100644 --- a/osu.Game/Online/API/Requests/Responses/APINotification.cs +++ b/osu.Game/Online/API/Requests/Responses/APINotification.cs @@ -2,8 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace osu.Game.Online.API.Requests.Responses { @@ -32,6 +32,6 @@ namespace osu.Game.Online.API.Requests.Responses public bool IsRead { get; set; } [JsonProperty(@"details")] - public Dictionary? Details { get; set; } + public JObject? Details { get; set; } } } From 0e502de8b473d9dda312bd4ddb590c7ce8dde1a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:49:52 +0900 Subject: [PATCH 113/261] Rename field to match usage --- .../Visual/Editing/TestSceneEditorTestGameplay.cs | 4 ++-- osu.Game/Graphics/Containers/UserDimContainer.cs | 8 ++++---- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 6 +++--- osu.Game/Screens/Edit/Editor.cs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index 9722c60cba..981967e413 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; + return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); } @@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; + return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddStep("start track", () => EditorClock.Start()); diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 62dd4e19b0..0b20159190 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -47,9 +47,9 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } = null!; /// - /// The amount of dim to be override if is true. + /// The amount of dim to be used when is true. /// - public Bindable DimAmount { get; set; } = new Bindable(); + public Bindable DimWhenUserSettingsIgnored { get; set; } = new Bindable(); protected Bindable LightenDuringBreaks { get; private set; } = null!; @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Containers private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; - protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : DimAmount.Value, 0); + protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : DimWhenUserSettingsIgnored.Value, 0); protected override Container Content => dimContent; @@ -79,7 +79,7 @@ namespace osu.Game.Graphics.Containers ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); UserDimLevel.ValueChanged += _ => UpdateVisuals(); - DimAmount.ValueChanged += _ => UpdateVisuals(); + DimWhenUserSettingsIgnored.ValueChanged += _ => UpdateVisuals(); LightenDuringBreaks.ValueChanged += _ => UpdateVisuals(); IsBreakTime.ValueChanged += _ => UpdateVisuals(); ShowStoryboard.ValueChanged += _ => UpdateVisuals(); diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 9f3e99d793..4d84a8194d 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -44,9 +44,9 @@ namespace osu.Game.Screens.Backgrounds public readonly Bindable BlurAmount = new BindableFloat(); /// - /// The amount of dim to be override if is true. + /// The amount of dim to be used when is true. /// - public readonly Bindable DimAmount = new Bindable(); + public readonly Bindable DimWhenUserSettingsIgnored = new Bindable(); internal readonly IBindable IsBreakTime = new Bindable(); @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Backgrounds dimmable.IgnoreUserSettings.BindTo(IgnoreUserSettings); dimmable.IsBreakTime.BindTo(IsBreakTime); dimmable.BlurAmount.BindTo(BlurAmount); - dimmable.DimAmount.BindTo(DimAmount); + dimmable.DimWhenUserSettingsIgnored.BindTo(DimWhenUserSettingsIgnored); StoryboardReplacesBackground.BindTo(dimmable.StoryboardReplacesBackground); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index bd0c4cfca4..990152471a 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -637,7 +637,7 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { b.IgnoreUserSettings.Value = true; - b.DimAmount.Value = editorBackgroundDim.Value; + b.DimWhenUserSettingsIgnored.Value = editorBackgroundDim.Value; b.BlurAmount.Value = 0; }); } @@ -668,7 +668,7 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { //b.DimAmount.UnbindAll(); - b.DimAmount.Value = 0; + b.DimWhenUserSettingsIgnored.Value = 0; }); resetTrack(); From 3ec9686e5858ad02070e3358eb971e62c449987b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 18:14:20 +0900 Subject: [PATCH 114/261] Fix test failures and rename configuration value to match better --- .../TestSceneLegacyBeatmapSkin.cs | 2 ++ .../Gameplay/TestSceneHitObjectAccentColour.cs | 14 +++++++++++++- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Settings/Sections/Gameplay/BeatmapSettings.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 2 +- .../Screens/Play/PlayerSettings/VisualSettings.cs | 2 +- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 1767d25e77..bb28b2b217 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -31,6 +31,8 @@ namespace osu.Game.Rulesets.Osu.Tests { config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins); config.BindWith(OsuSetting.BeatmapColours, BeatmapColours); + + config.SetValue(OsuSetting.ComboColourNormalisationAmount, 0f); } [TestCase(true, true)] diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 9701a32951..bc4c1d4cf2 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Testing; using osu.Game.Audio; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; @@ -25,10 +27,20 @@ namespace osu.Game.Tests.Gameplay [HeadlessTest] public class TestSceneHitObjectAccentColour : OsuTestScene { + [Resolved] + private OsuConfigManager config { get; set; } + private Container skinContainer; [SetUp] - public void Setup() => Schedule(() => Child = skinContainer = new SkinProvidingContainer(new TestSkin())); + public void Setup() + { + Schedule(() => + { + config.SetValue(OsuSetting.ComboColourNormalisationAmount, 0f); + Child = skinContainer = new SkinProvidingContainer(new TestSkin()); + }); + } [Test] public void TestChangeComboIndexBeforeLoad() diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 98776c7487..fdaad8cf70 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,7 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.LastProcessedMetadataId, -1); - SetDefault(OsuSetting.ComboColourNormalisation, 0.2f, 0f, 1f, 0.01f); + SetDefault(OsuSetting.ComboColourNormalisationAmount, 0.2f, 0f, 1f, 0.01f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -367,6 +367,6 @@ namespace osu.Game.Configuration ShowOnlineExplicitContent, LastProcessedMetadataId, SafeAreaConsiderations, - ComboColourNormalisation, + ComboColourNormalisationAmount, } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 8d64337eab..14ff6ac2b5 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.ComboColourNormalisation, comboColourNormalisation); + config.BindWith(OsuSetting.ComboColourNormalisationAmount, comboColourNormalisation); Children = new Drawable[] { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 98fd73c8e9..f82a24ff01 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.ComboColourNormalisation, comboColourBrightness); + config.BindWith(OsuSetting.ComboColourNormalisationAmount, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index c837f61a09..6a7eabc6a2 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play.PlayerSettings showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); beatmapColorsToggle.Current = config.GetBindable(OsuSetting.BeatmapColours); - comboColourNormalisationSliderBar.Current = config.GetBindable(OsuSetting.ComboColourNormalisation); + comboColourNormalisationSliderBar.Current = config.GetBindable(OsuSetting.ComboColourNormalisationAmount); } } } From a44c7c751497d72eb33e4106a0b7baac184254a4 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 19:56:35 +0900 Subject: [PATCH 115/261] range and precision for `EditorWaveformOpacity` --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index e9cfcd56c5..b832d1e310 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -172,7 +172,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); - SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); + SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); } From 7073d8dd8e9f75f4756adf3fef7a9c6035db911c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 19:57:01 +0900 Subject: [PATCH 116/261] range and precision for `EditorDim` --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b832d1e310..3c619d2ddd 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -121,7 +121,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); - SetDefault(OsuSetting.EditorDim, 0.25f); + SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); From 993439d30b173a5bdac0e22fea97c0e97bcb09a7 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 3 Nov 2022 11:28:39 +0900 Subject: [PATCH 117/261] Fix missed nullability --- osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs index de539b3cf0..0f214b8436 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(ISkinSource source) { - ISkin skin = source.FindProvider(s => getAnimationFrame(s, state, 0) != null); + ISkin? skin = source.FindProvider(s => getAnimationFrame(s, state, 0) != null); if (skin == null) return; From ec4ac77f14cbf6f85281c7e634a329efafa1b92a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 13:27:54 +0900 Subject: [PATCH 118/261] Increase the maximum seed range for tournament client --- osu.Game.Tournament/Models/SeedingBeatmap.cs | 2 +- osu.Game.Tournament/Models/SeedingResult.cs | 2 +- osu.Game.Tournament/Models/TournamentTeam.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tournament/Models/SeedingBeatmap.cs b/osu.Game.Tournament/Models/SeedingBeatmap.cs index fb0e20556c..0ac312342c 100644 --- a/osu.Game.Tournament/Models/SeedingBeatmap.cs +++ b/osu.Game.Tournament/Models/SeedingBeatmap.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tournament.Models public Bindable Seed = new BindableInt { MinValue = 1, - MaxValue = 64 + MaxValue = 256 }; } } diff --git a/osu.Game.Tournament/Models/SeedingResult.cs b/osu.Game.Tournament/Models/SeedingResult.cs index 71e52b3324..2a404153e6 100644 --- a/osu.Game.Tournament/Models/SeedingResult.cs +++ b/osu.Game.Tournament/Models/SeedingResult.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tournament.Models public Bindable Seed = new BindableInt { MinValue = 1, - MaxValue = 64 + MaxValue = 256 }; } } diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs index ac57f748da..1beea517d5 100644 --- a/osu.Game.Tournament/Models/TournamentTeam.cs +++ b/osu.Game.Tournament/Models/TournamentTeam.cs @@ -54,7 +54,7 @@ namespace osu.Game.Tournament.Models public Bindable LastYearPlacing = new BindableInt { MinValue = 1, - MaxValue = 64 + MaxValue = 256 }; [JsonProperty] From aef3c7918c98d3acd7cdb4bdba9e5bc0e9551054 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 12:14:37 +0900 Subject: [PATCH 119/261] Add total skip count to `SkipOverlay` --- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 7 +++++-- osu.Game/Screens/Play/SkipOverlay.cs | 11 ++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 6b02449aa3..4b564f704a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -137,8 +137,11 @@ namespace osu.Game.Tests.Visual.Gameplay checkRequestCount(0); } - private void checkRequestCount(int expected) => - AddAssert($"request count is {expected}", () => requestCount == expected); + private void checkRequestCount(int expected) + { + AddAssert($"skip count is {expected}", () => skip.SkipCount, () => Is.EqualTo(expected)); + AddAssert($"request count is {expected}", () => requestCount, () => Is.EqualTo(expected)); + } private class TestSkipOverlay : SkipOverlay { diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 974d40b538..ee05fce730 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -27,6 +27,11 @@ namespace osu.Game.Screens.Play { public class SkipOverlay : CompositeDrawable, IKeyBindingHandler { + /// + /// The total number of successful skips performed by this overlay. + /// + public int SkipCount { get; private set; } + private readonly double startTime; public Action RequestSkip; @@ -124,7 +129,11 @@ namespace osu.Game.Screens.Play return; } - button.Action = () => RequestSkip?.Invoke(); + button.Action = () => + { + SkipCount++; + RequestSkip?.Invoke(); + }; fadeContainer.TriggerShow(); From 5f2f6b84b2febc80fdc166c89011c7175bba3818 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 12:27:37 +0900 Subject: [PATCH 120/261] Add failing test coverage of automated skip scenarios --- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 4b564f704a..1bba62a5cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -93,6 +93,15 @@ namespace osu.Game.Tests.Visual.Gameplay checkRequestCount(1); } + [Test] + public void TestAutomaticSkipActuatesOnce() + { + createTest(); + AddStep("start automated skip", () => skip.SkipWhenReady()); + AddUntilStep("wait for button disabled", () => !skip.IsButtonVisible); + checkRequestCount(1); + } + [Test] public void TestClickOnlyActuatesOnce() { @@ -110,6 +119,16 @@ namespace osu.Game.Tests.Visual.Gameplay checkRequestCount(1); } + [Test] + public void TestAutomaticSkipActuatesMultipleTimes() + { + createTest(); + AddStep("set increment lower", () => increment = 3000); + AddStep("start automated skip", () => skip.SkipWhenReady()); + AddUntilStep("wait for button disabled", () => !skip.IsButtonVisible); + checkRequestCount(2); + } + [Test] public void TestClickOnlyActuatesMultipleTimes() { From 4154be6cdaccb5cf40f1a95b79d1ab226ddc5dd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 12:05:00 +0900 Subject: [PATCH 121/261] Adjust auto-skip to skip multiple times if necessary --- osu.Game/Screens/Play/SkipOverlay.cs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index ee05fce730..99fe659bf3 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -136,20 +136,29 @@ namespace osu.Game.Screens.Play }; fadeContainer.TriggerShow(); - - if (skipQueued) - { - Scheduler.AddDelayed(() => button.TriggerClick(), 200); - skipQueued = false; - } } + /// + /// Triggers an "automated" skip to happen as soon as available. + /// public void SkipWhenReady() { - if (IsLoaded) + if (skipQueued) return; + + skipQueued = true; + attemptNextSkip(); + + void attemptNextSkip() => Scheduler.AddDelayed(() => + { + if (!button.Enabled.Value) + { + skipQueued = false; + return; + } + button.TriggerClick(); - else - skipQueued = true; + attemptNextSkip(); + }, 200); } protected override void Update() From df9f49eef21a46431f2752b29f20a1434392bfdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 13:56:06 +0900 Subject: [PATCH 122/261] Move hover layer behind icon Looked bad on the "already downloaded" state where the icon becomes black. --- .../Drawables/Cards/Buttons/BeatmapCardIconButton.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index a4beab02ed..6b9b67123e 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -78,17 +78,17 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons Anchor = Anchor.Centre, Children = new Drawable[] { - Icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - }, hover = new Box { RelativeSizeAxes = Axes.Both, Colour = Color4.White.Opacity(0.1f), Blending = BlendingParameters.Additive, }, + Icon = new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + }, } }); From fc191807c6ea44659158d32476e5100058940837 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 3 Nov 2022 13:59:22 +0900 Subject: [PATCH 123/261] Fix velocity test failing with no audio device --- .../Timelines/Summary/Parts/TimelinePart.cs | 14 ++++++-------- osu.Game/Screens/Edit/EditorClock.cs | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 54914f4b23..bb5b4a6cea 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -57,15 +57,13 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { - // the track may not be loaded completely (only has a length once it is). - if (!beatmap.Value.Track.IsLoaded) - { - content.RelativeChildSize = Vector2.One; - Schedule(updateRelativeChildSize); - return; - } + // If the track is not loaded, assign a default sane length otherwise relative positioning becomes meaningless. + double trackLength = beatmap.Value.Track.IsLoaded ? beatmap.Value.Track.Length : 60000; + content.RelativeChildSize = new Vector2((float)Math.Max(1, trackLength), 1); - content.RelativeChildSize = new Vector2((float)Math.Max(1, beatmap.Value.Track.Length), 1); + // The track may not be loaded completely (only has a length once it is). + if (!beatmap.Value.Track.IsLoaded) + Schedule(updateRelativeChildSize); } protected virtual void LoadBeatmap(EditorBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 6485f683ad..81d82130da 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Edit private readonly Bindable track = new Bindable(); - public double TrackLength => track.Value?.Length ?? 60000; + public double TrackLength => track.Value?.IsLoaded == true ? track.Value.Length : 60000; public ControlPointInfo ControlPointInfo => Beatmap.ControlPointInfo; From 66a6084d3f6a93e4e10a61ea0625a9f457b51a48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:03:19 +0900 Subject: [PATCH 124/261] Scale in the background fill alongside the icon --- .../Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index 6b9b67123e..af1a8eb06a 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -74,6 +74,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons RelativeSizeAxes = Axes.Both, Masking = true, CornerRadius = BeatmapCard.CORNER_RADIUS, + Scale = new Vector2(0.8f), Origin = Anchor.Centre, Anchor = Anchor.Centre, Children = new Drawable[] @@ -88,6 +89,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { Origin = Anchor.Centre, Anchor = Anchor.Centre, + Scale = new Vector2(1.2f), }, } }); @@ -127,7 +129,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons bool isHovered = IsHovered && Enabled.Value; hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint); - Icon.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); + content.ScaleTo(isHovered ? 1 : 0.8f, 500, Easing.OutQuint); Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); } } From 07bfac40faaccdd47bbd4b96eaaa4d6789d1733c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:03:28 +0900 Subject: [PATCH 125/261] Adjust padding to avoid overlap with card border when expanded --- .../Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index f70694bdda..9b200d62aa 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -95,7 +95,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards Child = buttons = new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(3), + // Padding of 4 avoids touching the card borders when in the expanded (ie. showing difficulties) state. + // Left override allows the buttons to visually be wider and look better. + Padding = new MarginPadding(4) { Left = 2 }, Children = new BeatmapCardIconButton[] { new FavouriteButton(beatmapSet) From 62660ec92fe12dd64c42de6e7d3831e3169064eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:21:22 +0900 Subject: [PATCH 126/261] Reorganise drawables and transforms to make more sequential sense --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 83 +++++++++---------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index 3b418fcb2d..b2c804a2da 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -98,28 +98,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon AlwaysPresent = true, } }, - new Container - { - Name = @"Ring", - Masking = true, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new ArgonSpinnerRingArc - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Name = "Top Arc", - }, - new ArgonSpinnerRingArc - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Name = "Bottom Arc", - Scale = new Vector2(1, -1), - }, - } - }, ticksContainer = new Container { Anchor = Anchor.Centre, @@ -130,6 +108,29 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon }, }, new Container + { + Name = @"Ring", + Masking = true, + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(8f), + Children = new[] + { + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Top Arc", + }, + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Bottom Arc", + Scale = new Vector2(1, -1), + }, + } + }, + new Container { Name = @"Sides", RelativeSizeAxes = Axes.Both, @@ -226,6 +227,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { this.ScaleTo(initial_scale); ticksContainer.RotateTo(0); + centre.ScaleTo(0); + disc.ScaleTo(0); using (BeginDelayedSequence(spinner.TimePreempt / 2)) { @@ -233,27 +236,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon ticksContainer.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration); } - using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset)) - { - switch (state) - { - case ArmedState.Hit: - this.ScaleTo(initial_scale * 1.2f, 320, Easing.Out); - ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320); - break; - - case ArmedState.Miss: - this.ScaleTo(initial_scale * 0.8f, 320, Easing.In); - break; - } - } - } - - using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt)) - { - centre.ScaleTo(0); - disc.ScaleTo(0); - using (BeginDelayedSequence(spinner.TimePreempt / 2)) { centre.ScaleTo(0.3f, spinner.TimePreempt / 4, Easing.OutQuint); @@ -265,6 +247,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon disc.ScaleTo(1, spinner.TimePreempt / 2, Easing.OutQuint); } } + + using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset)) + { + switch (state) + { + case ArmedState.Hit: + disc.ScaleTo(initial_scale * 1.2f, 320, Easing.Out); + ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320); + break; + + case ArmedState.Miss: + disc.ScaleTo(initial_scale * 0.8f, 320, Easing.In); + break; + } + } } if (drawableSpinner.Result?.TimeStarted != null) From 0868c00ee83f00af4d4eb7a43317ac9569260ca0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:36:11 +0900 Subject: [PATCH 127/261] Fix spinner centre size being updated every frame using transforms --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index b2c804a2da..f99d4275bd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; @@ -184,6 +183,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon updateStateTransforms(drawableSpinner, drawableSpinner.State.Value); } + private float trackingElementInterpolation; + protected override void Update() { base.Update(); @@ -203,11 +204,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } else { - fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime)); - } + trackingElementInterpolation = + (float)Interpolation.Damp(trackingElementInterpolation, drawableSpinner.RotationTracker.Tracking ? 1 : 0, 0.985f, (float)Math.Abs(Clock.ElapsedFrameTime)); - if (centre.Width == idle_centre_size && drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); + fill.Alpha = trackingElementInterpolation * (tracking_alpha - idle_alpha) + idle_alpha; + centre.Size = new Vector2(trackingElementInterpolation * (tracking_centre_size - idle_centre_size) + idle_centre_size); + } const float initial_fill_scale = 0.1f; float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress; @@ -263,19 +265,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } } } - - if (drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); - } - - private void updateCentrePieceSize() - { - Debug.Assert(drawableSpinner.Result?.TimeStarted != null); - - Spinner spinner = drawableSpinner.HitObject; - - using (BeginAbsoluteSequence(drawableSpinner.Result.TimeStarted.Value)) - centre.ResizeTo(new Vector2(tracking_centre_size), spinner.TimePreempt / 2, Easing.OutQuint); } protected override void Dispose(bool isDisposing) From 94b1c2602eba7a75c76a7a4f4335377f5d4865aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:36:11 +0900 Subject: [PATCH 128/261] Fix spinner centre size being updated every frame using transforms --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index 4669b5b913..d88752f025 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; @@ -138,6 +137,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon updateStateTransforms(drawableSpinner, drawableSpinner.State.Value); } + private float trackingElementInterpolation; + protected override void Update() { base.Update(); @@ -157,11 +158,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } else { - fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime)); - } + trackingElementInterpolation = + (float)Interpolation.Damp(trackingElementInterpolation, drawableSpinner.RotationTracker.Tracking ? 1 : 0, 0.985f, (float)Math.Abs(Clock.ElapsedFrameTime)); - if (centre.Width == idle_centre_size && drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); + fill.Alpha = trackingElementInterpolation * (tracking_alpha - idle_alpha) + idle_alpha; + centre.Size = new Vector2(trackingElementInterpolation * (tracking_centre_size - idle_centre_size) + idle_centre_size); + } const float initial_fill_scale = 0.1f; float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress; @@ -221,19 +223,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } } } - - if (drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); - } - - private void updateCentrePieceSize() - { - Debug.Assert(drawableSpinner.Result?.TimeStarted != null); - - Spinner spinner = drawableSpinner.HitObject; - - using (BeginAbsoluteSequence(drawableSpinner.Result.TimeStarted.Value)) - centre.ResizeTo(new Vector2(tracking_centre_size), spinner.TimePreempt / 2, Easing.OutQuint); } protected override void Dispose(bool isDisposing) From e89d3840fc99c8f3724d674d14aad779e994bb2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 15:11:26 +0900 Subject: [PATCH 129/261] Adjust completion animation --- .../Skinning/Argon/ArgonSpinnerProgressArc.cs | 14 +++++++---- .../Skinning/Argon/ArgonSpinnerRingArc.cs | 24 +++++++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs index be7921a1f1..e998f55755 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Utils; -using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; using osuTK.Graphics; @@ -24,8 +23,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon private DrawableSpinner spinner = null!; + private CircularProgress background = null!; + [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableHitObject, OsuColour colours) + private void load(DrawableHitObject drawableHitObject) { RelativeSizeAxes = Axes.Both; @@ -33,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon InternalChildren = new Drawable[] { - new CircularProgress + background = new CircularProgress { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -59,8 +60,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { base.Update(); - fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 ? 1 : 0, 120f, (float)Math.Abs(Time.Elapsed)); - fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, arc_fill * spinner.Progress, 120f, (float)Math.Abs(Time.Elapsed)); + background.Alpha = spinner.Progress >= 1 ? 0 : 1; + + fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 && spinner.Progress < 1 ? 1 : 0, 40f, (float)Math.Abs(Time.Elapsed)); + fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, spinner.Progress >= 1 ? 0 : arc_fill * spinner.Progress, 40f, (float)Math.Abs(Time.Elapsed)); + fill.Rotation = (float)(90 - fill.Current.Value * 180); } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs index ec9d7bbae5..57fb57a09e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs @@ -1,24 +1,34 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Utils; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Argon { public class ArgonSpinnerRingArc : CompositeDrawable { private const float arc_fill = 0.31f; + private const float arc_fill_complete = 0.50f; + private const float arc_radius = 0.02f; + private DrawableSpinner spinner = null!; + private CircularProgress fill = null!; + [BackgroundDependencyLoader] - private void load() + private void load(DrawableHitObject drawableHitObject) { RelativeSizeAxes = Axes.Both; - InternalChild = new CircularProgress + spinner = (DrawableSpinner)drawableHitObject; + InternalChild = fill = new CircularProgress { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -29,5 +39,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon RoundedCaps = true, }; } + + protected override void Update() + { + base.Update(); + + fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, spinner.Progress >= 1 ? arc_fill_complete : arc_fill, 40f, (float)Math.Abs(Time.Elapsed)); + fill.InnerRadius = (float)Interpolation.DampContinuously(fill.InnerRadius, spinner.Progress >= 1 ? arc_radius * 2.2f : arc_radius, 40f, (float)Math.Abs(Time.Elapsed)); + + fill.Rotation = (float)(-fill.Current.Value * 180); + } } } From 56ef519cc28fc1ee5c7ca321723aa3d9370cbdd3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 15:43:06 +0900 Subject: [PATCH 130/261] Move `PopoverContainer` into `OnlineOverlay` to ensure correct colours --- osu.Game/OsuGameBase.cs | 9 ++------- osu.Game/Overlays/OnlineOverlay.cs | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c4c2c8325d..39ddffd2d0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,7 +18,6 @@ using osu.Framework.Development; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Handlers; @@ -358,13 +357,9 @@ namespace osu.Game (GlobalCursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both - }).WithChild(new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) + }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { - RelativeSizeAxes = Axes.Both, - Child = content = new PopoverContainer - { - RelativeSizeAxes = Axes.Both, - } + RelativeSizeAxes = Axes.Both }), // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything. globalBindings = new GlobalActionContainer(this) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 424584fbcf..24bc7a73e0 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online; @@ -45,7 +46,7 @@ namespace osu.Game.Overlays Children = new Drawable[] { Header.With(h => h.Depth = float.MinValue), - content = new Container + content = new PopoverContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y From f1c17129eb34d7e49342826e8fbd425b006d4f5f Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 3 Nov 2022 17:44:54 +0900 Subject: [PATCH 131/261] Add support for 'disabled' sample variation to HoverClickSounds --- .../UserInterface/TestSceneLabelledSliderBar.cs | 8 ++++++++ .../Graphics/Containers/OsuClickableContainer.cs | 2 +- .../Graphics/UserInterface/DrawableOsuMenuItem.cs | 4 +++- .../Graphics/UserInterface/HoverClickSounds.cs | 15 +++++++++++++-- osu.Game/Graphics/UserInterface/OsuButton.cs | 2 +- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 5 ++++- osu.Game/Graphics/UserInterface/ShearedButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarClock.cs | 3 +++ 8 files changed, 34 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs index e5f3aea2f7..5548375af2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs @@ -38,6 +38,14 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("revert back", () => this.ChildrenOfType>().ForEach(l => l.ResizeWidthTo(1, 200, Easing.OutQuint))); } + [Test] + public void TestDisable() + { + createSliderBar(); + AddStep("set disabled", () => this.ChildrenOfType>().ForEach(l => l.Current.Disabled = true)); + AddStep("unset disabled", () => this.ChildrenOfType>().ForEach(l => l.Current.Disabled = false)); + } + private void createSliderBar() { AddStep("create component", () => diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index 61ec9dfc24..03a1cfcc13 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Containers protected override Container Content => content; - protected virtual HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet); + protected virtual HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { BindTarget = Enabled } }; public OsuClickableContainer(HoverSampleSet sampleSet = HoverSampleSet.Default) { diff --git a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs index b469c21ab0..6c8eeed391 100644 --- a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs @@ -24,6 +24,7 @@ namespace osu.Game.Graphics.UserInterface private const int transition_length = 80; private TextContainer text; + private HoverClickSounds hoverClickSounds; public DrawableOsuMenuItem(MenuItem item) : base(item) @@ -36,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface BackgroundColour = Color4.Transparent; BackgroundColourHover = Color4Extensions.FromHex(@"172023"); - AddInternal(new HoverClickSounds()); + AddInternal(hoverClickSounds = new HoverClickSounds()); updateTextColour(); @@ -76,6 +77,7 @@ namespace osu.Game.Graphics.UserInterface private void updateState() { + hoverClickSounds.Enabled.Value = !Item.Action.Disabled; Alpha = Item.Action.Disabled ? 0.2f : 1; if (IsHovered && !Item.Action.Disabled) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index dab4390ede..9b4bff17e6 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Input.Events; using osu.Framework.Utils; @@ -21,6 +22,8 @@ namespace osu.Game.Graphics.UserInterface public class HoverClickSounds : HoverSounds { private Sample sampleClick; + private Sample sampleClickDisabled; + public Bindable Enabled = new Bindable(true); private readonly MouseButton[] buttons; /// @@ -41,8 +44,13 @@ namespace osu.Game.Graphics.UserInterface { if (buttons.Contains(e.Button) && Contains(e.ScreenSpaceMousePosition)) { - sampleClick.Frequency.Value = 0.99 + RNG.NextDouble(0.02); - sampleClick.Play(); + var channel = Enabled.Value ? sampleClick?.GetChannel() : sampleClickDisabled?.GetChannel(); + + if (channel != null) + { + channel.Frequency.Value = 0.99 + RNG.NextDouble(0.02); + channel.Play(); + } } return base.OnClick(e); @@ -53,6 +61,9 @@ namespace osu.Game.Graphics.UserInterface { sampleClick = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select") ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select"); + + sampleClickDisabled = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select-disabled") + ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select-disabled"); } } } diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 291ff644fd..88f3ccd191 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -104,7 +104,7 @@ namespace osu.Game.Graphics.UserInterface }); if (hoverSounds.HasValue) - AddInternal(new HoverClickSounds(hoverSounds.Value)); + AddInternal(new HoverClickSounds(hoverSounds.Value) { Enabled = { BindTarget = Enabled } }); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 9acb0c7f94..392740690a 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -46,6 +46,8 @@ namespace osu.Game.Graphics.UserInterface public bool PlaySamplesOnAdjust { get; set; } = true; + private readonly HoverClickSounds hoverClickSounds; + /// /// Whether to format the tooltip as a percentage or the actual value. /// @@ -127,7 +129,7 @@ namespace osu.Game.Graphics.UserInterface Current = { Value = true } }, }, - new HoverClickSounds() + hoverClickSounds = new HoverClickSounds() }; Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; }; @@ -152,6 +154,7 @@ namespace osu.Game.Graphics.UserInterface { base.LoadComplete(); CurrentNumber.BindValueChanged(current => TooltipText = getTooltipText(current.NewValue), true); + Current.DisabledChanged += disabled => hoverClickSounds.Enabled.Value = !disabled; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Graphics/UserInterface/ShearedButton.cs b/osu.Game/Graphics/UserInterface/ShearedButton.cs index 0c25d06cd4..e406e273e6 100644 --- a/osu.Game/Graphics/UserInterface/ShearedButton.cs +++ b/osu.Game/Graphics/UserInterface/ShearedButton.cs @@ -138,7 +138,7 @@ namespace osu.Game.Graphics.UserInterface } } - protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet); + protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { BindTarget = Enabled } }; protected override void LoadComplete() { diff --git a/osu.Game/Overlays/Toolbar/ToolbarClock.cs b/osu.Game/Overlays/Toolbar/ToolbarClock.cs index c5add6eee2..9c264acbd1 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarClock.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarClock.cs @@ -13,6 +13,7 @@ using osu.Framework.Input.Events; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using osuTK; using osuTK.Graphics; @@ -123,6 +124,8 @@ namespace osu.Game.Overlays.Toolbar base.OnHoverLost(e); } + protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { Value = true } }; + private void cycleDisplayMode() { switch (clockDisplayMode.Value) From 59bbd9c460afc87ee2cc8613692fc6d0e156dfff Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 3 Nov 2022 17:47:29 +0900 Subject: [PATCH 132/261] Fix some components using wrong sample set --- osu.Game/Graphics/UserInterface/LoadingButton.cs | 1 + osu.Game/Overlays/Comments/CancellableCommentEditor.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/LoadingButton.cs b/osu.Game/Graphics/UserInterface/LoadingButton.cs index 8be50a4b43..44067bac8b 100644 --- a/osu.Game/Graphics/UserInterface/LoadingButton.cs +++ b/osu.Game/Graphics/UserInterface/LoadingButton.cs @@ -41,6 +41,7 @@ namespace osu.Game.Graphics.UserInterface private readonly LoadingSpinner loading; protected LoadingButton() + : base(HoverSampleSet.Button) { Add(loading = new LoadingSpinner { diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 853171ea4a..7ba6de86b7 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -38,6 +39,7 @@ namespace osu.Game.Overlays.Comments private readonly Box background; public CancelButton() + : base(HoverSampleSet.Button) { AutoSizeAxes = Axes.Both; Child = new CircularContainer From f75c4ba95fff8056cb4b48582d281d53183f1758 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 20:27:44 +0900 Subject: [PATCH 133/261] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 8711ceec64..b3c48da2bf 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8d45ebec57..fe44ed3688 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 76d2e727c8..b5b488d82e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From f6c376c09077dd79713940c785c6985a802bbbbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 20:29:27 +0900 Subject: [PATCH 134/261] Minor refactoring --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 4 +++- osu.Game/Overlays/Toolbar/ToolbarClock.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 9b4bff17e6..89d1570cd4 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -21,9 +21,11 @@ namespace osu.Game.Graphics.UserInterface /// public class HoverClickSounds : HoverSounds { + public Bindable Enabled = new Bindable(true); + private Sample sampleClick; private Sample sampleClickDisabled; - public Bindable Enabled = new Bindable(true); + private readonly MouseButton[] buttons; /// diff --git a/osu.Game/Overlays/Toolbar/ToolbarClock.cs b/osu.Game/Overlays/Toolbar/ToolbarClock.cs index 9c264acbd1..3fd37d9a62 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarClock.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarClock.cs @@ -124,7 +124,7 @@ namespace osu.Game.Overlays.Toolbar base.OnHoverLost(e); } - protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { Value = true } }; + protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet); private void cycleDisplayMode() { From 37b5f4891149fa3b6eefadd02e963d4ac3f9f890 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 03:20:24 +0300 Subject: [PATCH 135/261] Adjust test scene to cover failure --- .../Visual/Online/TestSceneBeatmapListingOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs index 2c9b34e4a7..1e0a09d37a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs @@ -198,13 +198,13 @@ namespace osu.Game.Tests.Visual.Online beatmapSet = CreateAPIBeatmapSet(Ruleset.Value); beatmapSet.Title = "last beatmap of first page"; - fetchFor(getManyBeatmaps(49).Append(beatmapSet).ToArray(), true); + fetchFor(getManyBeatmaps(49).Append(new APIBeatmapSet { Title = "last beatmap of first page", OnlineID = beatmapSet.OnlineID }).ToArray(), true); }); AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() == 50); - AddStep("set next page", () => setSearchResponse(getManyBeatmaps(49).Prepend(beatmapSet).ToArray(), false)); + AddStep("set next page", () => setSearchResponse(getManyBeatmaps(49).Prepend(new APIBeatmapSet { Title = "this shouldn't show up", OnlineID = beatmapSet.OnlineID }).ToArray(), false)); AddStep("scroll to end", () => overlay.ChildrenOfType().Single().ScrollToEnd()); - AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() == 99); + AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() >= 99); AddAssert("beatmap not duplicated", () => overlay.ChildrenOfType().Count(c => c.BeatmapSet.Equals(beatmapSet)) == 1); } From ac8fb4f9b2b6ef1411b9aff9ede25607e898d3a8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 03:20:14 +0300 Subject: [PATCH 136/261] Fix beatmap cards still potentially showing twice in listing --- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 238f41e53d..717a1de6b5 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -149,5 +149,8 @@ namespace osu.Game.Online.API.Requests.Responses #endregion public bool Equals(IBeatmapSetInfo? other) => other is APIBeatmapSet b && this.MatchesOnlineID(b); + + // ReSharper disable once NonReadonlyMemberInGetHashCode + public override int GetHashCode() => OnlineID.GetHashCode(); } } From e11d44d14f9f575ae591bc89eeee1414107528fd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 2 Nov 2022 22:30:30 -0700 Subject: [PATCH 137/261] Add url clicking support to profile badges --- .../Online/TestSceneUserProfileOverlay.cs | 11 +++++++++-- .../Header/Components/DrawableBadge.cs | 19 ++++++++++--------- osu.Game/Users/Badge.cs | 3 +++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index caa2d2571d..7064a08151 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -52,8 +52,15 @@ namespace osu.Game.Tests.Visual.Online { AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), Description = "Outstanding help by being a voluntary test subject.", - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" - } + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg", + Url = "https://osu.ppy.sh/wiki/en/People/Community_Contributors", + }, + new Badge + { + AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), + Description = "Badge without a url.", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg", + }, }, Title = "osu!volunteer", Colour = "ff0000", diff --git a/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs index cf75818a0c..2ee80a7494 100644 --- a/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs @@ -1,22 +1,20 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; +using osu.Game.Graphics.Containers; +using osu.Game.Online; using osu.Game.Users; using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { [LongRunningLoad] - public class DrawableBadge : CompositeDrawable, IHasTooltip + public class DrawableBadge : OsuClickableContainer { public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); @@ -29,22 +27,25 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(LargeTextureStore textures) + private void load(LargeTextureStore textures, ILinkHandler? linkHandler) { - InternalChild = new Sprite + Child = new Sprite { FillMode = FillMode.Fit, RelativeSizeAxes = Axes.Both, Texture = textures.Get(badge.ImageUrl), }; + + if (!string.IsNullOrEmpty(badge.Url)) + Action = () => linkHandler?.HandleLink(badge.Url); } protected override void LoadComplete() { base.LoadComplete(); - InternalChild.FadeInFromZero(200); + this.FadeInFromZero(200); } - public LocalisableString TooltipText => badge.Description; + public override LocalisableString TooltipText => badge.Description; } } diff --git a/osu.Game/Users/Badge.cs b/osu.Game/Users/Badge.cs index c191c25895..b87e2ddecd 100644 --- a/osu.Game/Users/Badge.cs +++ b/osu.Game/Users/Badge.cs @@ -18,5 +18,8 @@ namespace osu.Game.Users [JsonProperty("image_url")] public string ImageUrl; + + [JsonProperty("url")] + public string Url; } } From c40c70509e1909fab2488120c9e867cb76f66827 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 15:14:09 +0900 Subject: [PATCH 138/261] Improve song select transition to gameplay --- osu.Game/Screens/Select/BeatmapCarousel.cs | 20 +++++++++++++++++ osu.Game/Screens/Select/SongSelect.cs | 26 +++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 3b694dbf43..2f99f6acca 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -770,6 +770,26 @@ namespace osu.Game.Screens.Select { updateItem(item); + if (!item.Item.Filtered.Value) + { + bool isSelected = item.Item.State.Value == CarouselItemState.Selected; + + // Cheap way of doing animations when entering / exiting song select. + const double half_time = 50; + const float panel_x_offset_when_inactive = 200; + + if (isSelected || AllowSelection) + { + item.Alpha = (float)Interpolation.DampContinuously(item.Alpha, 1, half_time, Clock.ElapsedFrameTime); + item.X = (float)Interpolation.DampContinuously(item.X, 0, half_time, Clock.ElapsedFrameTime); + } + else + { + item.Alpha = (float)Interpolation.DampContinuously(item.Alpha, 0, half_time, Clock.ElapsedFrameTime); + item.X = (float)Interpolation.DampContinuously(item.X, panel_x_offset_when_inactive, half_time, Clock.ElapsedFrameTime); + } + } + if (item is DrawableCarouselBeatmapSet set) { foreach (var diff in set.DrawableBeatmaps) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f5a058e945..fe9b67a02e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -89,6 +89,8 @@ namespace osu.Game.Screens.Select protected BeatmapCarousel Carousel { get; private set; } + private ParallaxContainer wedgeBackground; + protected Container LeftArea { get; private set; } private BeatmapInfoWedge beatmapInfoWedge; @@ -165,10 +167,12 @@ namespace osu.Game.Screens.Select { new Drawable[] { - new ParallaxContainer + wedgeBackground = new ParallaxContainer { ParallaxAmount = 0.005f, RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Child = new WedgeBackground { RelativeSizeAxes = Axes.Both, @@ -609,9 +613,15 @@ namespace osu.Game.Screens.Select } } - this.FadeIn(250); + LeftArea.MoveToX(0, 400, Easing.OutQuint); + LeftArea.FadeIn(100, Easing.OutQuint); - this.ScaleTo(1, 250, Easing.OutSine); + FilterControl.MoveToY(0, 400, Easing.OutQuint); + FilterControl.FadeIn(100, Easing.OutQuint); + + this.FadeIn(250, Easing.OutQuint); + + wedgeBackground.ScaleTo(1, 500, Easing.OutQuint); FilterControl.Activate(); } @@ -629,9 +639,15 @@ namespace osu.Game.Screens.Select endLooping(); - this.ScaleTo(1.1f, 250, Easing.InSine); + FilterControl.MoveToY(-120, 250, Easing.OutQuint); + FilterControl.FadeOut(100); - this.FadeOut(250); + LeftArea.MoveToX(-150, 1800, Easing.OutQuint); + LeftArea.FadeOut(200, Easing.OutQuint); + + wedgeBackground.ScaleTo(2.4f, 400, Easing.OutQuint); + + this.FadeOut(400, Easing.OutQuint); FilterControl.Deactivate(); base.OnSuspending(e); From 819027d61c812ad29c7dc05b9d2175e964e2bc02 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 16:17:49 +0900 Subject: [PATCH 139/261] Rename to `isConvert` --- .../Difficulty/TaikoPerformanceCalculator.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 317e4a2f72..2d1b2903c9 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked. - bool taikoSpecificBeatmap = score.BeatmapInfo.Ruleset.OnlineID == 1; + bool isConvert = score.BeatmapInfo.Ruleset.OnlineID != 1; double multiplier = 1.13; @@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes, taikoSpecificBeatmap); - double accuracyValue = computeAccuracyValue(score, taikoAttributes, taikoSpecificBeatmap); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, isConvert); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, isConvert); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) + if (score.Mods.Any(m => m is ModHidden) && !isConvert) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficultyValue * Math.Pow(accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert) { if (attributes.GreatHitWindow <= 0) return 0; @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty accuracyValue *= lengthBonus; // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && !isConvert) accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus); return accuracyValue; From dd5a3b2bf37ed0859e739849952d72490b9509dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 16:49:21 +0900 Subject: [PATCH 140/261] Add one more complex test --- .../Visual/Gameplay/TestSceneBezierConverter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs index 701f30bfd4..28a9d17882 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -134,6 +134,17 @@ namespace osu.Game.Tests.Visual.Gameplay }); } + [Test] + public void TestComplex() + { + AddStep("create path", () => + { + path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(100, 0))); + path.ControlPoints.AddRange(createSegment(PathType.Bezier, new Vector2(100, 0), new Vector2(150, 30), new Vector2(100, 100))); + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, new Vector2(100, 100), new Vector2(25, 50), Vector2.Zero)); + }); + } + [TestCase(0, 100)] [TestCase(1, 100)] [TestCase(5, 100)] From 923d44a769c3030e84f36227f33a2739d850dca6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:00:58 +0900 Subject: [PATCH 141/261] Update dependencies --- .../osu.Game.Rulesets.EmptyFreeform.Tests.csproj | 2 +- .../osu.Game.Rulesets.Pippidon.Tests.csproj | 2 +- .../osu.Game.Rulesets.EmptyScrolling.Tests.csproj | 2 +- .../osu.Game.Rulesets.Pippidon.Tests.csproj | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game.Benchmarks/osu.Game.Benchmarks.csproj | 2 +- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- .../osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 4 ++-- .../osu.Game.Tournament.Tests.csproj | 2 +- osu.Game/osu.Game.csproj | 12 ++++++------ 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj index 936808f38b..52b728a115 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index 35e7742172..95b96adab0 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj index c1044965b5..d12403016d 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index 35e7742172..95b96adab0 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 3f926ed45a..1f4544098b 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -27,7 +27,7 @@ - + diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index d62d422f33..f47b069373 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -9,7 +9,7 @@ - + diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index c9db824615..5a2e8e0bf0 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -3,7 +3,7 @@ - + WinExe diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 0d7b03d830..be51dc0e4c 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -3,7 +3,7 @@ - + WinExe diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 1eb1c85d93..c10c3ffb15 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + WinExe diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 38e61f5624..6af1beff69 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -3,7 +3,7 @@ - + WinExe diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index bdf8cc5136..24969414d0 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -1,11 +1,11 @@  - + - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index bdef46a6b2..9f2a088a4b 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -6,7 +6,7 @@ - + WinExe diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fe44ed3688..9a6866d264 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,10 +23,10 @@ - - - - + + + + @@ -34,10 +34,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + From 2b934e0beafbffda932574cf3fb17db4bb66e0b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:19:03 +0900 Subject: [PATCH 142/261] Increase delay for changing background on returning to main menu --- osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index f8546d6ed0..a7a763f2a6 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Backgrounds nextTask = Scheduler.AddDelayed(() => { LoadComponentAsync(nextBackground, displayNext, cancellationTokenSource.Token); - }, 100); + }, 500); return true; } From 4bbff99f315b23b34d88be8f90962e0f3053fafb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:35:30 +0900 Subject: [PATCH 143/261] Remove unnecessary fade in `SeasonalBackground` --- osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs b/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs index 5c98e22818..9d873762bf 100644 --- a/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs +++ b/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs @@ -111,8 +111,6 @@ namespace osu.Game.Graphics.Backgrounds private void load(LargeTextureStore textures) { Sprite.Texture = textures.Get(url) ?? textures.Get(fallback_texture_name); - // ensure we're not loading in without a transition. - this.FadeInFromZero(200, Easing.InOutSine); } public override bool Equals(Background other) From 4f14ae4e34ad3f70d0c26dedc7448006025279ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:36:11 +0900 Subject: [PATCH 144/261] Adjust transition effect for main menu backgrounds --- osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index a7a763f2a6..44b6fcce4a 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Backgrounds private void displayNext(Background newBackground) { - background?.FadeOut(800, Easing.InOutSine); + background?.FadeOut(800, Easing.OutQuint); background?.Expire(); AddInternal(background = newBackground); From 58396d49dc9e44a7a3dcec75a969851fd7856451 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 16:42:59 +0900 Subject: [PATCH 145/261] Fix handling of local echo deduplication --- .../CreateNewPrivateMessageRequest.cs | 1 + .../Online/API/Requests/PostMessageRequest.cs | 1 + osu.Game/Online/Chat/Channel.cs | 8 ++++ osu.Game/Online/Chat/ChannelManager.cs | 48 ++++++++++++------- osu.Game/Online/Chat/Message.cs | 6 +++ .../WebSocket/WebSocketNotificationsClient.cs | 10 ++-- 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs b/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs index dea94bfce2..6b7192dbf4 100644 --- a/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs +++ b/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs @@ -28,6 +28,7 @@ namespace osu.Game.Online.API.Requests req.AddParameter(@"target_id", user.Id.ToString()); req.AddParameter(@"message", message.Content); req.AddParameter(@"is_action", message.IsAction.ToString().ToLowerInvariant()); + req.AddParameter(@"uuid", message.Uuid); return req; } diff --git a/osu.Game/Online/API/Requests/PostMessageRequest.cs b/osu.Game/Online/API/Requests/PostMessageRequest.cs index 7b20bd9ad5..e3709d8f13 100644 --- a/osu.Game/Online/API/Requests/PostMessageRequest.cs +++ b/osu.Game/Online/API/Requests/PostMessageRequest.cs @@ -25,6 +25,7 @@ namespace osu.Game.Online.API.Requests req.Method = HttpMethod.Post; req.AddParameter(@"is_action", Message.IsAction.ToString().ToLowerInvariant()); req.AddParameter(@"message", Message.Content); + req.AddParameter(@"uuid", Message.Uuid); return req; } diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index f51ea3e8d6..9bfaecc46b 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -134,6 +134,14 @@ namespace osu.Game.Online.Chat /// public void AddNewMessages(params Message[] messages) { + foreach (var m in messages) + { + LocalEchoMessage localEcho = pendingMessages.FirstOrDefault(local => local.Uuid == m.Uuid); + + if (localEcho != null) + ReplaceMessage(localEcho, m); + } + messages = messages.Except(Messages).ToArray(); if (messages.Length == 0) return; diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a901c15bf4..05e2fb79e8 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -85,8 +85,21 @@ namespace osu.Game.Online.Chat [BackgroundDependencyLoader] private void load() { - connector.ChannelJoined += ch => Schedule(() => joinChannel(ch)); + connector.ChannelJoined += ch => Schedule(() => + { + var localChannel = getChannel(ch); + + if (localChannel != ch) + { + localChannel.Joined.Value = true; + localChannel.Id = ch.Id; + } + + joinChannel(localChannel); + }); + connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); + connector.PresenceReceived += () => Schedule(() => { if (!channelsInitialised) @@ -189,7 +202,8 @@ namespace osu.Game.Online.Chat Timestamp = DateTimeOffset.Now, ChannelId = target.Id, IsAction = isAction, - Content = text + Content = text, + Uuid = Guid.NewGuid().ToString() }; target.AddLocalEcho(message); @@ -199,13 +213,7 @@ namespace osu.Game.Online.Chat { var createNewPrivateMessageRequest = new CreateNewPrivateMessageRequest(target.Users.First(), message); - createNewPrivateMessageRequest.Success += createRes => - { - target.Id = createRes.ChannelID; - target.ReplaceMessage(message, createRes.Message); - dequeueAndRun(); - }; - + createNewPrivateMessageRequest.Success += _ => dequeueAndRun(); createNewPrivateMessageRequest.Failure += exception => { handlePostException(exception); @@ -219,12 +227,7 @@ namespace osu.Game.Online.Chat var req = new PostMessageRequest(message); - req.Success += m => - { - target.ReplaceMessage(message, m); - dequeueAndRun(); - }; - + req.Success += m => dequeueAndRun(); req.Failure += exception => { handlePostException(exception); @@ -403,7 +406,20 @@ namespace osu.Game.Online.Chat { Channel found = null; - bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : lookup.Name == ch.Name; + bool lookupCondition(Channel ch) + { + // If both channels have an id, use that. + if (lookup.Id > 0 && ch.Id > 0) + return ch.Id == lookup.Id; + + // In the case that the local echo is received in a new channel (i.e. one that does not yet have an ID), + // then we need to check for any existing channel with the message containing the same message matched by UUID. + if (lookup.Messages.Count > 0 && ch.Messages.Any(m => m.Uuid == lookup.Messages.Last().Uuid)) + return true; + + // As a last resort, fallback to matching by name. + return lookup.Name == ch.Name; + } var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 25c5b0853f..9f6f9c8d6b 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -37,6 +37,12 @@ namespace osu.Game.Online.Chat set => Sender = new APIUser { Id = value }; } + /// + /// A unique identifier for this message. Sent to and from osu!web to use for deduplication. + /// + [JsonProperty(@"uuid")] + public string Uuid { get; set; } = string.Empty; + [JsonConstructor] public Message() { diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index ff0941ecba..0a93081915 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Net.WebSockets; using System.Text; using System.Threading; @@ -126,12 +124,10 @@ namespace osu.Game.Online.Notifications.WebSocket NewChatMessageData? messageData = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(messageData != null); - List messages = messageData.Messages.Where(m => m.Sender.OnlineID != api.LocalUser.Value.OnlineID).ToList(); + foreach (var msg in messageData.Messages) + HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId, Messages = { msg } }); - foreach (var msg in messages) - HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId }); - - HandleMessages(messages); + HandleMessages(messageData.Messages); break; } From 72745656e71ef3def43ca65b709a6c2f4000b1ca Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 18:48:34 +0900 Subject: [PATCH 146/261] Remove StartChat()/chat enablement --- osu.Game/Online/Chat/ChannelManager.cs | 2 -- .../Notifications/NotificationsClient.cs | 24 +------------------ .../NotificationsClientConnector.cs | 11 --------- .../WebSocket/WebSocketNotificationsClient.cs | 13 ++++------ 4 files changed, 5 insertions(+), 45 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 05e2fb79e8..77d53911d9 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -110,8 +110,6 @@ namespace osu.Game.Online.Chat } }); - connector.StartChat(); - apiState.BindTo(api.State); apiState.BindValueChanged(status => { diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 5c575e828d..cb5e94fb1d 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -23,7 +23,6 @@ namespace osu.Game.Online.Notifications protected readonly IAPIProvider API; - private bool enableChat; private long lastMessageId; protected NotificationsClient(IAPIProvider api) @@ -31,28 +30,7 @@ namespace osu.Game.Online.Notifications API = api; } - public bool EnableChat - { - get => enableChat; - set - { - if (enableChat == value) - return; - - enableChat = value; - - if (EnableChat) - Task.Run(StartChatAsync); - } - } - - public override async Task ConnectAsync(CancellationToken cancellationToken) - { - if (EnableChat) - await StartChatAsync(); - } - - protected virtual Task StartChatAsync() + public override Task ConnectAsync(CancellationToken cancellationToken) { API.Queue(CreateFetchMessagesRequest(0)); return Task.CompletedTask; diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs index 5aa49a7783..d4c846a7a2 100644 --- a/osu.Game/Online/Notifications/NotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -19,21 +19,11 @@ namespace osu.Game.Online.Notifications public event Action>? NewMessages; public event Action? PresenceReceived; - private bool chatStarted; - protected NotificationsClientConnector(IAPIProvider api) : base(api) { } - public void StartChat() - { - chatStarted = true; - - if (CurrentConnection is NotificationsClient client) - client.EnableChat = true; - } - protected sealed override async Task BuildConnectionAsync(CancellationToken cancellationToken) { var client = await BuildNotificationClientAsync(cancellationToken); @@ -41,7 +31,6 @@ namespace osu.Game.Online.Notifications client.ChannelJoined = c => ChannelJoined?.Invoke(c); client.NewMessages = m => NewMessages?.Invoke(m); client.PresenceReceived = () => PresenceReceived?.Invoke(); - client.EnableChat = chatStarted; return client; } diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 0a93081915..bc4ceea993 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -22,27 +22,22 @@ namespace osu.Game.Online.Notifications.WebSocket { private readonly ClientWebSocket socket; private readonly string endpoint; - private readonly IAPIProvider api; public WebSocketNotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) : base(api) { this.socket = socket; this.endpoint = endpoint; - this.api = api; } public override async Task ConnectAsync(CancellationToken cancellationToken) { await socket.ConnectAsync(new Uri(endpoint), cancellationToken).ConfigureAwait(false); - runReadLoop(cancellationToken); - await base.ConnectAsync(cancellationToken); - } - - protected override async Task StartChatAsync() - { await sendMessage(new StartChatRequest(), CancellationToken.None); - await base.StartChatAsync(); + + runReadLoop(cancellationToken); + + await base.ConnectAsync(cancellationToken); } private void runReadLoop(CancellationToken cancellationToken) => Task.Run(async () => From eb836269e765549f5c76e6c0ca733442842c5c25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:50:17 +0900 Subject: [PATCH 147/261] Allow testing settings panel with interactivity by default --- .../Visual/Settings/TestSceneSettingsPanel.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs index 9791bb6248..ad60c98e05 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs @@ -35,13 +35,19 @@ namespace osu.Game.Tests.Visual.Settings State = { Value = Visibility.Visible } }); }); + } - AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + [Test] + public void TestBasic() + { + AddStep("do nothing", () => { }); } [Test] public void TestFiltering([Values] bool beforeLoad) { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + if (beforeLoad) AddStep("set filter", () => settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling"); @@ -67,6 +73,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestFilterAfterLoad() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddUntilStep("wait for items to load", () => settings.SectionsContainer.ChildrenOfType().Any()); AddStep("set filter", () => settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling"); @@ -75,6 +83,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void ToggleVisibility() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddWaitStep("wait some", 5); AddToggleStep("toggle visibility", _ => settings.ToggleVisibility()); } @@ -82,6 +92,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestTextboxFocusAfterNestedPanelBackButton() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddUntilStep("sections loaded", () => settings.SectionsContainer.Children.Count > 0); AddUntilStep("top-level textbox focused", () => settings.SectionsContainer.ChildrenOfType().FirstOrDefault()?.HasFocus == true); @@ -107,6 +119,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestTextboxFocusAfterNestedPanelEscape() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddUntilStep("sections loaded", () => settings.SectionsContainer.Children.Count > 0); AddUntilStep("top-level textbox focused", () => settings.SectionsContainer.ChildrenOfType().FirstOrDefault()?.HasFocus == true); From fa18b5f7014671f13c0f4930b3ae740755952f07 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 18:51:00 +0900 Subject: [PATCH 148/261] Construct notifications client inside ChannelManager --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneChatLink.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs | 2 +- .../Visual/Online/TestSceneStandAloneChatDisplay.cs | 2 +- .../Components/TournamentMatchChatDisplay.cs | 2 +- osu.Game/Online/Chat/ChannelManager.cs | 5 +++-- osu.Game/OsuGame.cs | 6 +----- 8 files changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index 86be638781..e7eb06c795 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -151,7 +151,7 @@ namespace osu.Game.Tests.Chat public ChannelManagerContainer(IAPIProvider apiProvider) { - InternalChild = ChannelManager = new ChannelManager(apiProvider, apiProvider.GetNotificationsConnector()); + InternalChild = ChannelManager = new ChannelManager(apiProvider); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 5c46cd96be..de44986001 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Online { linkColour = colours.Blue; - var chatManager = new ChannelManager(API, API.GetNotificationsConnector()); + var chatManager = new ChannelManager(API); BindableList availableChannels = (BindableList)chatManager.AvailableChannels; availableChannels.Add(new Channel { Name = "#english" }); availableChannels.Add(new Channel { Name = "#japanese" }); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 6b2124f1f8..0b982a5745 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { - (typeof(ChannelManager), channelManager = new ChannelManager(API, API.GetNotificationsConnector())), + (typeof(ChannelManager), channelManager = new ChannelManager(API)), }, Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs index cb93812bc2..57514cdf37 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs @@ -250,7 +250,7 @@ namespace osu.Game.Tests.Visual.Online public TestContainer(IAPIProvider api, Channel[] channels) { this.channels = channels; - ChannelManager = new ChannelManager(api, api.GetNotificationsConnector()); + ChannelManager = new ChannelManager(api); } [BackgroundDependencyLoader] diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index 07196cc92a..34ecad7dc1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Online { var api = parent.Get(); - Add(channelManager = new ChannelManager(api, api.GetNotificationsConnector())); + Add(channelManager = new ChannelManager(api)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 48ff45974d..ca2b400e8b 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tournament.Components if (manager == null) { - AddInternal(manager = new ChannelManager(api, api.GetNotificationsConnector())); + AddInternal(manager = new ChannelManager(api)); Channel.BindTo(manager.CurrentChannel); } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 77d53911d9..a9603506c6 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -74,10 +74,11 @@ namespace osu.Game.Online.Chat private bool channelsInitialised; private ScheduledDelegate ackDelegate; - public ChannelManager(IAPIProvider api, NotificationsClientConnector connector) + public ChannelManager(IAPIProvider api) { this.api = api; - this.connector = connector; + + connector = api.GetNotificationsConnector(); CurrentChannel.ValueChanged += currentChannelChanged; } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f36d83d5c2..3a8f202d97 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -44,7 +44,6 @@ using osu.Game.Localisation; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications; using osu.Game.Overlays; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; @@ -84,7 +83,6 @@ namespace osu.Game private ChatOverlay chatOverlay; private ChannelManager channelManager; - private NotificationsClientConnector notificationsClient; [NotNull] protected readonly NotificationOverlay Notifications = new NotificationOverlay(); @@ -680,7 +678,6 @@ namespace osu.Game { base.Dispose(isDisposing); SentryLogger.Dispose(); - notificationsClient.Dispose(); } protected override IDictionary GetFrameworkConfigDefaults() @@ -758,7 +755,6 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); - dependencies.CacheAs(notificationsClient = API.GetNotificationsConnector()); var sessionIdleTracker = new GameIdleTracker(300000); sessionIdleTracker.IsIdle.BindValueChanged(idle => @@ -885,7 +881,7 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); - loadComponentSingleFile(channelManager = new ChannelManager(API, notificationsClient), AddInternal, true); + loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(new MessageNotifier(), AddInternal, true); loadComponentSingleFile(Settings = new SettingsOverlay(), leftFloatingOverlayContent.Add, true); From 8b58475ee04dcbd1ffd59b11736a7c79197df2be Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:50:42 +0900 Subject: [PATCH 149/261] Update `OsuButton` hover animation to better suit immediacy of sound effects --- osu.Game/Graphics/UserInterface/OsuButton.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 88f3ccd191..9140815f32 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -4,7 +4,6 @@ #nullable disable using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -95,7 +94,7 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Colour = Color4.White.Opacity(.1f), + Colour = Color4.White, Blending = BlendingParameters.Additive, Depth = float.MinValue }, @@ -126,7 +125,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(ClickEvent e) { if (Enabled.Value) - Background.FlashColour(BackgroundColour.Lighten(0.4f), 200); + Background.FlashColour(Color4.White, 800, Easing.OutQuint); return base.OnClick(e); } @@ -134,7 +133,11 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(HoverEvent e) { if (Enabled.Value) - Hover.FadeIn(200, Easing.OutQuint); + { + Hover.FadeTo(0.2f, 40, Easing.OutQuint) + .Then() + .FadeTo(0.1f, 800, Easing.OutQuint); + } return base.OnHover(e); } @@ -143,7 +146,7 @@ namespace osu.Game.Graphics.UserInterface { base.OnHoverLost(e); - Hover.FadeOut(300); + Hover.FadeOut(800, Easing.OutQuint); } protected override bool OnMouseDown(MouseDownEvent e) From 66bbe3411628b0b9664e66ec66f15d241843b1bc Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 18:52:57 +0900 Subject: [PATCH 150/261] Move polling clients to osu.Game.Tests namespace --- osu.Game/Online/API/DummyAPIAccess.cs | 2 +- .../Polling => Tests}/PollingNotificationsClient.cs | 3 ++- .../Polling => Tests}/PollingNotificationsClientConnector.cs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) rename osu.Game/{Online/Notifications/Polling => Tests}/PollingNotificationsClient.cs (94%) rename osu.Game/{Online/Notifications/Polling => Tests}/PollingNotificationsClientConnector.cs (92%) diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs index 865e1e0a70..609efd8ab6 100644 --- a/osu.Game/Online/API/DummyAPIAccess.cs +++ b/osu.Game/Online/API/DummyAPIAccess.cs @@ -10,7 +10,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Notifications; -using osu.Game.Online.Notifications.Polling; +using osu.Game.Tests; using osu.Game.Users; namespace osu.Game.Online.API diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs b/osu.Game/Tests/PollingNotificationsClient.cs similarity index 94% rename from osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs rename to osu.Game/Tests/PollingNotificationsClient.cs index 2f343abf86..c1f032a647 100644 --- a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs +++ b/osu.Game/Tests/PollingNotificationsClient.cs @@ -4,8 +4,9 @@ using System.Threading; using System.Threading.Tasks; using osu.Game.Online.API; +using osu.Game.Online.Notifications; -namespace osu.Game.Online.Notifications.Polling +namespace osu.Game.Tests { /// /// A notifications client which polls for new messages every second. diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs b/osu.Game/Tests/PollingNotificationsClientConnector.cs similarity index 92% rename from osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs rename to osu.Game/Tests/PollingNotificationsClientConnector.cs index ff3f30edcd..823fc9d157 100644 --- a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs +++ b/osu.Game/Tests/PollingNotificationsClientConnector.cs @@ -4,8 +4,9 @@ using System.Threading; using System.Threading.Tasks; using osu.Game.Online.API; +using osu.Game.Online.Notifications; -namespace osu.Game.Online.Notifications.Polling +namespace osu.Game.Tests { /// /// A connector for s that poll for new messages. From 1d2818dc70dbafecb5a60db70c9229917bdcc487 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 19:02:26 +0900 Subject: [PATCH 151/261] Reschedule ack request on completion --- osu.Game/Online/Chat/ChannelManager.cs | 32 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a9603506c6..035957a7c4 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -72,7 +72,7 @@ namespace osu.Game.Online.Chat private readonly IBindable apiState = new Bindable(); private bool channelsInitialised; - private ScheduledDelegate ackDelegate; + private ScheduledDelegate scheduledAck; public ChannelManager(IAPIProvider api) { @@ -112,16 +112,28 @@ namespace osu.Game.Online.Chat }); apiState.BindTo(api.State); - apiState.BindValueChanged(status => - { - ackDelegate?.Cancel(); + apiState.BindValueChanged(_ => performChatAckRequest(), true); + } - if (status.NewValue == APIState.Online) - { - Scheduler.Add(ackDelegate = new ScheduledDelegate(() => api.Queue(new ChatAckRequest()), 0, 60000)); - // Todo: Handle silences. - } - }, true); + private void performChatAckRequest() + { + if (apiState.Value != APIState.Online) + return; + + scheduledAck?.Cancel(); + + var req = new ChatAckRequest(); + req.Success += _ => scheduleNextRequest(); + req.Failure += _ => scheduleNextRequest(); + api.Queue(req); + + // Todo: Handle silences. + + void scheduleNextRequest() + { + scheduledAck?.Cancel(); + scheduledAck = Scheduler.AddDelayed(performChatAckRequest, 60000); + } } /// From a16540dc6d440f6a368b98ff6b474881eb77e5a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:50:52 +0900 Subject: [PATCH 152/261] Update `Nub` hover animation to better suit immediacy of sound effects --- osu.Game/Graphics/UserInterface/Nub.cs | 34 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 7a3e54ddf1..80e012f596 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -27,9 +27,6 @@ namespace osu.Game.Graphics.UserInterface private const float border_width = 3; - private const double animate_in_duration = 200; - private const double animate_out_duration = 500; - private readonly Box fill; private readonly Container main; @@ -72,7 +69,7 @@ namespace osu.Game.Graphics.UserInterface Colour = GlowColour.Opacity(0), Type = EdgeEffectType.Glow, Radius = 8, - Roundness = 5, + Roundness = 4, }; } @@ -94,13 +91,18 @@ namespace osu.Game.Graphics.UserInterface if (value) { - main.FadeColour(GlowingAccentColour, animate_in_duration, Easing.OutQuint); - main.FadeEdgeEffectTo(0.2f, animate_in_duration, Easing.OutQuint); + main.FadeColour(GlowingAccentColour.Lighten(0.5f), 40, Easing.OutQuint) + .Then() + .FadeColour(GlowingAccentColour, 800, Easing.OutQuint); + + main.FadeEdgeEffectTo(Color4.White.Opacity(0.1f), 40, Easing.OutQuint) + .Then() + .FadeEdgeEffectTo(GlowColour.Opacity(0.1f), 800, Easing.OutQuint); } else { - main.FadeEdgeEffectTo(0, animate_out_duration, Easing.OutQuint); - main.FadeColour(AccentColour, animate_out_duration, Easing.OutQuint); + main.FadeEdgeEffectTo(GlowColour.Opacity(0), 800, Easing.OutQuint); + main.FadeColour(AccentColour, 800, Easing.OutQuint); } } } @@ -163,14 +165,20 @@ namespace osu.Game.Graphics.UserInterface private void onCurrentValueChanged(ValueChangedEvent filled) { - fill.FadeTo(filled.NewValue ? 1 : 0, 200, Easing.OutQuint); + const double duration = 200; + + fill.FadeTo(filled.NewValue ? 1 : 0, duration, Easing.OutQuint); if (filled.NewValue) - main.ResizeWidthTo(1, animate_in_duration, Easing.OutElasticHalf); + { + main.ResizeWidthTo(1, duration, Easing.OutElasticHalf); + main.TransformTo(nameof(BorderThickness), filled.NewValue ? 8.5f : border_width, duration, Easing.OutElasticHalf); + } else - main.ResizeWidthTo(0.9f, animate_out_duration, Easing.OutElastic); - - main.TransformTo(nameof(BorderThickness), filled.NewValue ? 8.5f : border_width, 200, Easing.OutQuint); + { + main.ResizeWidthTo(0.75f, duration, Easing.OutQuint); + main.TransformTo(nameof(BorderThickness), border_width, duration, Easing.OutQuint); + } } } } From a2fdad4afcf8c8ee2569929ab18fd54f8bac2616 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:52:32 +0900 Subject: [PATCH 153/261] Fix slider updating glow when disabled --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 392740690a..52b907707a 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -159,7 +159,8 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(HoverEvent e) { - updateGlow(); + if (!Current.Disabled) + updateGlow(); return base.OnHover(e); } From 0e350f52f5f644402aa609df9ce20b1a693ca937 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:58:20 +0900 Subject: [PATCH 154/261] Fix `SliderBar` disabled value potentially not transferring to hover sounds --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 52b907707a..d7f308c45d 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -131,8 +131,6 @@ namespace osu.Game.Graphics.UserInterface }, hoverClickSounds = new HoverClickSounds() }; - - Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; }; } [BackgroundDependencyLoader(true)] @@ -154,7 +152,12 @@ namespace osu.Game.Graphics.UserInterface { base.LoadComplete(); CurrentNumber.BindValueChanged(current => TooltipText = getTooltipText(current.NewValue), true); - Current.DisabledChanged += disabled => hoverClickSounds.Enabled.Value = !disabled; + + Current.BindDisabledChanged(disabled => + { + Alpha = disabled ? 0.3f : 1; + hoverClickSounds.Enabled.Value = !disabled; + }, true); } protected override bool OnHover(HoverEvent e) From 78bb940e6ce5df325d399146915010439513f37f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 19:01:24 +0900 Subject: [PATCH 155/261] Don't play hover sounds on disabled elements --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 89d1570cd4..99cec7411c 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -58,6 +58,14 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(e); } + public override void PlayHoverSample() + { + if (!Enabled.Value) + return; + + base.PlayHoverSample(); + } + [BackgroundDependencyLoader] private void load(AudioManager audio) { From f12ada9d9247db0fee8cad42d7418bef011db179 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 19:36:24 +0900 Subject: [PATCH 156/261] Fix chat connecting too early --- osu.Game/Online/Chat/ChannelManager.cs | 2 ++ osu.Game/Online/HubClientConnector.cs | 3 +++ .../Online/PersistentEndpointClientConnector.cs | 13 ++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 035957a7c4..db2436333b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -111,6 +111,8 @@ namespace osu.Game.Online.Chat } }); + connector.Start(); + apiState.BindTo(api.State); apiState.BindValueChanged(_ => performChatAckRequest(), true); } diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs index 6f246f6dd3..ca6d2932f7 100644 --- a/osu.Game/Online/HubClientConnector.cs +++ b/osu.Game/Online/HubClientConnector.cs @@ -49,6 +49,9 @@ namespace osu.Game.Online this.api = api; this.versionHash = versionHash; this.preferMessagePack = preferMessagePack; + + // Automatically start these connections. + Start(); } protected override Task BuildConnectionAsync(CancellationToken cancellationToken) diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 11e8e870d6..2c4e127723 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -29,6 +29,7 @@ namespace osu.Game.Online private readonly Bindable isConnected = new Bindable(); private readonly SemaphoreSlim connectionLock = new SemaphoreSlim(1); private CancellationTokenSource connectCancelSource = new CancellationTokenSource(); + private bool started; /// /// Constructs a new . @@ -37,9 +38,19 @@ namespace osu.Game.Online protected PersistentEndpointClientConnector(IAPIProvider api) { API = api; - apiState.BindTo(api.State); + } + + /// + /// Attempts to connect and begins processing messages from the remote endpoint. + /// + public void Start() + { + if (started) + return; + apiState.BindValueChanged(_ => Task.Run(connectIfPossible), true); + started = true; } public Task Reconnect() From 20021551bb1ee3c4074075cea11da769e49e9e66 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 19:36:59 +0900 Subject: [PATCH 157/261] Fix editor selection behaviour regressions due to new path visualiser optimisation --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 36ee7c2460..434e8f5012 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -119,10 +119,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { updateVisualDefinition(); - // In the case more than a single object is selected, block hover from arriving at sliders behind this one. - // Without doing this, the path visualisers of potentially hundreds of sliders will render, which is not only - // visually noisy but also functionally useless. - return !hasSingleObjectSelected; + return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) @@ -148,7 +145,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. - if (IsSelected && (hasSingleObjectSelected || IsHovered)) + if (IsSelected && selectedObjects.Count == 1) { if (ControlPointVisualiser == null) { From d426977f038f0e83e9c15ca952433f51ac654a02 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 20:11:42 +0900 Subject: [PATCH 158/261] Handle channel joins --- .../WebSocket/WebSocketNotificationsClient.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index bc4ceea993..eefe684795 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -113,6 +113,15 @@ namespace osu.Game.Online.Notifications.WebSocket { switch (message.Event) { + case @"chat.channel.join": + Debug.Assert(message.Data != null); + + Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); + Debug.Assert(joinedChannel != null); + + HandleJoinedChannel(joinedChannel); + break; + case @"chat.message.new": Debug.Assert(message.Data != null); From 36c08b69fe2ca08cb6a20cfec9a939fa6cde8892 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 20:47:49 +0900 Subject: [PATCH 159/261] Fix failing tests --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 434e8f5012..402858b702 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } - private bool hasSingleObjectSelected => selectedObjects.Count == 1; - protected override void Update() { base.Update(); @@ -145,7 +143,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. - if (IsSelected && selectedObjects.Count == 1) + if (IsSelected && selectedObjects.Count < 2) { if (ControlPointVisualiser == null) { From bd512c493729fb0e8e5da9e3f911d3cab0169074 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 19:01:52 +0300 Subject: [PATCH 160/261] Remove equality comparison implementation from `BeatmapCard` This turned out to be a hurdle instead as it disallows adding two beatmap cards of equal beatmap, which, while being a good behaviour in client, makes tests more complicated to work. --- osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 70312a1535..b9e0a4e6cb 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public abstract class BeatmapCard : OsuClickableContainer, IEquatable + public abstract class BeatmapCard : OsuClickableContainer { public const float TRANSITION_DURATION = 400; public const float CORNER_RADIUS = 10; @@ -96,16 +96,5 @@ namespace osu.Game.Beatmaps.Drawables.Cards throw new ArgumentOutOfRangeException(nameof(size), size, @"Unsupported card size"); } } - - public bool Equals(BeatmapCard? other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - return BeatmapSet.Equals(other.BeatmapSet); - } - - public override bool Equals(object obj) => obj is BeatmapCard other && Equals(other); - public override int GetHashCode() => BeatmapSet.GetHashCode(); } } From ce5aacb76049b3e815d4ef2248190a5549f02033 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 19:05:03 +0300 Subject: [PATCH 161/261] Filter out duplicated cards using custom equality comparer instead --- osu.Game/Overlays/BeatmapListingOverlay.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index c73936da8a..32e1a00675 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -180,7 +180,7 @@ namespace osu.Game.Overlays // new results may contain beatmaps from a previous page, // this is dodgy but matches web behaviour for now. // see: https://github.com/ppy/osu-web/issues/9270 - newCards = newCards.Except(foundContent); + newCards = newCards.Except(foundContent, BeatmapCardEqualityComparer.Default); panelLoadTask = LoadComponentsAsync(newCards, loaded => { @@ -394,5 +394,21 @@ namespace osu.Game.Overlays if (shouldShowMore) filterControl.FetchNextPage(); } + + private class BeatmapCardEqualityComparer : IEqualityComparer + { + public static BeatmapCardEqualityComparer Default { get; } = new BeatmapCardEqualityComparer(); + + public bool Equals(BeatmapCard x, BeatmapCard y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + + return x.BeatmapSet.Equals(y.BeatmapSet); + } + + public int GetHashCode(BeatmapCard obj) => obj.BeatmapSet.GetHashCode(); + } } } From ee6f036c44f80f72007e281537093f30a419dbfe Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 19:35:00 +0300 Subject: [PATCH 162/261] Add note about using `ExceptBy` once it's available --- osu.Game/Overlays/BeatmapListingOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 32e1a00675..c278c9cb93 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -180,6 +180,8 @@ namespace osu.Game.Overlays // new results may contain beatmaps from a previous page, // this is dodgy but matches web behaviour for now. // see: https://github.com/ppy/osu-web/issues/9270 + // todo: replace custom equality compraer with ExceptBy in net6.0 + // newCards = newCards.ExceptBy(foundContent.Select(c => c.BeatmapSet.OnlineID), c => c.BeatmapSet.OnlineID); newCards = newCards.Except(foundContent, BeatmapCardEqualityComparer.Default); panelLoadTask = LoadComponentsAsync(newCards, loaded => From 6c819cba02ac834a2ba3b88f154082be91798525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 4 Nov 2022 19:45:36 +0100 Subject: [PATCH 163/261] Add test coverage for regressed scenarios --- .../Editor/TestSceneOsuComposerSelection.cs | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs new file mode 100644 index 0000000000..800e6c0711 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs @@ -0,0 +1,117 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; +using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Screens.Edit.Compose.Components; +using osu.Game.Tests.Beatmaps; +using osuTK; +using osuTK.Input; + +namespace osu.Game.Rulesets.Osu.Tests.Editor +{ + [TestFixture] + public class TestSceneOsuComposerSelection : TestSceneOsuEditor + { + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false); + + [Test] + public void TestContextMenuShownCorrectlyForSelectedSlider() + { + var slider = new Slider + { + StartTime = 0, + Position = new Vector2(100, 100), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100)) + } + } + }; + AddStep("add slider", () => EditorBeatmap.Add(slider)); + + moveMouseToObject(() => slider); + AddStep("left click", () => InputManager.Click(MouseButton.Left)); + AddUntilStep("slider selected", () => EditorBeatmap.SelectedHitObjects.Single() == slider); + + AddStep("move mouse to centre", () => InputManager.MoveMouseTo(blueprintContainer.ChildrenOfType().Single().ScreenSpaceDrawQuad.Centre)); + AddStep("right click", () => InputManager.Click(MouseButton.Right)); + AddUntilStep("context menu is visible", () => contextMenuContainer.ChildrenOfType().Single().State == MenuState.Open); + } + + [Test] + public void TestSelectionIncludingSliderPreservedOnClick() + { + var firstSlider = new Slider + { + StartTime = 0, + Position = new Vector2(0, 0), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100)) + } + } + }; + var secondSlider = new Slider + { + StartTime = 1000, + Position = new Vector2(100, 100), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100, -100)) + } + } + }; + var hitCircle = new HitCircle + { + StartTime = 200, + Position = new Vector2(300, 0) + }; + + AddStep("add objects", () => EditorBeatmap.AddRange(new HitObject[] { firstSlider, secondSlider, hitCircle })); + AddStep("select last 2 objects", () => EditorBeatmap.SelectedHitObjects.AddRange(new HitObject[] { secondSlider, hitCircle })); + + moveMouseToObject(() => secondSlider); + AddStep("click left mouse", () => InputManager.Click(MouseButton.Left)); + AddAssert("selection preserved", () => EditorBeatmap.SelectedHitObjects.Count == 2); + } + + private ComposeBlueprintContainer blueprintContainer + => Editor.ChildrenOfType().First(); + + private ContextMenuContainer contextMenuContainer + => Editor.ChildrenOfType().First(); + + private void moveMouseToObject(Func targetFunc) + { + AddStep("move mouse to object", () => + { + var pos = blueprintContainer.SelectionBlueprints + .First(s => s.Item == targetFunc()) + .ChildrenOfType() + .First().ScreenSpaceDrawQuad.Centre; + + InputManager.MoveMouseTo(pos); + }); + } + } +} From 23134aea612e12b666586bd5024463c7cfabd37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 4 Nov 2022 19:48:19 +0100 Subject: [PATCH 164/261] Update outdated comment --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 402858b702..3718f0c6bc 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { - // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. + // To reduce overhead of drawing these blueprints, only add extra detail when only this slider is selected. if (IsSelected && selectedObjects.Count < 2) { if (ControlPointVisualiser == null) From b8438dc788b144c30baf3c552d9333b4fe2d309c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 4 Nov 2022 20:01:21 +0100 Subject: [PATCH 165/261] Fix realm package downgrade issue in mobile projects --- osu.Android.props | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b3c48da2bf..b6ddeeb41a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -56,6 +56,6 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b5b488d82e..b2854d7ddd 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -87,6 +87,6 @@ - + From 5931e965c5818f018950cdf505fed18ae687c05b Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:16:26 +0800 Subject: [PATCH 166/261] Mark background prams in the `getMockWorkingBeatmap()` as nun-nullable because technically it should not accept the null background. --- .../Editing/Checks/CheckBackgroundQualityTest.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index 1aead6d78c..295a10ba5b 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Rendering.Dummy; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -46,7 +45,7 @@ namespace osu.Game.Tests.Editing.Checks { // While this is a problem, it is out of scope for this check and is caught by a different one. beatmap.Metadata.BackgroundFile = string.Empty; - var context = getContext(null, new MemoryStream(Array.Empty())); + var context = getContext(null!, new MemoryStream(Array.Empty())); Assert.That(check.Run(context), Is.Empty); } @@ -116,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks stream.Verify(x => x.Close(), Times.Once()); } - private BeatmapVerifierContext getContext(Texture? background, Stream? stream = null) + private BeatmapVerifierContext getContext(Texture background, Stream? stream = null) { return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object); } @@ -126,13 +125,13 @@ namespace osu.Game.Tests.Editing.Checks /// /// The texture of the background. /// The stream representing the background file. - private Mock getMockWorkingBeatmap(Texture? background, Stream? stream = null) + private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null) { stream ??= new MemoryStream(new byte[1024 * 1024]); var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Background).Returns(background.AsNonNull()); + mock.SetupGet(w => w.Background).Returns(background); mock.Setup(w => w.GetStream(It.IsAny())).Returns(stream); return mock; From 6062641bf4862f43bcc10378e741e2ab4eaf8d77 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:17:20 +0800 Subject: [PATCH 167/261] Mark mock track as nun-nullable because technically it should not accept the null track. --- osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs index 8e269cbab2..61ee6a3663 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs @@ -5,7 +5,6 @@ using System.Linq; using Moq; using NUnit.Framework; using osu.Framework.Audio.Track; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; @@ -42,7 +41,7 @@ namespace osu.Game.Tests.Editing.Checks var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Track).Returns(default(Track?).AsNonNull()); + mock.SetupGet(w => w.Track).Returns((Track)null!); Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty); } From 4d4d7cf863574619ec41902b9e5bffb181d4635d Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:41:35 +0800 Subject: [PATCH 168/261] Remove nullable disable annotation in the cache ruleset. --- .../Editor/Checks/TestCheckBananaShowerGap.cs | 4 +--- osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs b/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs index 16361d12c6..ef34a5d664 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor.Checks [TestFixture] public class TestCheckBananaShowerGap { - private CheckBananaShowerGap check; + private CheckBananaShowerGap check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs b/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs index 00fd74c9a8..4b2933c0e1 100644 --- a/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs +++ b/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Game.Beatmaps; From b0673636cae8b341d3f99a9ed6fc1318d2754341 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:44:10 +0800 Subject: [PATCH 169/261] Remove nullable disable annotation in the osu ruleset. --- .../Editor/Checks/CheckLowDiffOverlapsTest.cs | 4 +--- .../Editor/Checks/CheckOffscreenObjectsTest.cs | 4 +--- .../Editor/Checks/CheckTimeDistanceEqualityTest.cs | 4 +--- .../Editor/Checks/CheckTooShortSlidersTest.cs | 4 +--- .../Editor/Checks/CheckTooShortSpinnersTest.cs | 6 ++---- osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs | 2 -- osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs | 2 -- .../Edit/Checks/CheckTimeDistanceEquality.cs | 2 -- osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs | 2 -- osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs | 2 -- 10 files changed, 6 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs index 7a361b0821..d035d2bc17 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckLowDiffOverlapsTest { - private CheckLowDiffOverlaps check; + private CheckLowDiffOverlaps check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs index a778b76c67..a72aaa966c 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks { private static readonly Vector2 playfield_centre = OsuPlayfield.BASE_SIZE * 0.5f; - private CheckOffscreenObjects check; + private CheckOffscreenObjects check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs index 4e8be75779..348243326d 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckTimeDistanceEqualityTest { - private CheckTimeDistanceEquality check; + private CheckTimeDistanceEquality check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs index 39a9d5e798..2ec3637bb7 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckTooShortSlidersTest { - private CheckTooShortSliders check; + private CheckTooShortSliders check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs index d044ae732a..f215255bab 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -19,8 +17,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckTooShortSpinnersTest { - private CheckTooShortSpinners check; - private IBeatmapDifficultyInfo difficulty; + private CheckTooShortSpinners check = null!; + private IBeatmapDifficultyInfo difficulty = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs index 57e6a6ad1d..084a3e5ea1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs index af3521c35c..a342c2a821 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs index 753ddba710..585bd35bd9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs index 75eeb91918..159498c479 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs index 6b4dc01ab1..f0aade1b7f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks.Components; From e862ba5e04d9e5d8cb3c4b96025124fd0931ff7d Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 20:13:50 +0800 Subject: [PATCH 170/261] Fix the wrong `AsNonNull()` usage. --- osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs index 7c2b1690af..a39ef22b72 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; -using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks; @@ -73,7 +72,7 @@ namespace osu.Game.Tests.Editing.Checks private BeatmapVerifierContext getContextMissing() { var mockWorkingBeatmap = new Mock(); - mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(default(Stream?).AsNonNull()); + mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns((Stream)null!); return new BeatmapVerifierContext(beatmap, mockWorkingBeatmap.Object); } From f8684f3e76df389d16ad5f694d03a8e0e03a2838 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2022 22:43:26 +0900 Subject: [PATCH 171/261] Add script helpers to use local framework --- UseLocalFramework.ps1 | 11 +++++++++++ UseLocalFramework.sh | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 UseLocalFramework.ps1 create mode 100755 UseLocalFramework.sh diff --git a/UseLocalFramework.ps1 b/UseLocalFramework.ps1 new file mode 100644 index 0000000000..b4e240c09b --- /dev/null +++ b/UseLocalFramework.ps1 @@ -0,0 +1,11 @@ +# Run this script to use a local copy of osu-framework rather than fetching it from nuget. +# It expects the osu-framework directory to be at the same level as the osu directory +# +# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects + +$CSPROJ="osu.Game/osu.Game.csproj" +$SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Framework; +dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj; +dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj diff --git a/UseLocalFramework.sh b/UseLocalFramework.sh new file mode 100755 index 0000000000..4fd1fdfd1b --- /dev/null +++ b/UseLocalFramework.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Run this script to use a local copy of osu-framework rather than fetching it from nuget. +# It expects the osu-framework directory to be at the same level as the osu directory +# +# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects + +CSPROJ="osu.Game/osu.Game.csproj" +SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Framework +dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj +dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj + +SLNF="osu.Desktop.slnf" +tmp=$(mktemp) +jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj"]' osu.Desktop.slnf > $tmp +mv -f $tmp $SLNF From 230009570e4b3409519376fd9cc1f600dddfd16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 5 Nov 2022 16:23:12 +0100 Subject: [PATCH 172/261] Add slnf support to powershell local framework script --- UseLocalFramework.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/UseLocalFramework.ps1 b/UseLocalFramework.ps1 index b4e240c09b..837685f310 100644 --- a/UseLocalFramework.ps1 +++ b/UseLocalFramework.ps1 @@ -9,3 +9,9 @@ $SLN="osu.sln" dotnet remove $CSPROJ package ppy.osu.Framework; dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj; dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj + +$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json +$TMP=New-TemporaryFile +$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj") +ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8 +Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force From 887a3f3e2834def69ef7fa399cfd8c89444fe464 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Sat, 5 Nov 2022 19:44:25 +0100 Subject: [PATCH 173/261] Fix preposition for exclusive fullscreen prompt --- osu.Game/Localisation/LayoutSettingsStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/LayoutSettingsStrings.cs b/osu.Game/Localisation/LayoutSettingsStrings.cs index 9b8b207c47..3006361c9a 100644 --- a/osu.Game/Localisation/LayoutSettingsStrings.cs +++ b/osu.Game/Localisation/LayoutSettingsStrings.cs @@ -15,9 +15,9 @@ namespace osu.Game.Localisation public static LocalisableString CheckingForFullscreenCapabilities => new TranslatableString(getKey(@"checking_for_fullscreen_capabilities"), @"Checking for fullscreen capabilities..."); /// - /// "osu! is running exclusive fullscreen, guaranteeing low latency!" + /// "osu! is running in exclusive fullscreen, guaranteeing low latency!" /// - public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running exclusive fullscreen, guaranteeing low latency!"); + public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running in exclusive fullscreen, guaranteeing low latency!"); /// /// "Unable to run exclusive fullscreen. You'll still experience some input latency." From 51078bddf95177e266ce101d9ddccbcebdb5a533 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 6 Nov 2022 23:34:04 +0900 Subject: [PATCH 174/261] Remove unused bindable --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index f82a24ff01..15d3e63be1 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -130,7 +130,6 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Bindable comboIndexBindable = new Bindable(); private readonly Bindable positionalHitsoundsLevel = new Bindable(); - private readonly Bindable normaliseComboColourBrightness = new Bindable(); private readonly Bindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); @@ -197,7 +196,6 @@ namespace osu.Game.Rulesets.Objects.Drawables comboIndexBindable.BindValueChanged(_ => UpdateComboColour()); comboIndexWithOffsetsBindable.BindValueChanged(_ => UpdateComboColour(), true); - normaliseComboColourBrightness.BindValueChanged(_ => UpdateComboColour()); comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); // Apply transforms From e8603ede15ce9acd38cc02fff84851847291b529 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Sun, 6 Nov 2022 14:55:16 +0100 Subject: [PATCH 175/261] Fix second prompt --- osu.Game/Localisation/LayoutSettingsStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/LayoutSettingsStrings.cs b/osu.Game/Localisation/LayoutSettingsStrings.cs index 3006361c9a..a5172ec774 100644 --- a/osu.Game/Localisation/LayoutSettingsStrings.cs +++ b/osu.Game/Localisation/LayoutSettingsStrings.cs @@ -20,9 +20,9 @@ namespace osu.Game.Localisation public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running in exclusive fullscreen, guaranteeing low latency!"); /// - /// "Unable to run exclusive fullscreen. You'll still experience some input latency." + /// "Unable to run in exclusive fullscreen. You may experience some input latency." /// - public static LocalisableString UnableToRunExclusiveFullscreen => new TranslatableString(getKey(@"unable_to_run_exclusive_fullscreen"), @"Unable to run exclusive fullscreen. You'll still experience some input latency."); + public static LocalisableString UnableToRunExclusiveFullscreen => new TranslatableString(getKey(@"unable_to_run_exclusive_fullscreen"), @"Unable to run in exclusive fullscreen. You may experience some input latency."); /// /// "Using fullscreen on macOS makes interacting with the menu bar and spaces no longer work, and may lead to freezes if a system dialog is presented. Using borderless is recommended." From 75bf023f1445c4a67efc3ca66b8f783a0352f0ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 6 Nov 2022 23:35:51 +0900 Subject: [PATCH 176/261] Fix `HSPAColour.ToColour` not being pure --- osu.Game/Graphics/HSPAColour.cs | 93 +++++++++++++++++---------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/osu.Game/Graphics/HSPAColour.cs b/osu.Game/Graphics/HSPAColour.cs index 5e3bc29b7e..18f4c6bca4 100644 --- a/osu.Game/Graphics/HSPAColour.cs +++ b/osu.Game/Graphics/HSPAColour.cs @@ -96,100 +96,101 @@ namespace osu.Game.Graphics float minOverMax = 1f - S; Color4 result = new Color4 { A = A }; + float h = H; if (minOverMax > 0f) { - if (H < 1f / 6f) + if (h < 1f / 6f) { - H = 6f * (H - 0f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (h - 0f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.B = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); result.R = result.B / minOverMax; - result.G = result.B + H * (result.R - result.B); + result.G = result.B + h * (result.R - result.B); } - else if (H < 2f / 6f) + else if (h < 2f / 6f) { - H = 6f * (-H + 2f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (-h + 2f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.B = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); result.G = result.B / minOverMax; - result.R = result.B + H * (result.G - result.B); + result.R = result.B + h * (result.G - result.B); } - else if (H < 3f / 6f) + else if (h < 3f / 6f) { - H = 6f * (H - 2f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (h - 2f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.R = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); result.G = result.R / minOverMax; - result.B = result.R + H * (result.G - result.R); + result.B = result.R + h * (result.G - result.R); } - else if (H < 4f / 6f) + else if (h < 4f / 6f) { - H = 6f * (-H + 4f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (-h + 4f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.R = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); result.B = result.R / minOverMax; - result.G = result.R + H * (result.B - result.R); + result.G = result.R + h * (result.B - result.R); } - else if (H < 5f / 6f) + else if (h < 5f / 6f) { - H = 6f * (H - 4f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (h - 4f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.G = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); result.B = result.G / minOverMax; - result.R = result.G + H * (result.B - result.G); + result.R = result.G + h * (result.B - result.G); } else { - H = 6f * (-H + 6f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (-h + 6f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.G = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); result.R = result.G / minOverMax; - result.B = result.G + H * (result.R - result.G); + result.B = result.G + h * (result.R - result.G); } } else { - if (H < 1f / 6f) + if (h < 1f / 6f) { - H = 6f * (H - 0f / 6f); - result.R = MathF.Sqrt(P * P / (p_r + p_g * H * H)); - result.G = result.R * H; + h = 6f * (h - 0f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_g * h * h)); + result.G = result.R * h; result.B = 0f; } - else if (H < 2f / 6f) + else if (h < 2f / 6f) { - H = 6f * (-H + 2f / 6f); - result.G = MathF.Sqrt(P * P / (p_g + p_r * H * H)); - result.R = result.G * H; + h = 6f * (-h + 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_r * h * h)); + result.R = result.G * h; result.B = 0f; } - else if (H < 3f / 6f) + else if (h < 3f / 6f) { - H = 6f * (H - 2f / 6f); - result.G = MathF.Sqrt(P * P / (p_g + p_b * H * H)); - result.B = result.G * H; + h = 6f * (h - 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_b * h * h)); + result.B = result.G * h; result.R = 0f; } - else if (H < 4f / 6f) + else if (h < 4f / 6f) { - H = 6f * (-H + 4f / 6f); - result.B = MathF.Sqrt(P * P / (p_b + p_g * H * H)); - result.G = result.B * H; + h = 6f * (-h + 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_g * h * h)); + result.G = result.B * h; result.R = 0f; } - else if (H < 5f / 6f) + else if (h < 5f / 6f) { - H = 6f * (H - 4f / 6f); - result.B = MathF.Sqrt(P * P / (p_b + p_r * H * H)); - result.R = result.B * H; + h = 6f * (h - 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_r * h * h)); + result.R = result.B * h; result.G = 0f; } else { - H = 6f * (-H + 6f / 6f); - result.R = MathF.Sqrt(P * P / (p_r + p_b * H * H)); - result.B = result.R * H; + h = 6f * (-h + 6f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_b * h * h)); + result.B = result.R * h; result.G = 0f; } } From 700f8b04690127464440568185cc8b60954d5325 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 02:13:04 +0900 Subject: [PATCH 177/261] Remove pointless nested if conditional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Graphics/UserInterface/Nub.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 80e012f596..db3a41e303 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -172,7 +172,7 @@ namespace osu.Game.Graphics.UserInterface if (filled.NewValue) { main.ResizeWidthTo(1, duration, Easing.OutElasticHalf); - main.TransformTo(nameof(BorderThickness), filled.NewValue ? 8.5f : border_width, duration, Easing.OutElasticHalf); + main.TransformTo(nameof(BorderThickness), 8.5f, duration, Easing.OutElasticHalf); } else { From e7b543de2f32298cc47045085bd7c10d58ed9db6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 02:19:13 +0900 Subject: [PATCH 178/261] Move disabled check to apply to all calls to `updateGlow()` --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index d7f308c45d..4d3f4be8f6 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -162,8 +162,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(HoverEvent e) { - if (!Current.Disabled) - updateGlow(); + updateGlow(); return base.OnHover(e); } @@ -184,7 +183,7 @@ namespace osu.Game.Graphics.UserInterface private void updateGlow() { - Nub.Glowing = IsHovered || IsDragged; + Nub.Glowing = !Current.Disabled && (IsHovered || IsDragged); } protected override void OnUserChange(T value) From e3adf5a98502d714c6849095f257a2ad343b5038 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 11:36:55 +0900 Subject: [PATCH 179/261] Handle channel parts --- osu.Game/Online/Chat/ChannelManager.cs | 2 ++ osu.Game/Online/Notifications/NotificationsClient.cs | 3 +++ .../Online/Notifications/NotificationsClientConnector.cs | 2 ++ .../WebSocket/WebSocketNotificationsClient.cs | 9 +++++++++ 4 files changed, 16 insertions(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index db2436333b..93033dffa0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -99,6 +99,8 @@ namespace osu.Game.Online.Chat joinChannel(localChannel); }); + connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch))); + connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); connector.PresenceReceived += () => Schedule(() => diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index cb5e94fb1d..5182bfa0e5 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -18,6 +18,7 @@ namespace osu.Game.Online.Notifications public abstract class NotificationsClient : PersistentEndpointClient { public Action? ChannelJoined; + public Action? ChannelParted; public Action>? NewMessages; public Action? PresenceReceived; @@ -65,6 +66,8 @@ namespace osu.Game.Online.Notifications ChannelJoined?.Invoke(channel); } + protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); + protected void HandleMessages(List messages) { NewMessages?.Invoke(messages); diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs index d4c846a7a2..d2c2e6673c 100644 --- a/osu.Game/Online/Notifications/NotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -16,6 +16,7 @@ namespace osu.Game.Online.Notifications public abstract class NotificationsClientConnector : PersistentEndpointClientConnector { public event Action? ChannelJoined; + public event Action? ChannelParted; public event Action>? NewMessages; public event Action? PresenceReceived; @@ -29,6 +30,7 @@ namespace osu.Game.Online.Notifications var client = await BuildNotificationClientAsync(cancellationToken); client.ChannelJoined = c => ChannelJoined?.Invoke(c); + client.ChannelParted = c => ChannelParted?.Invoke(c); client.NewMessages = m => NewMessages?.Invoke(m); client.PresenceReceived = () => PresenceReceived?.Invoke(); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index eefe684795..8f4b3c2f97 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -122,6 +122,15 @@ namespace osu.Game.Online.Notifications.WebSocket HandleJoinedChannel(joinedChannel); break; + case @"chat.channel.part": + Debug.Assert(message.Data != null); + + Channel? partedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); + Debug.Assert(partedChannel != null); + + HandleChannelParted(partedChannel); + break; + case @"chat.message.new": Debug.Assert(message.Data != null); From cf03001c83a7f6317513fd283a7761427c050e72 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 11:52:07 +0900 Subject: [PATCH 180/261] Better handling for joining channels with only ID --- .../Online/API/Requests/GetChannelRequest.cs | 19 +++++++++++++ .../Requests/Responses/GetChannelResponse.cs | 19 +++++++++++++ osu.Game/Online/Chat/ChannelManager.cs | 28 +++++-------------- .../Notifications/NotificationsClient.cs | 10 +++---- .../WebSocket/WebSocketNotificationsClient.cs | 3 +- 5 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetChannelRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs diff --git a/osu.Game/Online/API/Requests/GetChannelRequest.cs b/osu.Game/Online/API/Requests/GetChannelRequest.cs new file mode 100644 index 0000000000..5bc9cb519a --- /dev/null +++ b/osu.Game/Online/API/Requests/GetChannelRequest.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetChannelRequest : APIRequest + { + private readonly long channelId; + + public GetChannelRequest(long channelId) + { + this.channelId = channelId; + } + + protected override string Target => $"chat/channels/{channelId}"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs b/osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs new file mode 100644 index 0000000000..24b886e74d --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.Chat; + +namespace osu.Game.Online.API.Requests.Responses +{ + [JsonObject(MemberSerialization.OptIn)] + public class GetChannelResponse + { + [JsonProperty(@"channel")] + public Channel Channel { get; set; } = null!; + + [JsonProperty(@"users")] + public List Users { get; set; } = null!; + } +} diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 93033dffa0..ee3194243b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -88,15 +88,14 @@ namespace osu.Game.Online.Chat { connector.ChannelJoined += ch => Schedule(() => { - var localChannel = getChannel(ch); - - if (localChannel != ch) + if (ch.Joined.Value) + JoinChannel(ch); + else { - localChannel.Joined.Value = true; - localChannel.Id = ch.Id; + var req = new GetChannelRequest(ch.Id); + req.Success += response => JoinChannel(response.Channel); + api.Queue(req); } - - joinChannel(localChannel); }); connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch))); @@ -421,20 +420,7 @@ namespace osu.Game.Online.Chat { Channel found = null; - bool lookupCondition(Channel ch) - { - // If both channels have an id, use that. - if (lookup.Id > 0 && ch.Id > 0) - return ch.Id == lookup.Id; - - // In the case that the local echo is received in a new channel (i.e. one that does not yet have an ID), - // then we need to check for any existing channel with the message containing the same message matched by UUID. - if (lookup.Messages.Count > 0 && ch.Messages.Any(m => m.Uuid == lookup.Messages.Last().Uuid)) - return true; - - // As a last resort, fallback to matching by name. - return lookup.Name == ch.Name; - } + bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : ch.Name == lookup.Name; var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 5182bfa0e5..c706124351 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -46,7 +46,10 @@ namespace osu.Game.Online.Notifications if (updates?.Presence != null) { foreach (var channel in updates.Presence) + { + channel.Joined.Value = true; HandleJoinedChannel(channel); + } //todo: handle left channels @@ -59,12 +62,7 @@ namespace osu.Game.Online.Notifications return fetchReq; } - protected void HandleJoinedChannel(Channel channel) - { - // we received this from the server so should mark the channel already joined. - channel.Joined.Value = true; - ChannelJoined?.Invoke(channel); - } + protected void HandleJoinedChannel(Channel channel) => ChannelJoined?.Invoke(channel); protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 8f4b3c2f97..71aec942ac 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -119,6 +119,7 @@ namespace osu.Game.Online.Notifications.WebSocket Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(joinedChannel != null); + joinedChannel.Joined.Value = true; HandleJoinedChannel(joinedChannel); break; @@ -138,7 +139,7 @@ namespace osu.Game.Online.Notifications.WebSocket Debug.Assert(messageData != null); foreach (var msg in messageData.Messages) - HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId, Messages = { msg } }); + HandleJoinedChannel(new Channel { Id = msg.ChannelId }); HandleMessages(messageData.Messages); break; From 391840404de144367f979f4cde1ac59475c972c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 11:59:43 +0900 Subject: [PATCH 181/261] Play exiting transition in both directions --- osu.Game/Screens/Select/SongSelect.cs | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index fe9b67a02e..4b2417aab4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -633,14 +633,32 @@ namespace osu.Game.Screens.Select transferRulesetValue(); ModSelect.SelectedMods.UnbindFrom(selectedMods); + + playExitingTransition(); + base.OnSuspending(e); + } + + public override bool OnExiting(ScreenExitEvent e) + { + if (base.OnExiting(e)) + return true; + + playExitingTransition(); + return false; + } + + private void playExitingTransition() + { ModSelect.Hide(); BeatmapOptions.Hide(); + Carousel.AllowSelection = false; + endLooping(); - FilterControl.MoveToY(-120, 250, Easing.OutQuint); - FilterControl.FadeOut(100); + FilterControl.MoveToY(-120, 500, Easing.OutQuint); + FilterControl.FadeOut(200, Easing.OutQuint); LeftArea.MoveToX(-150, 1800, Easing.OutQuint); LeftArea.FadeOut(200, Easing.OutQuint); @@ -650,24 +668,6 @@ namespace osu.Game.Screens.Select this.FadeOut(400, Easing.OutQuint); FilterControl.Deactivate(); - base.OnSuspending(e); - } - - public override bool OnExiting(ScreenExitEvent e) - { - if (base.OnExiting(e)) - return true; - - beatmapInfoWedge.Hide(); - ModSelect.Hide(); - - this.FadeOut(100); - - FilterControl.Deactivate(); - - endLooping(); - - return false; } private bool isHandlingLooping; From cd8402df72f3945f0b0b56e55691e4117badb282 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 12:11:44 +0900 Subject: [PATCH 182/261] Print event type to logs --- .../Notifications/WebSocket/WebSocketNotificationsClient.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 71aec942ac..c5b11ea94a 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -69,13 +69,14 @@ namespace osu.Game.Online.Notifications.WebSocket break; } + Logger.Log($"{GetType().ReadableName()} handling event: {message.Event}"); await onMessageReceivedAsync(message); } break; case WebSocketMessageType.Binary: - throw new NotImplementedException(); + throw new NotImplementedException("Binary message type not supported."); case WebSocketMessageType.Close: throw new Exception("Connection closed by remote host."); From f931bdc5ff502518a29e7714507245c833b307cc Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 12:25:23 +0900 Subject: [PATCH 183/261] Fix channel lookup not considering missing ids --- osu.Game/Online/Chat/ChannelManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ee3194243b..ee6e22fbc1 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -420,7 +420,13 @@ namespace osu.Game.Online.Chat { Channel found = null; - bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : ch.Name == lookup.Name; + bool lookupCondition(Channel ch) + { + if (ch.Id > 0 && lookup.Id > 0) + return ch.Id == lookup.Id; + + return ch.Name == lookup.Name; + } var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) From 6085120dc527165241c672176cf98535d788be2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 12:25:36 +0900 Subject: [PATCH 184/261] Fix incorrect handling of storyboard events with `end_time` before `start_time` --- osu.Game/Storyboards/CommandTimeline.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index d1a1edcd03..0650c97165 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -28,8 +28,7 @@ namespace osu.Game.Storyboards { if (endTime < startTime) { - (startTime, endTime) = (endTime, startTime); - (startValue, endValue) = (endValue, startValue); + endTime = startTime; } commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue }); From b977fc8181372b2d999d354b0dac21f5b17f1410 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 6 Nov 2022 18:24:54 -0800 Subject: [PATCH 185/261] Use autosize instead of max width on fixed width timestamps --- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 1 - osu.Game/Overlays/Chat/ChatLine.cs | 43 ++++++++----------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 76fcb80eb4..81db3f0d53 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -191,7 +191,6 @@ namespace osu.Game.Online.Chat { protected override float TextSize => 15; protected override float Spacing => 5; - protected override float TimestampWidth => 45; protected override float UsernameWidth => 75; public StandAloneMessage(Message message) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 4c425d3d4c..b7e3b183dc 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -48,8 +48,6 @@ namespace osu.Game.Overlays.Chat protected virtual float Spacing => 15; - protected virtual float TimestampWidth => 60; - protected virtual float UsernameWidth => 130; private Color4 usernameColour; @@ -93,38 +91,31 @@ namespace osu.Game.Overlays.Chat RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, ColumnDimensions = new[] { - new Dimension(GridSizeMode.Absolute, TimestampWidth + Spacing + UsernameWidth + Spacing), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, Spacing + UsernameWidth + Spacing), new Dimension(), }, Content = new[] { new Drawable[] { - new Container + timestamp = new OsuSpriteText { - RelativeSizeAxes = Axes.X, + Shadow = false, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), + Colour = colourProvider?.Background1 ?? Colour4.White, + AlwaysPresent = true, + }, + new MessageSender(message.Sender) + { + Width = UsernameWidth, AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - timestamp = new OsuSpriteText - { - Shadow = false, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), - MaxWidth = TimestampWidth, - Colour = colourProvider?.Background1 ?? Colour4.White, - }, - new MessageSender(message.Sender) - { - Width = UsernameWidth, - AutoSizeAxes = Axes.Y, - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - Child = createUsername(), - Margin = new MarginPadding { Horizontal = Spacing }, - }, - }, + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + Child = createUsername(), + Margin = new MarginPadding { Horizontal = Spacing }, }, ContentFlow = new LinkFlowContainer(t => { From 61ec0ba56654e121dc018f1a0b0b2e0d64f56708 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 6 Nov 2022 18:32:13 -0800 Subject: [PATCH 186/261] Make chat line timestamp adjust to 24-hour time setting --- osu.Game/Overlays/Chat/ChatLine.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index b7e3b183dc..4db02db1bc 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,6 +13,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -60,6 +62,8 @@ namespace osu.Game.Overlays.Chat private Container? highlight; + private readonly Bindable prefer24HourTime = new Bindable(); + private bool senderHasColour => !string.IsNullOrEmpty(message.Sender.Colour); private bool messageHasColour => Message.IsAction && senderHasColour; @@ -78,7 +82,7 @@ namespace osu.Game.Overlays.Chat } [BackgroundDependencyLoader] - private void load(OverlayColourProvider? colourProvider) + private void load(OverlayColourProvider? colourProvider, OsuConfigManager configManager) { usernameColour = senderHasColour ? Color4Extensions.FromHex(message.Sender.Colour) @@ -130,6 +134,8 @@ namespace osu.Game.Overlays.Chat }, } }; + + configManager.BindWith(OsuSetting.Prefer24HourTime, prefer24HourTime); } protected override void LoadComplete() @@ -138,6 +144,8 @@ namespace osu.Game.Overlays.Chat updateMessageContent(); FinishTransforms(true); + + prefer24HourTime.BindValueChanged(_ => updateTimestamp(), true); } /// @@ -167,7 +175,7 @@ namespace osu.Game.Overlays.Chat this.FadeTo(message is LocalEchoMessage ? 0.4f : 1.0f, 500, Easing.OutQuint); timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); - timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; + updateTimestamp(); username.Text = $@"{message.Sender.Username}"; // remove non-existent channels from the link list @@ -177,6 +185,13 @@ namespace osu.Game.Overlays.Chat ContentFlow.AddLinks(message.DisplayContent, message.Links); } + private void updateTimestamp() + { + timestamp.Text = prefer24HourTime.Value + ? $@"{message.Timestamp.LocalDateTime:HH:mm:ss}" + : $@"{message.Timestamp.LocalDateTime:hh:mm:ss tt}"; + } + private Drawable createUsername() { username = new OsuSpriteText From 76df61504f6ce6656a9ae01497329333aba8f659 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 6 Nov 2022 19:45:59 -0800 Subject: [PATCH 187/261] Remove unnecessary timestamp update Co-authored-by: Dean Herbert --- osu.Game/Overlays/Chat/ChatLine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 4db02db1bc..a991103fac 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Chat updateMessageContent(); FinishTransforms(true); - prefer24HourTime.BindValueChanged(_ => updateTimestamp(), true); + prefer24HourTime.BindValueChanged(_ => updateTimestamp()); } /// From f6d93fcd5a76f33ab8d18388fc73743cbed5a6c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 12:54:02 +0900 Subject: [PATCH 188/261] Fix editor hard crash when beatmap file specified out-of-range timeline zoom value --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 3a93499527..8befda82e8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -196,10 +196,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { defaultTimelineZoom = getZoomLevelForVisibleMilliseconds(6000); - float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); float minimumZoom = getZoomLevelForVisibleMilliseconds(10000); float maximumZoom = getZoomLevelForVisibleMilliseconds(500); + float initialZoom = (float)Math.Clamp(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom), minimumZoom, maximumZoom); + SetupZoom(initialZoom, minimumZoom, maximumZoom); float getZoomLevelForVisibleMilliseconds(double milliseconds) => Math.Max(1, (float)(editorClock.TrackLength / milliseconds)); From c69a4f9333016d3d20d64b7ed5889ecdeafe2734 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 14:18:43 +0900 Subject: [PATCH 189/261] Move major barline portion to default implementation to allow for further customisation Of note, this removes the "major" barline triangles from legacy skins. I think this is more correct, as they did not display in stable. --- .../Objects/Drawables/DrawableBarLine.cs | 89 ++---------------- .../Skinning/Default/DefaultBarLine.cs | 94 +++++++++++++++++++ .../Objects/Drawables/DrawableHitObject.cs | 2 +- 3 files changed, 104 insertions(+), 81 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index e4806c4a12..5bfe64c73e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -1,17 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Objects; -using osuTK; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -28,35 +23,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// private const float tracker_width = 2f; - /// - /// The vertical offset of the triangles from the line tracker. - /// - private const float triangle_offset = 10f; - - /// - /// The size of the triangles. - /// - private const float triangle_size = 20f; - - /// - /// The visual line tracker. - /// - private SkinnableDrawable line; - - /// - /// Container with triangles. Only visible for major lines. - /// - private Container triangleContainer; - - private readonly Bindable major = new Bindable(); + public readonly Bindable Major = new Bindable(); public DrawableBarLine() : this(null) { } - public DrawableBarLine([CanBeNull] BarLine barLine) - : base(barLine) + public DrawableBarLine(BarLine? barLine) + : base(barLine!) { } @@ -69,69 +44,23 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Y; Width = tracker_width; - AddRangeInternal(new Drawable[] + AddInternal(new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new DefaultBarLine()) { - line = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new Box - { - RelativeSizeAxes = Axes.Both, - EdgeSmoothness = new Vector2(0.5f, 0), - }) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - triangleContainer = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new EquilateralTriangle - { - Name = "Top", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Position = new Vector2(0, -triangle_offset), - Size = new Vector2(-triangle_size), - EdgeSmoothness = new Vector2(1), - }, - new EquilateralTriangle - { - Name = "Bottom", - Anchor = Anchor.BottomCentre, - Origin = Anchor.TopCentre, - Position = new Vector2(0, triangle_offset), - Size = new Vector2(triangle_size), - EdgeSmoothness = new Vector2(1), - } - } - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, }); } - protected override void LoadComplete() - { - base.LoadComplete(); - major.BindValueChanged(updateMajor, true); - } - - private void updateMajor(ValueChangedEvent major) - { - line.Alpha = major.NewValue ? 1f : 0.75f; - triangleContainer.Alpha = major.NewValue ? 1 : 0; - } - protected override void OnApply() { base.OnApply(); - major.BindTo(HitObject.MajorBindable); + Major.BindTo(HitObject.MajorBindable); } protected override void OnFree() { base.OnFree(); - major.UnbindFrom(HitObject.MajorBindable); + Major.UnbindFrom(HitObject.MajorBindable); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs new file mode 100644 index 0000000000..973e685bc7 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs @@ -0,0 +1,94 @@ +// 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.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Default +{ + public class DefaultBarLine : CompositeDrawable + { + /// + /// The vertical offset of the triangles from the line tracker. + /// + private const float triangle_offset = 10f; + + /// + /// The size of the triangles. + /// + private const float triangle_size = 20f; + + /// + /// Container with triangles. Only visible for major lines. + /// + private Container triangleContainer = null!; + + private Bindable major = null!; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject) + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + line = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(0.5f, 0), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + triangleContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new EquilateralTriangle + { + Name = "Top", + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Position = new Vector2(0, -triangle_offset), + Size = new Vector2(-triangle_size), + EdgeSmoothness = new Vector2(1), + }, + new EquilateralTriangle + { + Name = "Bottom", + Anchor = Anchor.BottomCentre, + Origin = Anchor.TopCentre, + Position = new Vector2(0, triangle_offset), + Size = new Vector2(triangle_size), + EdgeSmoothness = new Vector2(1), + } + } + } + }; + + major = ((DrawableBarLine)drawableHitObject).Major.GetBoundCopy(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + major.BindValueChanged(updateMajor, true); + } + + private Box line = null!; + + private void updateMajor(ValueChangedEvent major) + { + line.Alpha = major.NewValue ? 1f : 0.75f; + triangleContainer.Alpha = major.NewValue ? 1 : 0; + } + } +} diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e5150576f2..5062cbc3e6 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -736,7 +736,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { public new TObject HitObject => (TObject)base.HitObject; - protected DrawableHitObject(TObject hitObject) + protected DrawableHitObject([CanBeNull] TObject hitObject) : base(hitObject) { } From 67e99b53448c9311e9aa65543aa94aaf5db031eb Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 14:34:53 +0900 Subject: [PATCH 190/261] Lookup channels before calling HandleJoinedChannel() --- osu.Game/Online/Chat/ChannelManager.cs | 18 +++++------- .../Notifications/NotificationsClient.cs | 9 +++--- .../WebSocket/WebSocketNotificationsClient.cs | 29 ++++++++++++++++--- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ee6e22fbc1..076f79a700 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -86,17 +86,7 @@ namespace osu.Game.Online.Chat [BackgroundDependencyLoader] private void load() { - connector.ChannelJoined += ch => Schedule(() => - { - if (ch.Joined.Value) - JoinChannel(ch); - else - { - var req = new GetChannelRequest(ch.Id); - req.Success += response => JoinChannel(response.Channel); - api.Queue(req); - } - }); + connector.ChannelJoined += ch => Schedule(() => joinChannel(ch)); connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch))); @@ -446,6 +436,12 @@ namespace osu.Game.Online.Chat if (foundSelf != null) found.Users.Remove(foundSelf); } + else + { + found.Id = lookup.Id; + found.Name = lookup.Name; + found.LastMessageId = Math.Max(found.LastMessageId ?? 0, lookup.LastMessageId ?? 0); + } if (joined == null && addToJoined) joinedChannels.Add(found); if (available == null && addToAvailable) availableChannels.Add(found); diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index c706124351..e5f477bc1e 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -46,10 +46,7 @@ namespace osu.Game.Online.Notifications if (updates?.Presence != null) { foreach (var channel in updates.Presence) - { - channel.Joined.Value = true; HandleJoinedChannel(channel); - } //todo: handle left channels @@ -62,7 +59,11 @@ namespace osu.Game.Online.Notifications return fetchReq; } - protected void HandleJoinedChannel(Channel channel) => ChannelJoined?.Invoke(channel); + protected void HandleJoinedChannel(Channel channel) + { + channel.Joined.Value = true; + ChannelJoined?.Invoke(channel); + } protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index c5b11ea94a..788847d368 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Net.WebSockets; using System.Text; @@ -11,6 +12,7 @@ using Newtonsoft.Json; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Logging; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; namespace osu.Game.Online.Notifications.WebSocket @@ -22,6 +24,7 @@ namespace osu.Game.Online.Notifications.WebSocket { private readonly ClientWebSocket socket; private readonly string endpoint; + private readonly ConcurrentDictionary channelsMap = new ConcurrentDictionary(); public WebSocketNotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) : base(api) @@ -110,7 +113,7 @@ namespace osu.Game.Online.Notifications.WebSocket await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken); } - private Task onMessageReceivedAsync(SocketMessage message) + private async Task onMessageReceivedAsync(SocketMessage message) { switch (message.Event) { @@ -120,7 +123,6 @@ namespace osu.Game.Online.Notifications.WebSocket Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(joinedChannel != null); - joinedChannel.Joined.Value = true; HandleJoinedChannel(joinedChannel); break; @@ -140,13 +142,32 @@ namespace osu.Game.Online.Notifications.WebSocket Debug.Assert(messageData != null); foreach (var msg in messageData.Messages) - HandleJoinedChannel(new Channel { Id = msg.ChannelId }); + HandleJoinedChannel(await getChannel(msg.ChannelId)); HandleMessages(messageData.Messages); break; } + } - return Task.CompletedTask; + private async Task getChannel(long channelId) + { + if (channelsMap.TryGetValue(channelId, out Channel channel)) + return channel; + + var tsc = new TaskCompletionSource(); + var req = new GetChannelRequest(channelId); + + req.Success += response => + { + channelsMap[channelId] = response.Channel; + tsc.SetResult(response.Channel); + }; + + req.Failure += ex => tsc.SetException(ex); + + API.Queue(req); + + return await tsc.Task; } public override async ValueTask DisposeAsync() From fdca3c2d1c5e6d122e297bd4204b2115f081eb13 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 14:35:42 +0900 Subject: [PATCH 191/261] Rename method for consistency --- osu.Game/Online/Notifications/NotificationsClient.cs | 4 ++-- .../Notifications/WebSocket/WebSocketNotificationsClient.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index e5f477bc1e..6198707111 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -46,7 +46,7 @@ namespace osu.Game.Online.Notifications if (updates?.Presence != null) { foreach (var channel in updates.Presence) - HandleJoinedChannel(channel); + HandleChannelJoined(channel); //todo: handle left channels @@ -59,7 +59,7 @@ namespace osu.Game.Online.Notifications return fetchReq; } - protected void HandleJoinedChannel(Channel channel) + protected void HandleChannelJoined(Channel channel) { channel.Joined.Value = true; ChannelJoined?.Invoke(channel); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 788847d368..86836099d8 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -123,7 +123,7 @@ namespace osu.Game.Online.Notifications.WebSocket Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(joinedChannel != null); - HandleJoinedChannel(joinedChannel); + HandleChannelJoined(joinedChannel); break; case @"chat.channel.part": @@ -142,7 +142,7 @@ namespace osu.Game.Online.Notifications.WebSocket Debug.Assert(messageData != null); foreach (var msg in messageData.Messages) - HandleJoinedChannel(await getChannel(msg.ChannelId)); + HandleChannelJoined(await getChannel(msg.ChannelId)); HandleMessages(messageData.Messages); break; From 1975385cc74e0a9a595cb1d31af2319281aa7ee9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:21:58 +0900 Subject: [PATCH 192/261] Move first tick tracking logic inside `TickPiece` --- .../Objects/Drawables/DrawableDrumRollTick.cs | 16 +++++++--- .../Skinning/Default/TickPiece.cs | 32 ++++++++++++------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 451c5a793b..95b6384274 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -5,6 +5,7 @@ using System; using JetBrains.Annotations; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Game.Rulesets.Objects; @@ -16,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableDrumRollTick : DrawableTaikoStrongableHitObject { + public BindableBool IsFirstTick = new BindableBool(); + /// /// The hit type corresponding to the that the user pressed to hit this . /// @@ -32,14 +35,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), - _ => new TickPiece - { - Filled = HitObject.FirstTick - }); + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); public override double MaximumJudgementOffset => HitObject.HitWindow; + protected override void OnApply() + { + base.OnApply(); + + IsFirstTick.Value = HitObject.FirstTick; + } + protected override void CheckForResult(bool userTriggered, double timeOffset) { if (!userTriggered) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs index 09c8243aac..a1eaef53ba 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs @@ -1,9 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -22,20 +26,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// private const float tick_size = 0.35f; - private bool filled; - - public bool Filled - { - get => filled; - set - { - filled = value; - fillBox.Alpha = filled ? 1 : 0; - } - } - private readonly Box fillBox; + private Bindable isFirstTick = null!; + public TickPiece() { Anchor = Anchor.Centre; @@ -62,5 +56,19 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default } }; } + + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (drawableHitObject is DrawableDrumRollTick drumRollTick) + { + isFirstTick = drumRollTick.IsFirstTick.GetBoundCopy(); + isFirstTick.BindValueChanged(first => fillBox.Alpha = first.NewValue ? 1 : 0, true); + } + } } } From 8745c2f0163760942e573ddae4c940c20c2b67aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:31:06 +0900 Subject: [PATCH 193/261] Split out taiko `DefaultJudgementPiece` and move animations across --- .../Skinning/Default/DefaultJudgementPiece.cs | 32 +++++++++++++++++++ .../UI/DrawableTaikoJudgement.cs | 28 ++-------------- 2 files changed, 34 insertions(+), 26 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs new file mode 100644 index 0000000000..a8cead6877 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Taiko.Skinning.Default +{ + public class DefaultJudgementPiece : Rulesets.Judgements.DefaultJudgementPiece + { + public DefaultJudgementPiece(HitResult result) + : base(result) + { + } + + public override void PlayAnimation() + { + if (Result != HitResult.Miss) + { + this + .MoveToY(0) + .MoveToY(-100, 500); + + JudgementText + .ScaleTo(0.9f) + .ScaleTo(1, 500, Easing.OutElastic); + } + + base.PlayAnimation(); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index 876fa207bf..dcb7dc25c0 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -4,6 +4,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; +using DefaultJudgementPiece = osu.Game.Rulesets.Taiko.Skinning.Default.DefaultJudgementPiece; namespace osu.Game.Rulesets.Taiko.UI { @@ -12,31 +13,6 @@ namespace osu.Game.Rulesets.Taiko.UI /// public class DrawableTaikoJudgement : DrawableJudgement { - protected override void ApplyHitAnimations() - { - this.MoveToY(-100, 500); - base.ApplyHitAnimations(); - } - - protected override Drawable CreateDefaultJudgement(HitResult result) => new TaikoJudgementPiece(result); - - private class TaikoJudgementPiece : DefaultJudgementPiece - { - public TaikoJudgementPiece(HitResult result) - : base(result) - { - } - - public override void PlayAnimation() - { - if (Result != HitResult.Miss) - { - JudgementText.ScaleTo(0.9f); - JudgementText.ScaleTo(1, 500, Easing.OutElastic); - } - - base.PlayAnimation(); - } - } + protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultJudgementPiece(result); } } From 2b72c3833be2c8e8abc1c7dc6222914f7bea00b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 17:05:16 +0900 Subject: [PATCH 194/261] Remove unnecessary centering logic in `DrawableJudgement` --- osu.Game/Rulesets/Judgements/DrawableJudgement.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 7e1196d4ca..daf7aafd77 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -168,11 +168,7 @@ namespace osu.Game.Rulesets.Judgements RemoveInternal(JudgementBody, true); AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponent(type), _ => - CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); + CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling)); JudgementBody.OnSkinChanged += () => { From 564d0785171a4bc45398896216330506f32b2706 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 17:12:58 +0900 Subject: [PATCH 195/261] Fix much brokenness with kiai and justment sizing --- .../Skinning/Default/DefaultJudgementPiece.cs | 11 +++++++---- .../UI/DrawableTaikoJudgement.cs | 10 ++++++++++ osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 15 +++++---------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs index a8cead6877..c85a8db788 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs @@ -11,6 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default public DefaultJudgementPiece(HitResult result) : base(result) { + RelativePositionAxes = Axes.Both; } public override void PlayAnimation() @@ -18,15 +19,17 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default if (Result != HitResult.Miss) { this - .MoveToY(0) - .MoveToY(-100, 500); + .MoveToY(-0.6f) + .MoveToY(-1.5f, 500); JudgementText .ScaleTo(0.9f) .ScaleTo(1, 500, Easing.OutElastic); - } - base.PlayAnimation(); + this.FadeOutFromOne(800, Easing.OutQuint); + } + else + base.PlayAnimation(); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index dcb7dc25c0..24d2fd7be7 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -4,6 +4,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; +using osuTK; using DefaultJudgementPiece = osu.Game.Rulesets.Taiko.Skinning.Default.DefaultJudgementPiece; namespace osu.Game.Rulesets.Taiko.UI @@ -13,6 +14,15 @@ namespace osu.Game.Rulesets.Taiko.UI /// public class DrawableTaikoJudgement : DrawableJudgement { + public DrawableTaikoJudgement() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + RelativeSizeAxes = Axes.Both; + Size = Vector2.One; + } + protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultJudgementPiece(result); } } diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index c4cff00d2a..faf107de77 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.UI JudgedObject = judgedObject; this.hitType = hitType; - Anchor = Anchor.CentreLeft; + Anchor = Anchor.Centre; Origin = Anchor.Centre; RelativeSizeAxes = Axes.Both; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index cc71ba5401..d6d4a4e3f0 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -146,13 +146,16 @@ namespace osu.Game.Rulesets.Taiko.UI kiaiExplosionContainer = new Container { Name = "Kiai hit explosions", + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, }, judgementContainer = new JudgementContainer { Name = "Judgements", - RelativeSizeAxes = Axes.Y, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, }, } }, @@ -320,15 +323,7 @@ namespace osu.Game.Rulesets.Taiko.UI if (!result.Type.IsScorable()) break; - judgementContainer.Add(judgementPools[result.Type].Get(j => - { - j.Apply(result, judgedObject); - - j.Anchor = result.IsHit ? Anchor.TopLeft : Anchor.CentreLeft; - j.Origin = result.IsHit ? Anchor.BottomCentre : Anchor.Centre; - j.RelativePositionAxes = Axes.X; - j.X = result.IsHit ? judgedObject.Position.X : 0; - })); + judgementContainer.Add(judgementPools[result.Type].Get(j => j.Apply(result, judgedObject))); var type = (judgedObject.HitObject as Hit)?.Type ?? HitType.Centre; addExplosion(judgedObject, result.Type, type); From ddc2ed1542a254c619692595ac1ef7330523dc40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 13:22:01 +0900 Subject: [PATCH 196/261] Fix height of playfield in taiko tests --- .../Skinning/TestSceneDrawableBarLine.cs | 6 ++--- .../Skinning/TestSceneTaikoPlayfield.cs | 24 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs index ad6f08dbd4..a4aa0e1fad 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning var cont = new Container { RelativeSizeAxes = Axes.Both, - Height = 0.8f, + Height = 0.2f, Anchor = Anchor.Centre, Origin = Anchor.Centre, Children = new Drawable[] @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning var cont = new Container { RelativeSizeAxes = Axes.Both, - Height = 0.8f, + Height = 0.2f, Anchor = Anchor.Centre, Origin = Anchor.Centre, Children = new Drawable[] @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning var barLine = new BarLine { Major = major, - StartTime = Time.Current + 2000, + StartTime = Time.Current + 5000, }; var cpi = new ControlPointInfo(); diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index 52d24b567f..eff9f58751 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; @@ -25,11 +26,10 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning TimeRange = { Value = 5000 }, }; - public TestSceneTaikoPlayfield() + [SetUpSteps] + public void SetUpSteps() { TaikoBeatmap beatmap; - bool kiai = false; - AddStep("set beatmap", () => { Beatmap.Value = CreateWorkingBeatmap(beatmap = new TaikoBeatmap()); @@ -41,12 +41,28 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning AddStep("Load playfield", () => SetContents(_ => new TaikoPlayfield { + Height = 0.2f, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Height = 0.6f, })); + } + [Test] + public void TestBasic() + { + AddStep("do nothing", () => { }); + } + + [Test] + public void TestHeightChanges() + { AddRepeatStep("change height", () => this.ChildrenOfType().ForEach(p => p.Height = Math.Max(0.2f, (p.Height + 0.2f) % 1f)), 50); + } + + [Test] + public void TestKiai() + { + bool kiai = false; AddStep("Toggle kiai", () => { From baf8db8de4ae9a2b26d9401b02b66463ffd39cae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 15:45:32 +0900 Subject: [PATCH 197/261] Add basic setup for taiko argon skinning --- .../Argon/TaikoArgonSkinTransformer.cs | 34 +++++++++++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 4 +++ 2 files changed, 38 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs new file mode 100644 index 0000000000..13c484af24 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -0,0 +1,34 @@ +// 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.Game.Skinning; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class TaikoArgonSkinTransformer : SkinTransformer + { + public TaikoArgonSkinTransformer(ISkin skin) + : base(skin) + { + } + + public override Drawable? GetDrawableComponent(ISkinComponent component) + { + switch (component) + { + case TaikoSkinComponent catchComponent: + // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. + switch (catchComponent.Component) + { + case TaikoSkinComponents.CentreHit: + return Drawable.Empty(); + } + + break; + } + + return base.GetDrawableComponent(component); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index dc36bc0320..fe12cf9765 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -24,6 +24,7 @@ using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Rulesets.Taiko.Scoring; +using osu.Game.Rulesets.Taiko.Skinning.Argon; using osu.Game.Rulesets.Taiko.Skinning.Legacy; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; @@ -47,6 +48,9 @@ namespace osu.Game.Rulesets.Taiko { switch (skin) { + case ArgonSkin: + return new TaikoArgonSkinTransformer(skin); + case LegacySkin: return new TaikoLegacySkinTransformer(skin); } From bc0e9375afcc54b108246f6bb60e2b3e50425b82 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 16:52:09 +0900 Subject: [PATCH 198/261] Add basic argon hits --- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 21 ++++ .../Skinning/Argon/ArgonCirclePiece.cs | 116 ++++++++++++++++++ .../Skinning/Argon/ArgonRimCirclePiece.cs | 21 ++++ .../Skinning/Argon/RingPiece.cs | 40 ++++++ .../Argon/TaikoArgonSkinTransformer.cs | 5 +- 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs new file mode 100644 index 0000000000..234d9f659a --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Colour; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonCentreCirclePiece : ArgonCirclePiece + { + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(241, 0, 0, 255), + new Color4(167, 0, 0, 255) + ); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs new file mode 100644 index 0000000000..b58b7455fd --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -0,0 +1,116 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public abstract class ArgonCirclePiece : BeatSyncedContainer + { + private const double pre_beat_transition_time = 80; + + private const float flash_opacity = 0.3f; + + private ColourInfo accentColour; + + /// + /// The colour of the inner circle and outer glows. + /// + public ColourInfo AccentColour + { + get => accentColour; + set + { + accentColour = value; + ring.Colour = AccentColour.MultiplyAlpha(0.5f); + ring2.Colour = AccentColour; + } + } + + /// + /// Whether Kiai mode effects are enabled for this circle piece. + /// + public bool KiaiMode { get; set; } + + public Box FlashBox; + + private readonly RingPiece ring; + private readonly RingPiece ring2; + + protected ArgonCirclePiece() + { + RelativeSizeAxes = Axes.Both; + + EarlyActivationMilliseconds = pre_beat_transition_time; + + AddRangeInternal(new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = new Color4(0, 22, 30, 190) + }, + ring = new RingPiece(20 / 70f), + ring2 = new RingPiece(5 / 70f), + new CircularContainer + { + Name = "Flash layer", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Children = new[] + { + FlashBox = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Blending = BlendingParameters.Additive, + Alpha = 0, + AlwaysPresent = true + } + }, + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Size = new Vector2(20 / 70f), + Scale = new Vector2(0.8f, 1) + } + }); + } + + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) + { + if (!effectPoint.KiaiMode) + return; + + if (drawableHitObject.State.Value == ArmedState.Idle) + { + FlashBox + .FadeTo(flash_opacity) + .Then() + .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs new file mode 100644 index 0000000000..5dc955c56e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Colour; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonRimCirclePiece : ArgonCirclePiece + { + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(0, 161, 241, 255), + new Color4(0, 111, 167, 255) + ); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs new file mode 100644 index 0000000000..2c5d824ff5 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs @@ -0,0 +1,40 @@ +// 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.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class RingPiece : CircularContainer + { + private readonly float relativeBorderThickness; + + public RingPiece(float relativeBorderThickness) + { + this.relativeBorderThickness = relativeBorderThickness; + RelativeSizeAxes = Axes.Both; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Masking = true; + BorderColour = Color4.White; + + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both + }; + } + + protected override void Update() + { + base.Update(); + BorderThickness = relativeBorderThickness * DrawSize.X; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 13c484af24..f223d35b0a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -22,7 +22,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon switch (catchComponent.Component) { case TaikoSkinComponents.CentreHit: - return Drawable.Empty(); + return new ArgonCentreCirclePiece(); + + case TaikoSkinComponents.RimHit: + return new ArgonRimCirclePiece(); } break; From 421bdd2c1a3736c0583150deb5c585f8d64771a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 13:16:51 +0900 Subject: [PATCH 199/261] Add playfield background implementations --- .../Argon/ArgonPlayfieldBackgroundLeft.cs | 27 ++++++++++++++++++ .../Argon/ArgonPlayfieldBackgroundRight.cs | 28 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 6 ++++ 3 files changed, 61 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs new file mode 100644 index 0000000000..ebde83b607 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs @@ -0,0 +1,27 @@ +// 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.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonPlayfieldBackgroundLeft : CompositeDrawable + { + public ArgonPlayfieldBackgroundLeft() + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs new file mode 100644 index 0000000000..bd0f3ab276 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs @@ -0,0 +1,28 @@ +// 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.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonPlayfieldBackgroundRight : CompositeDrawable + { + public ArgonPlayfieldBackgroundRight() + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + new Box + { + Colour = Color4.Black, + Alpha = 0.7f, + RelativeSizeAxes = Axes.Both, + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index f223d35b0a..d2a3e19f38 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -26,6 +26,12 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.RimHit: return new ArgonRimCirclePiece(); + + case TaikoSkinComponents.PlayfieldBackgroundLeft: + return new ArgonPlayfieldBackgroundLeft(); + + case TaikoSkinComponents.PlayfieldBackgroundRight: + return new ArgonPlayfieldBackgroundRight(); } break; From f1a1f29da78de9d49de56b9fda3728ccd84453b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 13:43:04 +0900 Subject: [PATCH 200/261] Add hit target implementation --- .../Skinning/Argon/ArgonHitTarget.cs | 72 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 2 files changed, 75 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs new file mode 100644 index 0000000000..ec2eccd595 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs @@ -0,0 +1,72 @@ +// 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.Shapes; +using osu.Game.Rulesets.Taiko.Objects; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonHitTarget : CompositeDrawable + { + /// + /// Thickness of all drawn line pieces. + /// + public ArgonHitTarget() + { + RelativeSizeAxes = Axes.Both; + Masking = true; + + const float border_thickness = 4f; + + InternalChildren = new Drawable[] + { + new Circle + { + Name = "Bar Upper", + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = -border_thickness, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(border_thickness, (1 - TaikoStrongableHitObject.DEFAULT_STRONG_SIZE)), + }, + new Circle + { + Name = "Outer circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Blending = BlendingParameters.Additive, + Alpha = 0.1f, + Size = new Vector2(TaikoHitObject.DEFAULT_SIZE), + Masking = true, + }, + new Circle + { + Name = "Inner circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Blending = BlendingParameters.Additive, + Alpha = 0.1f, + Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * 0.85f), + Masking = true, + }, + new Circle + { + Name = "Bar Lower", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Y, + Y = border_thickness, + Size = new Vector2(border_thickness, (1 - TaikoStrongableHitObject.DEFAULT_STRONG_SIZE)), + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index d2a3e19f38..eec7e92511 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -32,6 +32,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.PlayfieldBackgroundRight: return new ArgonPlayfieldBackgroundRight(); + + case TaikoSkinComponents.HitTarget: + return new ArgonHitTarget(); } break; From 529e3217cfea2571d4f405836a592a988fb16a3e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 14:01:18 +0900 Subject: [PATCH 201/261] Add barline implementation --- .../Skinning/Argon/ArgonBarLine.cs | 83 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 2 files changed, 86 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs new file mode 100644 index 0000000000..402e88b64d --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs @@ -0,0 +1,83 @@ +// 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.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonBarLine : CompositeDrawable + { + private Container majorEdgeContainer = null!; + + private Bindable major = null!; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject) + { + RelativeSizeAxes = Axes.Both; + + const float line_offset = 8; + var majorPieceSize = new Vector2(6, 20); + + InternalChildren = new Drawable[] + { + line = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(0.5f, 0), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + majorEdgeContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Circle + { + Name = "Top line", + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Size = majorPieceSize, + Y = -line_offset, + }, + new Circle + { + Name = "Bottom line", + Anchor = Anchor.BottomCentre, + Origin = Anchor.TopCentre, + Size = majorPieceSize, + Y = line_offset, + }, + } + } + }; + + major = ((DrawableBarLine)drawableHitObject).Major.GetBoundCopy(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + major.BindValueChanged(updateMajor, true); + } + + private Box line = null!; + + private void updateMajor(ValueChangedEvent major) + { + line.Alpha = major.NewValue ? 1f : 0.5f; + line.Width = major.NewValue ? 1 : 0.5f; + majorEdgeContainer.Alpha = major.NewValue ? 1 : 0; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index eec7e92511..0d5c19a525 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -35,6 +35,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.HitTarget: return new ArgonHitTarget(); + + case TaikoSkinComponents.BarLine: + return new ArgonBarLine(); } break; From 66365451952639040590a7d328ce4bb8ea9853a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:07:33 +0900 Subject: [PATCH 202/261] Move taiko argon hit icon to respective centre/rim pieces --- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 13 +++++++++++++ .../Skinning/Argon/ArgonCirclePiece.cs | 11 ----------- .../Skinning/Argon/ArgonRimCirclePiece.cs | 13 +++++++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs index 234d9f659a..f347863be9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -2,7 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Sprites; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -16,6 +19,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon new Color4(241, 0, 0, 255), new Color4(167, 0, 0, 255) ); + + AddInternal(new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Size = new Vector2(20 / 70f), + Scale = new Vector2(0.8f, 1) + }); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index b58b7455fd..ba8ef12902 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -7,11 +7,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; -using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -84,15 +82,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon } }, }, - new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.Solid.AngleLeft, - Size = new Vector2(20 / 70f), - Scale = new Vector2(0.8f, 1) - } }); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs index 5dc955c56e..390f134d6f 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -2,7 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Sprites; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -16,6 +19,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon new Color4(0, 161, 241, 255), new Color4(0, 111, 167, 255) ); + + AddInternal(new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Size = new Vector2(20 / 70f), + Scale = new Vector2(0.8f, 1) + }); } } } From f1556c98e3e4ccf5fe89e92f62a8f109b73db730 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:07:47 +0900 Subject: [PATCH 203/261] Add drum roll implementation --- .../Argon/ArgonElongatedCirclePiece.cs | 33 +++++++++++++++++++ .../Skinning/Argon/RingPiece.cs | 2 +- .../Argon/TaikoArgonSkinTransformer.cs | 3 ++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs new file mode 100644 index 0000000000..f86f181b2e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonElongatedCirclePiece : ArgonCirclePiece + { + public ArgonElongatedCirclePiece() + { + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(241, 161, 0, 255), + new Color4(167, 111, 0, 255) + ); + } + + protected override void Update() + { + base.Update(); + Width = Parent.DrawSize.X + DrawHeight; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs index 2c5d824ff5..534a1c71a3 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon protected override void Update() { base.Update(); - BorderThickness = relativeBorderThickness * DrawSize.X; + BorderThickness = relativeBorderThickness * DrawSize.Y; } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 0d5c19a525..64f733a969 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -38,6 +38,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.BarLine: return new ArgonBarLine(); + + case TaikoSkinComponents.DrumRollBody: + return new ArgonElongatedCirclePiece(); } break; From 938a8f865b51e2df7b2508f3a53cb15d577292a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:11:40 +0900 Subject: [PATCH 204/261] Adjust transform of taiko drum roll ticks to not scale to 0 (looks bad) --- .../Objects/Drawables/DrawableDrumRollTick.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 95b6384274..ed89d0a14e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -74,7 +74,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (state) { case ArmedState.Hit: - this.ScaleTo(0, 100, Easing.OutQuint); + this.ScaleTo(1.4f, 200, Easing.OutQuint); + this.FadeOut(200, Easing.OutQuint); break; } } From aa61eb8f4bb61f8f51fef5edb669e62913583f02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:17:20 +0900 Subject: [PATCH 205/261] Add note about taiko pooling oversight --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index c0c80eaa4a..400c2f40b1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -133,6 +133,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override void OnApply() { base.OnApply(); + + // TODO: THIS CANNOT BE HERE, it makes pooling pointless (see https://github.com/ppy/osu/issues/21072). RecreatePieces(); } From e2046791c2aff7e07532016d8a771f5e4d3b1a3a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:39:24 +0900 Subject: [PATCH 206/261] Add argon drum roll ticks --- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonCirclePiece.cs | 2 + .../Skinning/Argon/ArgonRimCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonTickPiece.cs | 68 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs index f347863be9..551a5af078 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.AngleLeft, - Size = new Vector2(20 / 70f), + Size = new Vector2(ICON_SIZE), Scale = new Vector2(0.8f, 1) }); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index ba8ef12902..8ef7b71069 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { public abstract class ArgonCirclePiece : BeatSyncedContainer { + public const float ICON_SIZE = 20 / 70f; + private const double pre_beat_transition_time = 80; private const float flash_opacity = 0.3f; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs index 390f134d6f..fd81221be3 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.AngleLeft, - Size = new Vector2(20 / 70f), + Size = new Vector2(ICON_SIZE), Scale = new Vector2(0.8f, 1) }); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs new file mode 100644 index 0000000000..df63d4948e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs @@ -0,0 +1,68 @@ +// 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.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonTickPiece : CompositeDrawable + { + private readonly Bindable isFirstTick = new Bindable(); + + public ArgonTickPiece() + { + const float tick_size = 1 / TaikoHitObject.DEFAULT_SIZE * ArgonCirclePiece.ICON_SIZE; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fit; + Size = new Vector2(tick_size); + } + + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (drawableHitObject is DrawableDrumRollTick drumRollTick) + isFirstTick.BindTo(drumRollTick.IsFirstTick); + + isFirstTick.BindValueChanged(first => + { + if (first.NewValue) + { + InternalChild = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + }; + } + else + { + InternalChild = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Scale = new Vector2(0.8f, 1) + }; + } + }, true); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 64f733a969..6782ae67f9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -41,6 +41,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.DrumRollBody: return new ArgonElongatedCirclePiece(); + + case TaikoSkinComponents.DrumRollTick: + return new ArgonTickPiece(); } break; From 37cb187d2eb958167df1397dedda7a53a094f6b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:17:43 +0900 Subject: [PATCH 207/261] Move strong hit scale to `DefaultHitExplosion` --- osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs | 2 ++ osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index b7ba76effa..2e76396a4d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Default @@ -74,6 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default public void AnimateSecondHit() { + this.ResizeTo(new Vector2(TaikoStrongableHitObject.STRONG_SCALE), 50); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 10a7495c62..d9b6db7734 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -90,7 +90,6 @@ namespace osu.Game.Rulesets.Taiko.UI { using (BeginAbsoluteSequence(secondHitTime.Value)) { - this.ResizeTo(new Vector2(TaikoStrongableHitObject.DEFAULT_STRONG_SIZE), 50); (skinnable.Drawable as IAnimatableHitExplosion)?.AnimateSecondHit(); } } From d5c375b139f135e9ffc49ae4c9e67f8979b07865 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:18:03 +0900 Subject: [PATCH 208/261] Add argon hit explosion implementation --- .../Skinning/Argon/ArgonHitExplosion.cs | 87 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 9 ++ 2 files changed, 96 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs new file mode 100644 index 0000000000..05bb9bcb9a --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs @@ -0,0 +1,87 @@ +// 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 osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.UI; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonHitExplosion : CompositeDrawable, IAnimatableHitExplosion + { + private readonly TaikoSkinComponents component; + private readonly Circle outer; + + public ArgonHitExplosion(TaikoSkinComponents component) + { + this.component = component; + + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + outer = new Circle + { + Name = "Outer circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical( + new Color4(255, 227, 236, 255), + new Color4(255, 198, 211, 255) + ), + Masking = true, + }, + new Circle + { + Name = "Inner circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Size = new Vector2(0.85f), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(255, 132, 191, 255).Opacity(0.5f), + Radius = 45, + }, + Masking = true, + }, + }; + } + + public void Animate(DrawableHitObject drawableHitObject) + { + this.FadeOut(); + + switch (component) + { + case TaikoSkinComponents.TaikoExplosionGreat: + this.FadeIn(30, Easing.In) + .Then() + .FadeOut(450, Easing.OutQuint); + break; + + case TaikoSkinComponents.TaikoExplosionOk: + this.FadeTo(0.2f, 30, Easing.In) + .Then() + .FadeOut(200, Easing.OutQuint); + break; + } + } + + public void AnimateSecondHit() + { + outer.ResizeTo(new Vector2(TaikoStrongableHitObject.STRONG_SCALE), 500, Easing.OutQuint); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 6782ae67f9..3b75cfff11 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -44,6 +44,15 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.DrumRollTick: return new ArgonTickPiece(); + + case TaikoSkinComponents.TaikoExplosionKiai: + // the drawable needs to expire as soon as possible to avoid accumulating empty drawables on the playfield. + return Drawable.Empty().With(d => d.Expire()); + + case TaikoSkinComponents.TaikoExplosionGreat: + case TaikoSkinComponents.TaikoExplosionMiss: + case TaikoSkinComponents.TaikoExplosionOk: + return new ArgonHitExplosion(catchComponent.Component); } break; From b15d1bc333c9a379c56e0bd7466a4b7795b9fc77 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:31:24 +0900 Subject: [PATCH 209/261] Add argon result display implementation --- .../Skinning/Argon/ArgonJudgementPiece.cs | 198 ++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 4 + 2 files changed, 202 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs new file mode 100644 index 0000000000..0ea0473023 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -0,0 +1,198 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Utils; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + { + protected readonly HitResult Result; + + protected SpriteText JudgementText { get; private set; } = null!; + + private RingExplosion? ringExplosion; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + public ArgonJudgementPiece(HitResult result) + { + Result = result; + RelativePositionAxes = Axes.Both; + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + JudgementText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = Result.GetDescription().ToUpperInvariant(), + Colour = colours.ForHitResult(Result), + Blending = BlendingParameters.Additive, + Spacing = new Vector2(10, 0), + RelativePositionAxes = Axes.Both, + Font = OsuFont.Default.With(size: 20, weight: FontWeight.Regular), + }, + }; + + if (Result.IsHit()) + { + AddInternal(ringExplosion = new RingExplosion(Result) + { + Colour = colours.ForHitResult(Result), + RelativePositionAxes = Axes.Y, + }); + } + } + + /// + /// Plays the default animation for this judgement piece. + /// + /// + /// The base implementation only handles fade (for all result types) and misses. + /// Individual rulesets are recommended to implement their appropriate hit animations. + /// + public virtual void PlayAnimation() + { + const double duration = 800; + + switch (Result) + { + default: + JudgementText.MoveToY(-0.2f) + .MoveToY(-0.8f, duration, Easing.OutQuint); + + JudgementText + .ScaleTo(Vector2.One) + .ScaleTo(new Vector2(1.8f), duration, Easing.OutQuint); + break; + + case HitResult.Miss: + this.ScaleTo(1.6f); + this.ScaleTo(1, 100, Easing.In); + + JudgementText.MoveTo(Vector2.Zero); + JudgementText.MoveToOffset(new Vector2(0, 100), duration, Easing.InQuint); + + this.RotateTo(0); + this.RotateTo(40, duration, Easing.InQuint); + break; + } + + this.FadeOutFromOne(duration, Easing.OutQuint); + + ringExplosion?.PlayAnimation(); + } + + public Drawable? GetAboveHitObjectsProxiedContent() => null; + + private class RingExplosion : CompositeDrawable + { + private readonly float travel = 58; + + public RingExplosion(HitResult result) + { + const float thickness = 4; + + const float small_size = 9; + const float large_size = 14; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Blending = BlendingParameters.Additive; + + int countSmall = 0; + int countLarge = 0; + + switch (result) + { + case HitResult.Meh: + countSmall = 3; + travel *= 0.3f; + break; + + case HitResult.Ok: + case HitResult.Good: + countSmall = 4; + travel *= 0.6f; + break; + + case HitResult.Great: + case HitResult.Perfect: + countSmall = 4; + countLarge = 4; + break; + } + + for (int i = 0; i < countSmall; i++) + AddInternal(new RingPiece(thickness) { Size = new Vector2(small_size) }); + + for (int i = 0; i < countLarge; i++) + AddInternal(new RingPiece(thickness) { Size = new Vector2(large_size) }); + } + + public void PlayAnimation() + { + foreach (var c in InternalChildren) + { + const float start_position_ratio = 0.6f; + + float direction = RNG.NextSingle(0, 360); + float distance = RNG.NextSingle(travel / 2, travel); + + c.MoveTo(new Vector2( + MathF.Cos(direction) * distance * start_position_ratio, + MathF.Sin(direction) * distance * start_position_ratio + )); + + c.MoveTo(new Vector2( + MathF.Cos(direction) * distance, + MathF.Sin(direction) * distance + ), 600, Easing.OutQuint); + } + + this.FadeOutFromOne(1000, Easing.OutQuint); + } + + public class RingPiece : CircularContainer + { + public RingPiece(float thickness = 9) + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Masking = true; + BorderThickness = thickness; + BorderColour = Color4.White; + + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both + }; + } + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 3b75cfff11..a6e053f0df 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; +using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -17,6 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { switch (component) { + case GameplaySkinComponent resultComponent: + return new ArgonJudgementPiece(resultComponent.Component); + case TaikoSkinComponent catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) From d57ec4b227331f6264671cfb6776261aca76c4a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 17:29:27 +0900 Subject: [PATCH 210/261] Add argon input drum implementation --- .../Skinning/Argon/ArgonInputDrum.cs | 218 ++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 2 files changed, 221 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs new file mode 100644 index 0000000000..528e75aabb --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs @@ -0,0 +1,218 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Screens.Ranking; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonInputDrum : AspectContainer + { + private const float rim_size = 0.3f; + + public ArgonInputDrum() + { + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + const float middle_split = 6; + + InternalChild = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.9f), + Children = new Drawable[] + { + new TaikoHalfDrum(false) + { + Name = "Left Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + RimAction = TaikoAction.LeftRim, + CentreAction = TaikoAction.LeftCentre + }, + new TaikoHalfDrum(true) + { + Name = "Right Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + RimAction = TaikoAction.RightRim, + CentreAction = TaikoAction.RightCentre + }, + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + Children = new Drawable[] + { + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = OsuColour.Gray(38 / 255f), + Width = middle_split, + RelativeSizeAxes = Axes.Y, + }, + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = OsuColour.Gray(48 / 255f), + Width = middle_split, + Height = 1 - rim_size, + RelativeSizeAxes = Axes.Y, + }, + }, + } + } + }; + } + + /// + /// A half-drum. Contains one centre and one rim hit. + /// + private class TaikoHalfDrum : CompositeDrawable, IKeyBindingHandler + { + /// + /// The key to be used for the rim of the half-drum. + /// + public TaikoAction RimAction; + + /// + /// The key to be used for the centre of the half-drum. + /// + public TaikoAction CentreAction; + + private readonly Drawable rimHit; + private readonly Drawable centreHit; + + public TaikoHalfDrum(bool flipped) + { + Anchor anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight; + + Masking = true; + + Anchor = anchor; + Origin = anchor; + + RelativeSizeAxes = Axes.Both; + // Extend maskable region for glow. + Height = 2f; + + InternalChildren = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Children = new[] + { + new Circle + { + Anchor = anchor, + Colour = OsuColour.Gray(51 / 255f), + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + }, + rimHit = new Circle + { + Anchor = anchor, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal( + new Color4(227, 248, 255, 255), + new Color4(198, 245, 255, 255) + ), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(126, 215, 253, 170), + Radius = 50, + }, + Alpha = 0, + }, + new Circle + { + Anchor = anchor, + Origin = Anchor.Centre, + Colour = OsuColour.Gray(64 / 255f), + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1 - rim_size) + }, + centreHit = new Circle + { + Anchor = anchor, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal( + new Color4(255, 227, 236, 255), + new Color4(255, 198, 211, 255) + ), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(255, 147, 199, 255), + Radius = 50, + }, + Size = new Vector2(1 - rim_size), + Alpha = 0, + } + }, + }, + }; + } + + public bool OnPressed(KeyBindingPressEvent e) + { + Drawable? target = null; + + if (e.Action == CentreAction) + target = centreHit; + else if (e.Action == RimAction) + target = rimHit; + + if (target != null) + { + const float alpha_amount = 0.5f; + + const float down_time = 40; + const float up_time = 750; + + target.Animate( + t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint) + ).Then( + t => t.FadeOut(up_time, Easing.OutQuint) + ); + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index a6e053f0df..f0d14f657d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -37,6 +37,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.PlayfieldBackgroundRight: return new ArgonPlayfieldBackgroundRight(); + case TaikoSkinComponents.InputDrum: + return new ArgonInputDrum(); + case TaikoSkinComponents.HitTarget: return new ArgonHitTarget(); From de2dac22b86fea188daa886a01e65adcf136e2cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 18:46:04 +0900 Subject: [PATCH 211/261] Ensure seeding screen is refreshed on entering --- .../Screens/TeamIntro/SeedingScreen.cs | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index 9262cab098..8bc28e1068 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -70,16 +70,16 @@ namespace osu.Game.Tournament.Screens.TeamIntro currentTeam.BindValueChanged(teamChanged, true); } - private void teamChanged(ValueChangedEvent team) => Scheduler.AddOnce(() => - { - if (team.NewValue == null) - { - mainContainer.Clear(); - return; - } + private void teamChanged(ValueChangedEvent team) => updateTeamDisplay(); - showTeam(team.NewValue); - }); + public override void Show() + { + base.Show(); + + // Changes could have been made on editor screen. + // Rather than trying to track all the possibilities (teams / players / scores) just force a full refresh. + updateTeamDisplay(); + } protected override void CurrentMatchChanged(ValueChangedEvent match) { @@ -91,14 +91,20 @@ namespace osu.Game.Tournament.Screens.TeamIntro currentTeam.Value = match.NewValue.Team1.Value; } - private void showTeam(TournamentTeam team) + private void updateTeamDisplay() => Scheduler.AddOnce(() => { + if (currentTeam.Value == null) + { + mainContainer.Clear(); + return; + } + mainContainer.Children = new Drawable[] { - new LeftInfo(team) { Position = new Vector2(55, 150), }, - new RightInfo(team) { Position = new Vector2(500, 150), }, + new LeftInfo(currentTeam.Value) { Position = new Vector2(55, 150), }, + new RightInfo(currentTeam.Value) { Position = new Vector2(500, 150), }, }; - } + }); private class RightInfo : CompositeDrawable { From 64f9d6c8916d13e225e7631b8662793d7edb3220 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 19:03:56 +0900 Subject: [PATCH 212/261] Fix potential cross-thread drawable operation in round editor screen --- osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 1b670f4b69..0bd5ddb257 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -256,7 +256,7 @@ namespace osu.Game.Tournament.Screens.Editors mods.BindValueChanged(modString => Model.Mods = modString.NewValue); } - private void updatePanel() + private void updatePanel() => Schedule(() => { drawableContainer.Clear(); @@ -269,7 +269,7 @@ namespace osu.Game.Tournament.Screens.Editors Width = 300 }; } - } + }); } } } From d77b6b3603e5a302efe8c960427516106f78e985 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 19:04:06 +0900 Subject: [PATCH 213/261] Fix seeding screen buttons crashing the game if no match is selected --- .../Screens/TeamIntro/SeedingScreen.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index 8bc28e1068..ba75b6a2ed 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -26,6 +26,9 @@ namespace osu.Game.Tournament.Screens.TeamIntro private readonly Bindable currentTeam = new Bindable(); + private TourneyButton showFirstTeamButton; + private TourneyButton showSecondTeamButton; + [BackgroundDependencyLoader] private void load() { @@ -46,13 +49,13 @@ namespace osu.Game.Tournament.Screens.TeamIntro { Children = new Drawable[] { - new TourneyButton + showFirstTeamButton = new TourneyButton { RelativeSizeAxes = Axes.X, Text = "Show first team", Action = () => currentTeam.Value = CurrentMatch.Value.Team1.Value, }, - new TourneyButton + showSecondTeamButton = new TourneyButton { RelativeSizeAxes = Axes.X, Text = "Show second team", @@ -86,7 +89,14 @@ namespace osu.Game.Tournament.Screens.TeamIntro base.CurrentMatchChanged(match); if (match.NewValue == null) + { + showFirstTeamButton.Enabled.Value = false; + showSecondTeamButton.Enabled.Value = false; return; + } + + showFirstTeamButton.Enabled.Value = true; + showSecondTeamButton.Enabled.Value = true; currentTeam.Value = match.NewValue.Team1.Value; } From 1e2e0dea74fbbdf53b0eb04a5913b6bdd4f15a52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 19:04:19 +0900 Subject: [PATCH 214/261] Ensure seeding results get beatmaps populated if `BeatmapIno` model is null --- osu.Game.Tournament/TournamentGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 1861e39c60..98ba3ca60f 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -238,7 +238,7 @@ namespace osu.Game.Tournament var beatmapsRequiringPopulation = ladder.Teams .SelectMany(r => r.SeedingResults) .SelectMany(r => r.Beatmaps) - .Where(b => b.Beatmap?.OnlineID == 0 && b.ID > 0).ToList(); + .Where(b => (b.Beatmap == null || b.Beatmap.OnlineID == 0) && b.ID > 0).ToList(); if (beatmapsRequiringPopulation.Count == 0) return false; From 7ee9018a94c0e2bfb81c9fca6d3a067d1075f437 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 8 Nov 2022 03:18:12 +0300 Subject: [PATCH 215/261] Always display menu cursor when game is not focused --- .../Graphics/Cursor/MenuCursorContainer.cs | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index af542989ff..adc0f81daf 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -70,7 +70,8 @@ namespace osu.Game.Graphics.Cursor private OsuGame? game { get; set; } private readonly IBindable lastInputWasMouse = new BindableBool(); - private readonly IBindable isIdle = new BindableBool(); + private readonly IBindable gameActive = new BindableBool(true); + private readonly IBindable gameIdle = new BindableBool(); protected override void LoadComplete() { @@ -81,8 +82,11 @@ namespace osu.Game.Graphics.Cursor if (game != null) { - isIdle.BindTo(game.IsIdle); - isIdle.BindValueChanged(_ => updateState()); + gameIdle.BindTo(game.IsIdle); + gameIdle.BindValueChanged(_ => updateState()); + + gameActive.BindTo(game.IsActive); + gameActive.BindValueChanged(_ => updateState()); } } @@ -90,7 +94,7 @@ namespace osu.Game.Graphics.Cursor private void updateState() { - bool combinedVisibility = State.Value == Visibility.Visible && (lastInputWasMouse.Value || !hideCursorOnNonMouseInput) && !isIdle.Value; + bool combinedVisibility = getCursorVisibility(); if (visible == combinedVisibility) return; @@ -103,6 +107,27 @@ namespace osu.Game.Graphics.Cursor PopOut(); } + private bool getCursorVisibility() + { + // do not display when explicitly set to hidden state. + if (State.Value == Visibility.Hidden) + return false; + + // only hide cursor when game is focused, otherwise it should always be displayed. + if (gameActive.Value) + { + // do not display when last input is not mouse. + if (hideCursorOnNonMouseInput && !lastInputWasMouse.Value) + return false; + + // do not display when game is idle. + if (gameIdle.Value) + return false; + } + + return true; + } + protected override void Update() { base.Update(); From 8568520c33db332cb21d479342e334809ee49104 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Tue, 8 Nov 2022 01:34:06 +0100 Subject: [PATCH 216/261] Fix `Prefer24HourTime` default value Will use the system culture so it always matches the rest of the OS. --- osu.Game/Configuration/OsuConfigManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 093eaa0f31..5137214d62 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; -using System.Globalization; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; @@ -115,7 +114,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.MenuParallax, true); // See https://stackoverflow.com/a/63307411 for default sourcing. - SetDefault(OsuSetting.Prefer24HourTime, CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); + SetDefault(OsuSetting.Prefer24HourTime, !CultureInfoHelper.SystemCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); // Gameplay SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); From 3af48352c98e1602b55fee988482122b2e2fbcba Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 8 Nov 2022 04:05:06 +0300 Subject: [PATCH 217/261] Fix taiko major barlines no longer rendering correctly --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index cc71ba5401..f2d7811f44 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -60,8 +60,9 @@ namespace osu.Game.Rulesets.Taiko.UI /// private BarLinePlayfield barLinePlayfield; - private Container playfieldContent; - private Container playfieldOverlay; + private Container barLineContent; + private Container hitObjectContent; + private Container overlayContent; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -121,22 +122,20 @@ namespace osu.Game.Rulesets.Taiko.UI } } }, - new Container + barLineContent = new Container + { + Name = "Bar line content", + RelativeSizeAxes = Axes.Both, + Child = barLinePlayfield = new BarLinePlayfield(), + }, + hitObjectContent = new Container { Name = "Masked hit objects content", RelativeSizeAxes = Axes.Both, Masking = true, - Child = playfieldContent = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - barLinePlayfield = new BarLinePlayfield(), - HitObjectContainer, - } - } + Child = HitObjectContainer, }, - playfieldOverlay = new Container + overlayContent = new Container { Name = "Elements after hit objects", RelativeSizeAxes = Axes.Both, @@ -215,8 +214,9 @@ namespace osu.Game.Rulesets.Taiko.UI // Padding is required to be updated for elements which are based on "absolute" X sized elements. // This is basically allowing for correct alignment as relative pieces move around them. rightArea.Padding = new MarginPadding { Left = inputDrum.Width }; - playfieldContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; - playfieldOverlay.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; + barLineContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; + hitObjectContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; + overlayContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT); } From 2163cd212b57a1fb7e2156621973bde5251ea4e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 12:03:25 +0900 Subject: [PATCH 218/261] Automatically close settings and notification overlays when opening main overlay Closes #21162. --- osu.Game/OsuGame.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4f8098136f..0015de7da1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1006,6 +1006,9 @@ namespace osu.Game if (overlay.IsPresent) return; + Settings.Hide(); + Notifications.Hide(); + // Show above all other overlays. if (overlay.IsLoaded) overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); From b764d1bd0469f8136c4abc4c30683117f3d67d99 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 13:29:25 +0900 Subject: [PATCH 219/261] Decode variables earlier in flow in case they include indent logic Without this change, the `depth` calculation could be incorrect. --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index b8f60f0bc6..4d407bb5f0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -79,6 +79,8 @@ namespace osu.Game.Beatmaps.Formats private void handleEvents(string line) { + decodeVariables(ref line); + int depth = 0; foreach (char c in line) @@ -91,8 +93,6 @@ namespace osu.Game.Beatmaps.Formats line = line.Substring(depth); - decodeVariables(ref line); - string[] split = line.Split(','); if (depth == 0) From 064a245c50c4e3a92e2fcbf87e7dc014864322ab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 13:30:11 +0900 Subject: [PATCH 220/261] Don't trim whitespace from variable keys / values --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 12 +++++++++--- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index ed7ca47cfd..6991500df5 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -130,14 +130,20 @@ namespace osu.Game.Beatmaps.Formats } } - protected KeyValuePair SplitKeyVal(string line, char separator = ':') + protected KeyValuePair SplitKeyVal(string line, char separator = ':', bool shouldTrim = true) { string[] split = line.Split(separator, 2); + if (shouldTrim) + { + for (int i = 0; i < split.Length; i++) + split[i] = split[i].Trim(); + } + return new KeyValuePair ( - split[0].Trim(), - split.Length > 1 ? split[1].Trim() : string.Empty + split[0], + split.Length > 1 ? split[1] : string.Empty ); } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 4d407bb5f0..2b4f377ab6 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -349,7 +349,7 @@ namespace osu.Game.Beatmaps.Formats private void handleVariables(string line) { - var pair = SplitKeyVal(line, '='); + var pair = SplitKeyVal(line, '=', false); variables[pair.Key] = pair.Value; } From 0b343404472d26ecbe243e7529a8615d5dd961ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 14:34:28 +0900 Subject: [PATCH 221/261] Fix sprites not displaying in storyboard if filename extension is missing in script --- osu.Game/Storyboards/Storyboard.cs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 473f1ce97f..8133244e89 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.IO; using System.Linq; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -89,12 +90,31 @@ namespace osu.Game.Storyboards public DrawableStoryboard CreateDrawable(IReadOnlyList? mods = null) => new DrawableStoryboard(this, mods); + private static readonly string[] image_extensions = { @".png", @".jpg" }; + public Texture? GetTextureFromPath(string path, TextureStore textureStore) { - string? storyboardPath = BeatmapInfo.BeatmapSet?.GetPathForFile(path); + string? resolvedPath = null; - if (!string.IsNullOrEmpty(storyboardPath)) - return textureStore.Get(storyboardPath); + if (Path.HasExtension(path)) + { + resolvedPath = BeatmapInfo.BeatmapSet?.GetPathForFile(path); + } + else + { + // Just doing this extension logic locally here for simplicity. + // + // A more "sane" path may be to use the ISkinSource.GetTexture path (which will use the extensions of the underlying TextureStore), + // but comes with potential complexity (what happens if the user has beatmap skins disabled?). + foreach (string ext in image_extensions) + { + if ((resolvedPath = BeatmapInfo.BeatmapSet?.GetPathForFile($"{path}{ext}")) != null) + break; + } + } + + if (!string.IsNullOrEmpty(resolvedPath)) + return textureStore.Get(resolvedPath); return null; } From b9374cae55ade91632302f64eacef6bf9ab9f64a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 14:38:02 +0900 Subject: [PATCH 222/261] Hide settings/notifications regardless of `IsPresent` state of new overlay --- osu.Game/OsuGame.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0015de7da1..7476324e11 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1002,13 +1002,13 @@ namespace osu.Game { otherOverlays.Where(o => o != overlay).ForEach(o => o.Hide()); + Settings.Hide(); + Notifications.Hide(); + // Partially visible so leave it at the current depth. if (overlay.IsPresent) return; - Settings.Hide(); - Notifications.Hide(); - // Show above all other overlays. if (overlay.IsLoaded) overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); From 4c157946941a26b1ecab092c826390dd741c3342 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 14:58:52 +0900 Subject: [PATCH 223/261] Add test coverage of overlay interplay --- .../Navigation/TestSceneScreenNavigation.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8fce43f9b0..e69bdfb7ac 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -513,6 +513,40 @@ namespace osu.Game.Tests.Visual.Navigation AddWaitStep("wait two frames", 2); } + [Test] + public void TestMainOverlaysClosesNotificationOverlay() + { + ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); + + AddUntilStep("Wait for options to load", () => Game.Notifications.IsLoaded); + AddStep("Show notifications", () => Game.Notifications.Show()); + AddUntilStep("wait for notifications shown", () => Game.Notifications.IsPresent && Game.Notifications.State.Value == Visibility.Visible); + AddStep("Show changelog listing", () => Game.ShowChangelogListing()); + AddUntilStep("wait for changelog shown", () => getChangelogOverlay()?.IsPresent == true && getChangelogOverlay()?.State.Value == Visibility.Visible); + AddAssert("Notifications is hidden", () => Game.Notifications.State.Value == Visibility.Hidden); + + AddStep("Show notifications", () => Game.Notifications.Show()); + AddUntilStep("wait for notifications shown", () => Game.Notifications.State.Value == Visibility.Visible); + AddUntilStep("changelog still visible", () => getChangelogOverlay().State.Value == Visibility.Visible); + } + + [Test] + public void TestMainOverlaysClosesSettingsOverlay() + { + ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); + + AddUntilStep("Wait for options to load", () => Game.Settings.IsLoaded); + AddStep("Show settings", () => Game.Settings.Show()); + AddUntilStep("wait for settings shown", () => Game.Settings.IsPresent && Game.Settings.State.Value == Visibility.Visible); + AddStep("Show changelog listing", () => Game.ShowChangelogListing()); + AddUntilStep("wait for changelog shown", () => getChangelogOverlay()?.IsPresent == true && getChangelogOverlay()?.State.Value == Visibility.Visible); + AddAssert("Settings is hidden", () => Game.Settings.State.Value == Visibility.Hidden); + + AddStep("Show settings", () => Game.Settings.Show()); + AddUntilStep("wait for settings shown", () => Game.Settings.State.Value == Visibility.Visible); + AddUntilStep("changelog still visible", () => getChangelogOverlay().State.Value == Visibility.Visible); + } + [Test] public void TestOverlayClosing() { From 01803c3f13f0a46907401a5b1a3b670944d1ff09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 15:08:52 +0900 Subject: [PATCH 224/261] Adjust judgement text to be more visible --- .../Skinning/Argon/ArgonJudgementPiece.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs index 0ea0473023..baaf9e41e2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -78,12 +78,12 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon switch (Result) { default: - JudgementText.MoveToY(-0.2f) - .MoveToY(-0.8f, duration, Easing.OutQuint); + JudgementText.MoveToY(-0.6f) + .MoveToY(-1.0f, duration, Easing.OutQuint); JudgementText .ScaleTo(Vector2.One) - .ScaleTo(new Vector2(1.8f), duration, Easing.OutQuint); + .ScaleTo(new Vector2(1.4f), duration, Easing.OutQuint); break; case HitResult.Miss: From aa7d0e2c9699743d220828962d7a2c63d4433e57 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 15:19:08 +0900 Subject: [PATCH 225/261] Remove triangles skin specific implementation from base `DrawableHit` --- .../Objects/Drawables/DrawableHit.cs | 5 +--- .../Skinning/Default/CirclePiece.cs | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 484f125a09..02ac054b52 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -201,12 +201,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables break; case ArmedState.Hit: - // If we're far enough away from the left stage, we should bring outselves in front of it + // If we're far enough away from the left stage, we should bring ourselves in front of it ProxyContent(); - var flash = (MainPiece.Drawable as CirclePiece)?.FlashBox; - flash?.FadeTo(0.9f).FadeOut(300); - const float gravity_time = 300; const float gravity_travel_height = 200; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 6b5a9ae6d2..e8edf94e76 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default private readonly Container background; - public Box FlashBox; + private readonly Box flashBox; protected CirclePiece() { @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default Masking = true, Children = new[] { - FlashBox = new Box + flashBox = new Box { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -144,6 +144,25 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default }); } + protected override void LoadComplete() + { + base.LoadComplete(); + + drawableHitObject.ApplyCustomUpdateState += updateStateTransforms; + updateStateTransforms(drawableHitObject, drawableHitObject.State.Value); + } + + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + { + switch (state) + { + case ArmedState.Hit: + using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) + flashBox?.FadeTo(0.9f).FadeOut(300); + break; + } + } + private const float edge_alpha_kiai = 0.5f; private void resetEdgeEffects() @@ -166,7 +185,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default if (drawableHitObject.State.Value == ArmedState.Idle) { - FlashBox + flashBox .FadeTo(flash_opacity) .Then() .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); From 30890644a8c417119199de6f24fcd63cd366543b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 15:21:20 +0900 Subject: [PATCH 226/261] Flash piece when hit --- .../Skinning/Argon/ArgonCirclePiece.cs | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index 8ef7b71069..91f34e1f0e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; @@ -33,17 +32,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon set { accentColour = value; + ring.Colour = AccentColour.MultiplyAlpha(0.5f); ring2.Colour = AccentColour; } } - /// - /// Whether Kiai mode effects are enabled for this circle piece. - /// - public bool KiaiMode { get; set; } + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; - public Box FlashBox; + private readonly Drawable flash; private readonly RingPiece ring; private readonly RingPiece ring2; @@ -59,36 +57,43 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon new Circle { RelativeSizeAxes = Axes.Both, - Colour = new Color4(0, 22, 30, 190) + Colour = new Color4(0, 0, 0, 190) }, ring = new RingPiece(20 / 70f), ring2 = new RingPiece(5 / 70f), - new CircularContainer + flash = new Circle { Name = "Flash layer", Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] - { - FlashBox = new Box - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - Blending = BlendingParameters.Additive, - Alpha = 0, - AlwaysPresent = true - } - }, + Blending = BlendingParameters.Additive, + Alpha = 0, }, }); } - [Resolved] - private DrawableHitObject drawableHitObject { get; set; } = null!; + protected override void LoadComplete() + { + base.LoadComplete(); + + drawableHitObject.ApplyCustomUpdateState += updateStateTransforms; + updateStateTransforms(drawableHitObject, drawableHitObject.State.Value); + } + + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + { + switch (state) + { + case ArmedState.Hit: + using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) + { + flash.FadeTo(0.9f).FadeOut(500, Easing.OutQuint); + } + + break; + } + } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { @@ -97,7 +102,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon if (drawableHitObject.State.Value == ArmedState.Idle) { - FlashBox + flash .FadeTo(flash_opacity) .Then() .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); From 349d262c1820d5056282bc2a3a2014a6535a17af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 18:05:22 +0900 Subject: [PATCH 227/261] Remove commented unbind --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 990152471a..df3c1f7ec4 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -667,9 +667,9 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { - //b.DimAmount.UnbindAll(); b.DimWhenUserSettingsIgnored.Value = 0; }); + resetTrack(); refetchBeatmap(); From 9650ae1329b07cf8801601186d4dae91c1fe7929 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 17:20:37 +0900 Subject: [PATCH 228/261] Limit editor background dim to 75% maximum --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Screens/Edit/BackgroundDimMenuItem.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3c619d2ddd..fccd1a8715 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -121,7 +121,6 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); - SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); @@ -172,6 +171,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); + SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f); SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs index b8644ed690..b5a33f06e7 100644 --- a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -23,7 +23,6 @@ namespace osu.Game.Screens.Edit createMenuItem(0.25f), createMenuItem(0.5f), createMenuItem(0.75f), - createMenuItem(1f), }; this.backgroudDim = backgroudDim; From ada039151b80f73d678161ec0f10f13f0c79ffab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 18:07:06 +0900 Subject: [PATCH 229/261] Add the ability to toggle off hit marker displays in the editor --- .../Components/HitCircleOverlapMarker.cs | 50 +++++++++++++------ .../Edit/Blueprints/OsuSelectionBlueprint.cs | 2 +- osu.Game/Configuration/OsuConfigManager.cs | 2 + .../Edit/HitObjectSelectionBlueprint.cs | 14 ++++++ osu.Game/Screens/Edit/Editor.cs | 6 +++ 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs index 71cdbc276e..f16b6c138e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs @@ -4,9 +4,12 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Skinning.Default; @@ -27,31 +30,45 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components private readonly RingPiece ring; + private readonly Container content; + [Resolved] private EditorClock editorClock { get; set; } + private Bindable showHitMarkers; + public HitCircleOverlapMarker() { Origin = Anchor.Centre; Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - InternalChildren = new Drawable[] + InternalChild = content = new Container { - new Circle + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - }, - ring = new RingPiece - { - BorderThickness = 4, + new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + ring = new RingPiece + { + BorderThickness = 4, + } } }; } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + showHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers); + } + [Resolved] private ISkinSource skin { get; set; } @@ -68,21 +85,26 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components double hitObjectTime = hitObject.StartTime; bool hasReachedObject = editorTime >= hitObjectTime; - if (hasReachedObject) + if (hasReachedObject && showHitMarkers.Value) { float alpha = Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION, Easing.In); float ringScale = MathHelper.Clamp(Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION / 2, Easing.OutQuint), 0, 1); ring.Scale = new Vector2(1 + 0.1f * ringScale); - Alpha = 0.9f * (1 - alpha); + content.Alpha = 0.9f * (1 - alpha); } else - Alpha = 0; + content.Alpha = 0; + } + + public override void Show() + { + // intentional no op so SelectionBlueprint Selection/Deselection logic doesn't touch us. } public override void Hide() { - // intentional no op so we are not hidden when not selected. + // intentional no op so SelectionBlueprint Selection/Deselection logic doesn't touch us. } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs index 422287918e..11527c9537 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints protected override bool AlwaysShowWhenSelected => true; protected override bool ShouldBeAlive => base.ShouldBeAlive - || (editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION); + || (ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION); protected OsuSelectionBlueprint(T hitObject) : base(hitObject) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index fccd1a8715..2aa369cf78 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -173,6 +173,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f); SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); + SetDefault(OsuSetting.EditorShowHitMarkers, true); SetDefault(OsuSetting.LastProcessedMetadataId, -1); } @@ -367,5 +368,6 @@ namespace osu.Game.Configuration ShowOnlineExplicitContent, LastProcessedMetadataId, SafeAreaConsiderations, + EditorShowHitMarkers } } diff --git a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs index c74fb83d58..408fbfc04f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs @@ -3,7 +3,10 @@ #nullable disable +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics.Primitives; +using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; @@ -23,6 +26,11 @@ namespace osu.Game.Rulesets.Edit /// protected virtual bool AlwaysShowWhenSelected => false; + /// + /// Whether extra animations should be shown to convey hit position / state in addition to gameplay animations. + /// + protected Bindable ShowHitMarkers { get; private set; } + protected override bool ShouldBeAlive => (DrawableObject?.IsAlive == true && DrawableObject.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected); protected HitObjectSelectionBlueprint(HitObject hitObject) @@ -30,6 +38,12 @@ namespace osu.Game.Rulesets.Edit { } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + ShowHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers); + } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos); public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index df3c1f7ec4..7f94370bb2 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -176,6 +176,7 @@ namespace osu.Game.Screens.Edit private OnScreenDisplay onScreenDisplay { get; set; } private Bindable editorBackgroundDim; + private Bindable editorHitMarkers; public Editor(EditorLoader loader = null) { @@ -262,6 +263,7 @@ namespace osu.Game.Screens.Edit OsuMenuItem redoMenuItem; editorBackgroundDim = config.GetBindable(OsuSetting.EditorDim); + editorHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers); AddInternal(new OsuContextMenuContainer { @@ -316,6 +318,10 @@ namespace osu.Game.Screens.Edit { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), new BackgroundDimMenuItem(editorBackgroundDim), + new ToggleMenuItem("Show hit markers") + { + State = { BindTarget = editorHitMarkers }, + } } } } From dd4cd3cf8e5be9f5c413efa67be780a2a931e08c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 18:24:57 +0900 Subject: [PATCH 230/261] Move gameplay configuration to interface to allow editor overriding --- osu.Game/Configuration/IGameplaySettings.cs | 23 +++++++++++++++++++ osu.Game/Configuration/OsuConfigManager.cs | 6 ++++- osu.Game/OsuGameBase.cs | 1 + .../Objects/Drawables/DrawableHitObject.cs | 10 ++++---- 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Configuration/IGameplaySettings.cs diff --git a/osu.Game/Configuration/IGameplaySettings.cs b/osu.Game/Configuration/IGameplaySettings.cs new file mode 100644 index 0000000000..a35bdd20d0 --- /dev/null +++ b/osu.Game/Configuration/IGameplaySettings.cs @@ -0,0 +1,23 @@ +// 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.Bindables; + +namespace osu.Game.Configuration +{ + /// + /// A settings provider which generally sources from (global user settings) + /// but can allow overriding settings by caching more locally. For instance, in the editor. + /// + /// + /// More settings can be moved into this interface as required. + /// + [Cached] + public interface IGameplaySettings + { + IBindable ComboColourNormalisationAmount { get; } + + IBindable PositionalHitsoundsLevel { get; } + } +} diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index fdaad8cf70..1286a07eeb 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; using System.Globalization; +using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; @@ -27,7 +28,7 @@ using osu.Game.Skinning; namespace osu.Game.Configuration { [ExcludeFromDynamicCompile] - public class OsuConfigManager : IniConfigManager + public class OsuConfigManager : IniConfigManager, IGameplaySettings { public OsuConfigManager(Storage storage) : base(storage) @@ -276,6 +277,9 @@ namespace osu.Game.Configuration public Func LookupSkinName { private get; set; } = _ => @"unknown"; public Func LookupKeyBindings { get; set; } = _ => @"unknown"; + + IBindable IGameplaySettings.ComboColourNormalisationAmount => GetOriginalBindable(OsuSetting.ComboColourNormalisationAmount); + IBindable IGameplaySettings.PositionalHitsoundsLevel => GetOriginalBindable(OsuSetting.PositionalHitsoundsLevel); } // IMPORTANT: These are used in user configuration files. diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 511f492b8a..1d5f5a75e5 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -262,6 +262,7 @@ namespace osu.Game dependencies.Cache(largeStore); dependencies.CacheAs(LocalConfig); + dependencies.CacheAs(LocalConfig); InitialiseFonts(); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 15d3e63be1..6795a07cb4 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -129,8 +129,8 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly BindableList samplesBindable = new BindableList(); private readonly Bindable comboIndexBindable = new Bindable(); - private readonly Bindable positionalHitsoundsLevel = new Bindable(); - private readonly Bindable comboColourBrightness = new Bindable(); + private readonly IBindable positionalHitsoundsLevel = new Bindable(); + private readonly IBindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); protected override bool RequiresChildrenUpdate => true; @@ -171,10 +171,10 @@ namespace osu.Game.Rulesets.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, ISkinSource skinSource) + private void load(IGameplaySettings gameplaySettings, ISkinSource skinSource) { - config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.ComboColourNormalisationAmount, comboColourBrightness); + positionalHitsoundsLevel.BindTo(gameplaySettings.PositionalHitsoundsLevel); + comboColourBrightness.BindTo(gameplaySettings.ComboColourNormalisationAmount); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); From 4448fcb3c876241428f2015f51f35a735fe21740 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 18:28:48 +0900 Subject: [PATCH 231/261] Override combo colour brightness normalisation setting only in editor --- osu.Game/Screens/Edit/Editor.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 912681e114..65d2371551 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -59,7 +59,8 @@ namespace osu.Game.Screens.Edit { [Cached(typeof(IBeatSnapProvider))] [Cached] - public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider + public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider, + IGameplaySettings { public override float BackgroundParallaxAmount => 0.1f; @@ -99,6 +100,9 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private INotificationOverlay notifications { get; set; } + [Resolved] + private IGameplaySettings globalGameplaySettings { get; set; } + public readonly Bindable Mode = new Bindable(); public IBindable SamplePlaybackDisabled => samplePlaybackDisabled; @@ -1031,5 +1035,11 @@ namespace osu.Game.Screens.Edit { } } + + // Combo colour normalisation should not be applied in the editor. + IBindable IGameplaySettings.ComboColourNormalisationAmount => new Bindable(); + + // Arguable. + IBindable IGameplaySettings.PositionalHitsoundsLevel => globalGameplaySettings.PositionalHitsoundsLevel; } } From 710c224de45988649feca86275669b0e2c607d55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:18:24 +0900 Subject: [PATCH 232/261] Remove unused `IHasMainCirclePiece` interface --- .../Objects/Drawables/DrawableHitCircle.cs | 2 +- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 3 +-- .../Skinning/Default/IHasMainCirclePiece.cs | 14 -------------- 4 files changed, 3 insertions(+), 18 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 841a52da7b..d420091499 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableHitCircle : DrawableOsuHitObject, IHasMainCirclePiece, IHasApproachCircle + public class DrawableHitCircle : DrawableOsuHitObject, IHasApproachCircle { public OsuAction? HitAction => HitArea.HitAction; protected virtual OsuSkinComponents CirclePieceComponent => OsuSkinComponents.HitCircle; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 7b9c0c7e40..a02cc9227e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking, IHasMainCirclePiece + public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking { public new SliderRepeat HitObject => (SliderRepeat)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index 063d297f5a..6270d6709b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -10,13 +10,12 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Skinning; using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, IHasMainCirclePiece + public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking { public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs deleted file mode 100644 index 0ba7998d43..0000000000 --- a/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using osu.Game.Skinning; - -namespace osu.Game.Rulesets.Osu.Skinning.Default -{ - public interface IHasMainCirclePiece - { - SkinnableDrawable CirclePiece { get; } - } -} From 5e7dc34d05c5a6ab644d88bbf7e014c012505b7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:23:53 +0900 Subject: [PATCH 233/261] Move some non-default skin files to correct namespace --- osu.Game.Rulesets.Osu/Skinning/{Default => }/SliderBody.cs | 3 ++- .../Skinning/{Default => }/SnakingSliderBody.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename osu.Game.Rulesets.Osu/Skinning/{Default => }/SliderBody.cs (97%) rename osu.Game.Rulesets.Osu/Skinning/{Default => }/SnakingSliderBody.cs (99%) diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs similarity index 97% rename from osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs rename to osu.Game.Rulesets.Osu/Skinning/SliderBody.cs index 9841cc7cdf..1411b27c09 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs @@ -8,10 +8,11 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; +using osu.Game.Rulesets.Osu.Skinning.Default; using osuTK; using osuTK.Graphics; -namespace osu.Game.Rulesets.Osu.Skinning.Default +namespace osu.Game.Rulesets.Osu.Skinning { public abstract class SliderBody : CompositeDrawable { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs similarity index 99% rename from osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs rename to osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs index 86dd5f5c74..a4a3316927 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osuTK; -namespace osu.Game.Rulesets.Osu.Skinning.Default +namespace osu.Game.Rulesets.Osu.Skinning { /// /// A which changes its curve depending on the snaking progress. From 20b8ab324fcd92129c501e12ebb189cdca9ca02d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:36:46 +0900 Subject: [PATCH 234/261] Apply nullability to osu!taiko skinning classes --- .../Skinning/Default/CentreHitCirclePiece.cs | 2 -- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 8 +++----- .../Skinning/Default/DefaultInputDrum.cs | 5 ++--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs index 958f4b3a17..339ab35795 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 6b5a9ae6d2..72809ffd57 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; @@ -36,6 +34,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default private const float flash_opacity = 0.3f; + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + private Color4 accentColour; /// @@ -156,9 +157,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default }; } - [Resolved] - private DrawableHitObject drawableHitObject { get; set; } - protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { if (!effectPoint.KiaiMode) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs index fa60d209e7..3d0578dbc0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.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. -#nullable disable using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -135,8 +134,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default public bool OnPressed(KeyBindingPressEvent e) { - Drawable target = null; - Drawable back = null; + Drawable? target = null; + Drawable? back = null; if (e.Action == CentreAction) { From 82ff142b1b379de24550f314241ddbc82965d4c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:36:52 +0900 Subject: [PATCH 235/261] Apply nullability to osu! skinning classes --- osu.Game.Rulesets.Osu/OsuSkinComponent.cs | 2 -- osu.Game.Rulesets.Osu/OsuSkinComponents.cs | 2 -- .../Skinning/Default/CirclePiece.cs | 9 +++---- .../Skinning/Default/DefaultApproachCircle.cs | 4 +-- .../Skinning/Default/DefaultSpinner.cs | 17 ++++++------- .../Skinning/Default/DefaultSpinnerDisc.cs | 17 ++++++------- .../Skinning/Default/DrawableSliderPath.cs | 2 -- .../Skinning/Default/ExplodePiece.cs | 9 +++---- .../Skinning/Default/FlashPiece.cs | 2 -- .../Skinning/Default/GlowPiece.cs | 2 -- .../Skinning/Default/KiaiFlash.cs | 2 -- .../Skinning/Default/MainCirclePiece.cs | 7 +++--- .../Skinning/Default/ManualSliderBody.cs | 2 -- .../Skinning/Default/NumberPiece.cs | 2 -- .../Skinning/Default/PlaySliderBody.cs | 6 ++--- .../Skinning/Default/ReverseArrowPiece.cs | 4 +-- .../Default/SpinnerBackgroundLayer.cs | 2 -- .../Skinning/Default/SpinnerCentreLayer.cs | 10 +++----- .../Skinning/Default/SpinnerFill.cs | 2 -- .../Default/SpinnerRotationTracker.cs | 25 +++++++++---------- .../Skinning/Default/SpinnerSpmCalculator.cs | 7 +++--- .../Skinning/Default/SpinnerTicks.cs | 2 -- .../Skinning/Default/TrianglesPiece.cs | 2 -- .../Skinning/IHasApproachCircle.cs | 4 +-- .../Skinning/Legacy/LegacyApproachCircle.cs | 4 +-- .../Skinning/Legacy/LegacyCursor.cs | 2 -- .../Skinning/Legacy/LegacyCursorParticles.cs | 18 ++++++------- .../Skinning/Legacy/LegacyCursorTrail.cs | 9 +++---- .../Skinning/Legacy/LegacyNewStyleSpinner.cs | 14 +++++------ .../Skinning/Legacy/LegacyOldStyleSpinner.cs | 8 +++--- .../Skinning/Legacy/LegacyReverseArrow.cs | 6 ++--- .../Skinning/Legacy/LegacySliderBody.cs | 2 -- .../Legacy/LegacySliderHeadHitCircle.cs | 6 ++--- .../Skinning/Legacy/LegacySpinner.cs | 23 ++++++++--------- .../Legacy/OsuLegacySkinTransformer.cs | 6 ++--- .../Skinning/NonPlayfieldSprite.cs | 4 +-- .../Skinning/OsuSkinColour.cs | 2 -- .../Skinning/OsuSkinConfiguration.cs | 2 -- .../Skinning/SnakingSliderBody.cs | 8 +++--- 39 files changed, 94 insertions(+), 163 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs index 0abaf2c924..aa59bd572e 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs index 4248cce55a..8fdf3821fa 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Osu { public enum OsuSkinComponents diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs index 40e9f69963..4a679cda2c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -17,9 +16,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public class CirclePiece : CompositeDrawable { [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; - private TrianglesPiece triangles; + private TrianglesPiece triangles = null!; public CirclePiece() { @@ -72,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableObject != null) + if (drawableObject.IsNotNull()) drawableObject.HitObjectApplied -= onHitObjectApplied; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index 251fd8d948..e991bc6cf3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly IBindable accentColour = new Bindable(); [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; public DefaultApproachCircle() : base("Gameplay/osu/approachcircle") diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs index a215b3b1f0..a975030630 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -18,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { public class DefaultSpinner : CompositeDrawable { - private DrawableSpinner drawableSpinner; + private DrawableSpinner drawableSpinner = null!; - private OsuSpriteText bonusCounter; + private OsuSpriteText bonusCounter = null!; - private Container spmContainer; - private OsuSpriteText spmCounter; + private Container spmContainer = null!; + private OsuSpriteText spmCounter = null!; public DefaultSpinner() { @@ -81,8 +80,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default }); } - private IBindable gainedBonus; - private IBindable spinsPerMinute; + private IBindable gainedBonus = null!; + private IBindable spinsPerMinute = null!; protected override void LoadComplete() { @@ -135,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs index 60489c1b22..b58daf7174 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Utils; @@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { public class DefaultSpinnerDisc : CompositeDrawable { - private DrawableSpinner drawableSpinner; + private DrawableSpinner drawableSpinner = null!; private const float initial_scale = 1.3f; private const float idle_alpha = 0.2f; @@ -30,15 +29,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private Color4 normalColour; private Color4 completeColour; - private SpinnerTicks ticks; + private SpinnerTicks ticks = null!; private int wholeRotationCount; private readonly BindableBool complete = new BindableBool(); - private SpinnerFill fill; - private Container mainContainer; - private SpinnerCentreLayer centre; - private SpinnerBackgroundLayer background; + private SpinnerFill fill = null!; + private Container mainContainer = null!; + private SpinnerCentreLayer centre = null!; + private SpinnerBackgroundLayer background = null!; public DefaultSpinnerDisc() { @@ -214,7 +213,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs index e3a83a9280..883524f334 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Lines; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs index 6ee8a12132..f8010a9971 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -15,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public class ExplodePiece : Container { [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; - private TrianglesPiece triangles; + private TrianglesPiece triangles = null!; public ExplodePiece() { @@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableObject != null) + if (drawableObject.IsNotNull()) drawableObject.HitObjectApplied -= onHitObjectApplied; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs index 98a8b39f6f..06ee64d8b3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs index 2360bc2238..f5e01b802e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs index a1cfd170a6..506f679836 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Audio.Track; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs index 4acc406ae1..6d56d21349 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -46,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly IBindable indexInCurrentCombo = new Bindable(); [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -113,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableObject != null) + if (drawableObject.IsNotNull()) drawableObject.ApplyCustomUpdateState -= updateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs index 8d8d9e0d94..d73c94eb9b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osuTK; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index f6759c1093..43d8d1e27f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs index 6c422cf127..96af59abe2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Rulesets.Objects.Drawables; @@ -20,10 +18,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default protected IBindable AccentColourBindable { get; private set; } = null!; - private IBindable pathVersion; + private IBindable pathVersion = null!; [Resolved(CanBeNull = true)] - private OsuRulesetConfigManager config { get; set; } + private OsuRulesetConfigManager? config { get; set; } private readonly Bindable configSnakingOut = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 8f682d02f6..1fce512f53 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; @@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public class ReverseArrowPiece : BeatSyncedContainer { [Resolved] - private DrawableHitObject drawableRepeat { get; set; } + private DrawableHitObject drawableRepeat { get; set; } = null!; public ReverseArrowPiece() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs index a9b7ddf86f..a1184a15cd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs index ef7b4c2c96..3dd5aed6ae 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -19,11 +17,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { public class SpinnerCentreLayer : CompositeDrawable, IHasAccentColour { - private DrawableSpinner spinner; + private DrawableSpinner spinner = null!; - private CirclePiece circle; - private GlowPiece glow; - private SpriteIcon symbol; + private CirclePiece circle = null!; + private GlowPiece glow = null!; + private SpriteIcon symbol = null!; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject) diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs index b7ec9e9799..f574ae589e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs index 97cebc3123..3a9f73404d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; @@ -23,6 +22,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly DrawableSpinner drawableSpinner; + private Vector2 mousePosition; + + private float lastAngle; + private float currentRotation; + + private bool rotationTransferred; + + [Resolved(canBeNull: true)] + private IGameplayClock? gameplayClock { get; set; } + public SpinnerRotationTracker(DrawableSpinner drawableSpinner) { this.drawableSpinner = drawableSpinner; @@ -51,16 +60,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default return base.OnMouseMove(e); } - private Vector2 mousePosition; - - private float lastAngle; - private float currentRotation; - - private bool rotationTransferred; - - [Resolved(canBeNull: true)] - private IGameplayClock gameplayClock { get; set; } - protected override void Update() { base.Update(); @@ -126,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.HitObjectApplied -= resetState; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs index df72223214..9feaa0966a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Utils; using osu.Game.Rulesets.Objects.Drawables; @@ -26,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly Bindable result = new BindableDouble(); [Resolved] - private DrawableHitObject drawableSpinner { get; set; } + private DrawableHitObject drawableSpinner { get; set; } = null!; protected override void LoadComplete() { @@ -66,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.HitObjectApplied -= resetState; } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs index b66cbe41b6..e518ae1da8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Extensions.Color4Extensions; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs index 7399ddbd1b..fa23c60d57 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Graphics.Backgrounds; namespace osu.Game.Rulesets.Osu.Skinning.Default diff --git a/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs index 8ebab97503..5ddca03fa1 100644 --- a/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; namespace osu.Game.Rulesets.Osu.Skinning @@ -15,6 +13,6 @@ namespace osu.Game.Rulesets.Osu.Skinning /// /// The approach circle drawable. /// - Drawable ApproachCircle { get; } + Drawable? ApproachCircle { get; } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index 03406d37ff..fa5c5b84e4 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private readonly IBindable accentColour = new Bindable(); [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; public LegacyApproachCircle() : base("Gameplay/osu/approachcircle") diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs index 4465f9c266..b2ffc171be 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Osu.UI.Cursor; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs index ee75b8a857..a28b480753 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -27,19 +25,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { public class LegacyCursorParticles : CompositeDrawable, IKeyBindingHandler { - public bool Active => breakSpewer?.Active.Value == true || kiaiSpewer?.Active.Value == true; + public bool Active => breakSpewer.Active.Value || kiaiSpewer.Active.Value; - private LegacyCursorParticleSpewer breakSpewer; - private LegacyCursorParticleSpewer kiaiSpewer; + private LegacyCursorParticleSpewer breakSpewer = null!; + private LegacyCursorParticleSpewer kiaiSpewer = null!; [Resolved(canBeNull: true)] - private Player player { get; set; } + private Player? player { get; set; } [Resolved(canBeNull: true)] - private OsuPlayfield playfield { get; set; } + private OsuPlayfield? playfield { get; set; } [Resolved(canBeNull: true)] - private GameplayState gameplayState { get; set; } + private GameplayState? gameplayState { get; set; } [BackgroundDependencyLoader] private void load(ISkinSource skin) @@ -79,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { if (playfield == null || gameplayState == null) return; - DrawableHitObject kiaiHitObject = null; + DrawableHitObject? kiaiHitObject = null; // Check whether currently in a kiai section first. This is only done as an optimisation to avoid enumerating AliveObjects when not necessary. if (gameplayState.Beatmap.ControlPointInfo.EffectPointAt(Time.Current).KiaiMode) @@ -152,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy protected override bool CanSpawnParticles => base.CanSpawnParticles && cursorScreenPosition.HasValue; protected override float ParticleGravity => 240; - public LegacyCursorParticleSpewer(Texture texture, int perSecond) + public LegacyCursorParticleSpewer(Texture? texture, int perSecond) : base(texture, perSecond, particle_duration_max) { Active.BindValueChanged(_ => resetVelocityCalculation()); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs index e62754c6ce..9a59fd73b2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -22,7 +20,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private bool disjointTrail; private double lastTrailTime; - private IBindable cursorSize; + + private IBindable cursorSize = null!; private Vector2? currentPosition; @@ -34,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + cursorSize = config.GetBindable(OsuSetting.GameplayCursorSize).GetBoundCopy(); + Texture = skin.GetTexture("cursortrail"); disjointTrail = skin.GetTexture("cursormiddle") == null; @@ -54,8 +55,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy // stable "magic ratio". see OsuPlayfieldAdjustmentContainer for full explanation. Texture.ScaleAdjust *= 1.6f; } - - cursorSize = config.GetBindable(OsuSetting.GameplayCursorSize).GetBoundCopy(); } protected override double FadeDuration => disjointTrail ? 150 : 500; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs index 71c3e4c9f0..f950d3e43e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -23,15 +21,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy /// public class LegacyNewStyleSpinner : LegacySpinner { - private Sprite glow; - private Sprite discBottom; - private Sprite discTop; - private Sprite spinningMiddle; - private Sprite fixedMiddle; + private Sprite glow = null!; + private Sprite discBottom = null!; + private Sprite discTop = null!; + private Sprite spinningMiddle = null!; + private Sprite fixedMiddle = null!; private readonly Color4 glowColour = new Color4(3, 151, 255, 255); - private Container scaleContainer; + private Container scaleContainer = null!; [BackgroundDependencyLoader] private void load(ISkinSource source) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs index a5a765fc02..e5efb668bc 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -23,9 +21,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy /// public class LegacyOldStyleSpinner : LegacySpinner { - private Sprite disc; - private Sprite metreSprite; - private Container metre; + private Sprite disc = null!; + private Sprite metreSprite = null!; + private Container metre = null!; private bool spinnerBlink; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index ff384ee7fc..7e9626eb7f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -16,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy public class LegacyReverseArrow : CompositeDrawable { [Resolved(canBeNull: true)] - private DrawableHitObject drawableHitObject { get; set; } + private DrawableHitObject? drawableHitObject { get; set; } - private Drawable proxy; + private Drawable proxy = null!; [BackgroundDependencyLoader] private void load(ISkinSource skinSource) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs index dbfec14eb2..29a0745193 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Extensions.Color4Extensions; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs index ab39d7c6ef..08b579697c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -14,9 +12,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy public class LegacySliderHeadHitCircle : LegacyMainCirclePiece { [Resolved(canBeNull: true)] - private DrawableHitObject drawableHitObject { get; set; } + private DrawableHitObject? drawableHitObject { get; set; } - private Drawable proxiedOverlayLayer; + private Drawable proxiedOverlayLayer = null!; public LegacySliderHeadHitCircle() : base("sliderstartcircle") diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs index a817e5f2b7..66b195962b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -32,17 +31,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private const float spm_hide_offset = 50f; - protected DrawableSpinner DrawableSpinner { get; private set; } + protected DrawableSpinner DrawableSpinner { get; private set; } = null!; - public Drawable ApproachCircle { get; protected set; } + public Drawable? ApproachCircle { get; protected set; } - private Sprite spin; - private Sprite clear; + private Sprite spin = null!; + private Sprite clear = null!; - private LegacySpriteText bonusCounter; + private LegacySpriteText bonusCounter = null!; - private Sprite spmBackground; - private LegacySpriteText spmCounter; + private Sprite spmBackground = null!; + private LegacySpriteText spmCounter = null!; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject, ISkinSource source) @@ -108,8 +107,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy }); } - private IBindable gainedBonus; - private IBindable spinsPerMinute; + private IBindable gainedBonus = null!; + private IBindable spinsPerMinute = null!; private readonly Bindable completed = new Bindable(); @@ -207,7 +206,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.Dispose(isDisposing); - if (DrawableSpinner != null) + if (DrawableSpinner.IsNotNull()) DrawableSpinner.ApplyCustomUpdateState -= UpdateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 856ccb5044..3bc2668733 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -30,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null); } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (component is OsuSkinComponent osuComponent) { @@ -145,7 +143,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return base.GetDrawableComponent(component); } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { switch (lookup) { diff --git a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs index 0b45c770ba..2a13f07cdb 100644 --- a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs +++ b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets.UI; @@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Skinning /// public class NonPlayfieldSprite : Sprite { - public override Texture Texture + public override Texture? Texture { get => base.Texture; set diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs index 5d8a2ff606..24f9217a5f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Osu.Skinning { public enum OsuSkinColour diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 1c0a62454b..77fea9d8f7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Osu.Skinning { public enum OsuSkinConfiguration diff --git a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs index a4a3316927..8ba9e75d19 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -55,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Skinning /// private Vector2 snakedPathOffset; - private DrawableSlider drawableSlider; + private DrawableSlider drawableSlider = null!; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableObject) @@ -67,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning public void UpdateProgress(double completionProgress) { - if (drawableSlider?.HitObject == null) + if (drawableSlider.HitObject == null) return; Slider slider = drawableSlider.HitObject; @@ -96,7 +94,7 @@ namespace osu.Game.Rulesets.Osu.Skinning public void Refresh() { - if (drawableSlider?.HitObject == null) + if (drawableSlider.HitObject == null) return; // Generate the entire curve From a6165ea78ab06518eed3410b15869401943a4dd9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:37:04 +0900 Subject: [PATCH 236/261] Apply nullability to osu!mania skinning classes --- osu.Game.Rulesets.Mania/ManiaSkinComponent.cs | 2 -- .../Skinning/Default/DefaultBodyPiece.cs | 15 ++++++--------- .../Skinning/Default/DefaultNotePiece.cs | 5 +---- .../Skinning/Default/IHoldNoteBody.cs | 2 -- .../Skinning/Legacy/HitTargetInsetContainer.cs | 2 -- .../Skinning/Legacy/LegacyBodyPiece.cs | 17 ++++++----------- .../Skinning/Legacy/LegacyColumnBackground.cs | 6 ++---- .../Skinning/Legacy/LegacyHitExplosion.cs | 4 +--- .../Skinning/Legacy/LegacyHitTarget.cs | 4 +--- .../Skinning/Legacy/LegacyHoldNoteHeadPiece.cs | 4 +--- .../Skinning/Legacy/LegacyHoldNoteTailPiece.cs | 4 +--- .../Skinning/Legacy/LegacyKeyArea.cs | 10 ++++------ .../Legacy/LegacyManiaColumnElement.cs | 10 ++++------ .../Legacy/LegacyManiaJudgementPiece.cs | 18 +++++------------- .../Skinning/Legacy/LegacyNotePiece.cs | 16 +++++----------- .../Skinning/Legacy/LegacyStageForeground.cs | 4 +--- .../Legacy/ManiaClassicSkinTransformer.cs | 2 +- .../Skinning/ManiaSkinConfigExtensions.cs | 8 +++----- .../Skinning/ManiaSkinConfigurationLookup.cs | 2 -- 19 files changed, 42 insertions(+), 93 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs index f05edb4677..a074aab9da 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs index 7476af3c3c..f0e214b190 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -27,8 +24,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default protected readonly Bindable AccentColour = new Bindable(); protected readonly IBindable IsHitting = new Bindable(); - protected Drawable Background { get; private set; } - private Container foregroundContainer; + protected Drawable Background { get; private set; } = null!; + private Container foregroundContainer = null!; public DefaultBodyPiece() { @@ -36,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default } [BackgroundDependencyLoader(true)] - private void load([CanBeNull] DrawableHitObject drawableObject) + private void load(DrawableHitObject? drawableObject) { InternalChildren = new[] { @@ -74,9 +71,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default private readonly LayoutValue subtractionCache = new LayoutValue(Invalidation.DrawSize); - private BufferedContainer foregroundBuffer; - private BufferedContainer subtractionBuffer; - private Container subtractionLayer; + private BufferedContainer foregroundBuffer = null!; + private BufferedContainer subtractionBuffer = null!; + private Container subtractionLayer = null!; public ForegroundPiece() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs index 72bb05de49..569740deee 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -53,7 +50,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default } [BackgroundDependencyLoader(true)] - private void load([NotNull] IScrollingInfo scrollingInfo, [CanBeNull] DrawableHitObject drawableObject) + private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject) { direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs b/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs index 9168a96b95..1f290f1f1c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Mania.Skinning.Default { /// diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs index 362a265789..3c89e2c04a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs index 49ba503cb5..52bca2aaa0 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs @@ -1,12 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Textures; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { public class LegacyBodyPiece : LegacyManiaColumnElement { - private DrawableHoldNote holdNote; + private DrawableHoldNote holdNote = null!; private readonly IBindable direction = new Bindable(); private readonly IBindable isHitting = new Bindable(); @@ -31,14 +29,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy /// private readonly Bindable missFadeTime = new Bindable(); - [CanBeNull] - private Drawable bodySprite; + private Drawable? bodySprite; - [CanBeNull] - private Drawable lightContainer; + private Drawable? lightContainer; - [CanBeNull] - private Drawable light; + private Drawable? light; public LegacyBodyPiece() { @@ -214,7 +209,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { base.Dispose(isDisposing); - if (holdNote != null) + if (holdNote.IsNotNull()) holdNote.ApplyCustomUpdateState -= applyCustomUpdateState; lightContainer?.Expire(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs index f35cedab08..0ed96cf6f1 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container lightContainer; - private Sprite light; + private Container lightContainer = null!; + private Sprite light = null!; public LegacyColumnBackground() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs index 278cf0707c..6b0e1e5d8a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy private readonly IBindable direction = new Bindable(); - private Drawable explosion; + private Drawable? explosion; public LegacyHitExplosion() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs index 611dac30b3..ed78cb6086 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container directionContainer; + private Container directionContainer = null!; [BackgroundDependencyLoader] private void load(ISkinSource skin, IScrollingInfo scrollingInfo) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs index a653e2ce36..c3ed0111be 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Skinning; @@ -10,7 +8,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { public class LegacyHoldNoteHeadPiece : LegacyNotePiece { - protected override Drawable GetAnimation(ISkinSource skin) + protected override Drawable? GetAnimation(ISkinSource skin) { // TODO: Should fallback to the head from default legacy skin instead of note. return GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteHeadImage) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs index 7511b008f0..13edc6e495 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.UI.Scrolling; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy : new ValueChangedEvent(ScrollingDirection.Up, ScrollingDirection.Up)); } - protected override Drawable GetAnimation(ISkinSource skin) + protected override Drawable? GetAnimation(ISkinSource skin) { // TODO: Should fallback to the head from default legacy skin instead of note. return GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteTailImage) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs index dfd5af89c1..e7dca3d946 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,12 +19,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container directionContainer; - private Sprite upSprite; - private Sprite downSprite; + private Container directionContainer = null!; + private Sprite upSprite = null!; + private Sprite downSprite = null!; [Resolved] - private Column column { get; set; } + private Column column { get; set; } = null!; public LegacyKeyArea() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs index e227c80845..4ffef18781 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,15 +17,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy public class LegacyManiaColumnElement : CompositeDrawable { [Resolved] - protected Column Column { get; private set; } + protected Column Column { get; private set; } = null!; [Resolved] - private StageDefinition stage { get; set; } + private StageDefinition stage { get; set; } = null!; /// /// The column type identifier to use for texture lookups, in the case of no user-provided configuration. /// - protected string FallbackColumnIndex { get; private set; } + protected string FallbackColumnIndex { get; private set; } = null!; [BackgroundDependencyLoader] private void load() @@ -41,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy } } - protected IBindable GetColumnSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) + protected IBindable? GetColumnSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) where T : notnull => skin.GetManiaSkinConfig(lookup, Column.Index); } } diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs index d09a73a693..670a0aad6e 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -41,21 +39,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy Y = scorePosition ?? 0; - if (animation != null) + InternalChild = animation.With(d => { - InternalChild = animation.With(d => - { - d.Anchor = Anchor.Centre; - d.Origin = Anchor.Centre; - }); - } + d.Anchor = Anchor.Centre; + d.Origin = Anchor.Centre; + }); } public void PlayAnimation() { - if (animation == null) - return; - (animation as IFramedAnimation)?.GotoFrame(0); this.FadeInFromZero(20, Easing.Out) @@ -86,6 +78,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy } } - public Drawable GetAboveHitObjectsProxiedContent() => null; + public Drawable? GetAboveHitObjectsProxiedContent() => null; } } diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs index 41e149ea2f..8c5a594b3b 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,10 +18,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container directionContainer; + private Container directionContainer = null!; - [CanBeNull] - private Drawable noteAnimation; + private Drawable noteAnimation = null!; private float? minimumColumnWidth; @@ -55,7 +51,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { base.Update(); - Texture texture = null; + Texture? texture = null; if (noteAnimation is Sprite sprite) texture = sprite.Texture; @@ -84,11 +80,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy } } - [CanBeNull] - protected virtual Drawable GetAnimation(ISkinSource skin) => GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage); + protected virtual Drawable? GetAnimation(ISkinSource skin) => GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage); - [CanBeNull] - protected Drawable GetAnimationFromLookup(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) + protected Drawable? GetAnimationFromLookup(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) { string suffix = string.Empty; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs index f7c611d551..8e72e970ab 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -17,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Drawable sprite; + private Drawable? sprite; public LegacyStageForeground() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs index e57927897c..be3372fe58 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { if (lookup is ManiaSkinConfigurationLookup maniaLookup) { diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs index e22bf63049..0f15bfe12b 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Game.Skinning; @@ -16,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Skinning /// The skin from which configuration is retrieved. /// The value to retrieve. /// If not null, denotes the index of the column to which the entry applies. - public static IBindable GetManiaSkinConfig(this ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? columnIndex = null) - => skin.GetConfig( - new ManiaSkinConfigurationLookup(lookup, columnIndex)); + public static IBindable? GetManiaSkinConfig(this ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? columnIndex = null) + where T : notnull + => skin.GetConfig(new ManiaSkinConfigurationLookup(lookup, columnIndex)); } } diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs index 59188f02f9..6c39ffdcc3 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Mania.UI; using osu.Game.Skinning; From 2952dbc8fb9ffd0e7c3475dcdf5ea123431d559a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:37:19 +0900 Subject: [PATCH 237/261] Apply nullability to osu!catch skinning classes --- osu.Game.Rulesets.Catch/CatchInputManager.cs | 2 -- osu.Game.Rulesets.Catch/CatchSkinComponent.cs | 2 -- .../CatchSkinComponents.cs | 2 -- .../Skinning/CatchSkinColour.cs | 2 -- .../Skinning/CatchSkinConfiguration.cs | 2 -- .../Skinning/Default/BananaPulpFormation.cs | 2 -- .../Skinning/Default/BorderPiece.cs | 2 -- .../Skinning/Default/CatchHitObjectPiece.cs | 11 +++------ .../Skinning/Default/DefaultCatcher.cs | 2 -- .../Skinning/Default/DefaultHitExplosion.cs | 10 ++++---- .../Skinning/Default/DropletPiece.cs | 2 -- .../Skinning/Default/FruitPiece.cs | 2 -- .../Skinning/Default/FruitPulpFormation.cs | 2 -- .../Skinning/Default/HyperBorderPiece.cs | 2 -- .../Default/HyperDropletBorderPiece.cs | 2 -- .../Skinning/Default/Pulp.cs | 2 -- .../Skinning/Default/PulpFormation.cs | 2 -- .../Legacy/CatchLegacySkinTransformer.cs | 8 +++---- .../Skinning/Legacy/LegacyBananaPiece.cs | 6 ++--- .../Legacy/LegacyCatchHitObjectPiece.cs | 23 +++++++++---------- .../Skinning/Legacy/LegacyCatcherNew.cs | 9 ++++---- .../Skinning/Legacy/LegacyCatcherOld.cs | 4 +--- .../Skinning/Legacy/LegacyDropletPiece.cs | 6 ++--- .../Skinning/Legacy/LegacyFruitPiece.cs | 2 -- .../Skinning/Legacy/LegacyHitExplosion.cs | 4 +--- 25 files changed, 31 insertions(+), 82 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs index 5b62154a34..0f76953003 100644 --- a/osu.Game.Rulesets.Catch/CatchInputManager.cs +++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Input.Bindings; diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs index e79da667da..07c613d6ff 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs index 7587de5803..371e901c69 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch { public enum CatchSkinComponents diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs b/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs index d038ccb31c..4506111498 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Skinning { public enum CatchSkinColour diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs index 65d6acd88d..ea8d742b1a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Skinning { public enum CatchSkinConfiguration diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs index ffeed80615..ee1cc68f7d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Default diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs index 60a13bee59..8d8ee49af7 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs index 3b8df6ee6f..e84e4d4ad2 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,19 +18,17 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default public readonly Bindable IndexInBeatmap = new Bindable(); [Resolved] - protected IHasCatchObjectState ObjectState { get; private set; } + protected IHasCatchObjectState ObjectState { get; private set; } = null!; /// /// A part of this piece that will be faded out while falling in the playfield. /// - [CanBeNull] - protected virtual Drawable BorderPiece => null; + protected virtual Drawable? BorderPiece => null; /// /// A part of this piece that will be only visible when is true. /// - [CanBeNull] - protected virtual Drawable HyperBorderPiece => null; + protected virtual Drawable? HyperBorderPiece => null; protected override void LoadComplete() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs index 4148fed11c..e423f21b98 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index 7ea99b3ed9..2650ba765b 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -18,10 +16,10 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default { public class DefaultHitExplosion : CompositeDrawable, IHitExplosion { - private CircularContainer largeFaint; - private CircularContainer smallFaint; - private CircularContainer directionalGlow1; - private CircularContainer directionalGlow2; + private CircularContainer largeFaint = null!; + private CircularContainer smallFaint = null!; + private CircularContainer directionalGlow1 = null!; + private CircularContainer directionalGlow2 = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs index b8ae062382..59e74bff74 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs index adee960c3c..3bd8032649 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs index db51195f11..f097361d2a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Game.Rulesets.Catch.Objects; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs index 42b0b85495..c8895f32f4 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.UI; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs index 29cb339625..53a487b97f 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Skinning.Default { public class HyperDropletBorderPiece : HyperBorderPiece diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs index 8ea54617d9..96c6233b41 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs index aa5ef5fb66..8753aa4077 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index a73b34c9b6..ef83e67876 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (component is SkinnableTargetComponent targetComponent) { @@ -112,12 +110,12 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy GetTexture(@"fruit-catcher-idle") != null || GetTexture(@"fruit-catcher-idle-0") != null; - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { switch (lookup) { case CatchSkinColour colour: - var result = (Bindable)base.GetConfig(new SkinCustomColourLookup(colour)); + var result = (Bindable?)base.GetConfig(new SkinCustomColourLookup(colour)); if (result == null) return null; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs index 9f64a2129e..310da8bf78 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Catch.Skinning.Legacy @@ -13,8 +11,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { base.LoadComplete(); - Texture texture = Skin.GetTexture("fruit-bananas"); - Texture overlayTexture = Skin.GetTexture("fruit-bananas-overlay"); + Texture? texture = Skin.GetTexture("fruit-bananas"); + Texture? overlayTexture = Skin.GetTexture("fruit-bananas-overlay"); SetTexture(texture, overlayTexture); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs index 5a5288105d..1231ed6d5a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -19,19 +17,20 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { public abstract class LegacyCatchHitObjectPiece : PoolableDrawable { - public readonly Bindable AccentColour = new Bindable(); - public readonly Bindable HyperDash = new Bindable(); - public readonly Bindable IndexInBeatmap = new Bindable(); + protected readonly Bindable IndexInBeatmap = new Bindable(); + + private readonly Bindable accentColour = new Bindable(); + private readonly Bindable hyperDash = new Bindable(); private readonly Sprite colouredSprite; private readonly Sprite overlaySprite; private readonly Sprite hyperSprite; [Resolved] - protected ISkinSource Skin { get; private set; } + protected ISkinSource Skin { get; private set; } = null!; [Resolved] - protected IHasCatchObjectState ObjectState { get; private set; } + protected IHasCatchObjectState ObjectState { get; private set; } = null!; protected LegacyCatchHitObjectPiece() { @@ -65,26 +64,26 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { base.LoadComplete(); - AccentColour.BindTo(ObjectState.AccentColour); - HyperDash.BindTo(ObjectState.HyperDash); + accentColour.BindTo(ObjectState.AccentColour); + hyperDash.BindTo(ObjectState.HyperDash); IndexInBeatmap.BindTo(ObjectState.IndexInBeatmap); hyperSprite.Colour = Skin.GetConfig(CatchSkinColour.HyperDashFruit)?.Value ?? Skin.GetConfig(CatchSkinColour.HyperDash)?.Value ?? Catcher.DEFAULT_HYPER_DASH_COLOUR; - AccentColour.BindValueChanged(colour => + accentColour.BindValueChanged(colour => { colouredSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue); }, true); - HyperDash.BindValueChanged(hyper => + hyperDash.BindValueChanged(hyper => { hyperSprite.Alpha = hyper.NewValue ? 0.7f : 0; }, true); } - protected void SetTexture(Texture texture, Texture overlayTexture) + protected void SetTexture(Texture? texture, Texture? overlayTexture) { colouredSprite.Texture = texture; overlaySprite.Texture = overlayTexture; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs index 93d79f00d3..667622e6f2 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -20,11 +18,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public class LegacyCatcherNew : CompositeDrawable { [Resolved] - private Bindable currentState { get; set; } + private Bindable currentState { get; set; } = null!; private readonly Dictionary drawables = new Dictionary(); - private Drawable currentDrawable; + private Drawable currentDrawable = null!; public LegacyCatcherNew() { @@ -51,7 +49,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy Drawable getDrawableFor(CatcherAnimationState state) => skin.GetAnimation(@$"fruit-catcher-{state.ToString().ToLowerInvariant()}", true, true, true) ?? - skin.GetAnimation(@"fruit-catcher-idle", true, true, true); + skin.GetAnimation(@"fruit-catcher-idle", true, true, true) ?? + Empty(); } protected override void LoadComplete() diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs index 736e9cfddf..5f09d1e254 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy [BackgroundDependencyLoader] private void load(ISkinSource skin) { - InternalChild = skin.GetAnimation(@"fruit-ryuuta", true, true, true).With(d => + InternalChild = (skin.GetAnimation(@"fruit-ryuuta", true, true, true) ?? Empty()).With(d => { d.Anchor = Anchor.TopCentre; d.Origin = Anchor.TopCentre; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs index f99cedab3f..7007f1cc29 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Textures; using osuTK; @@ -19,8 +17,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { base.LoadComplete(); - Texture texture = Skin.GetTexture("fruit-drop"); - Texture overlayTexture = Skin.GetTexture("fruit-drop-overlay"); + Texture? texture = Skin.GetTexture("fruit-drop"); + Texture? overlayTexture = Skin.GetTexture("fruit-drop-overlay"); SetTexture(texture, overlayTexture); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs index 125a96a446..f002bab219 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Skinning.Legacy diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 8f46bdbe6e..393a1076af 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public class LegacyHitExplosion : CompositeDrawable, IHitExplosion { [Resolved] - private Catcher catcher { get; set; } + private Catcher catcher { get; set; } = null!; private const float catch_margin = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2; From bf26dbffc2e48458f48d4e8433d2b96f49eacf82 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:44:59 +0900 Subject: [PATCH 238/261] Apply nullability to skinning support classes --- .../Judgements/IAnimatableJudgement.cs | 6 +-- osu.Game/Skinning/ArgonSkin.cs | 13 +++--- osu.Game/Skinning/DefaultLegacySkin.cs | 2 - osu.Game/Skinning/GameplaySkinComponent.cs | 3 +- osu.Game/Skinning/GlobalSkinColours.cs | 2 - osu.Game/Skinning/IAnimationTimeReference.cs | 2 - osu.Game/Skinning/IPooledSampleProvider.cs | 6 +-- osu.Game/Skinning/ISkinComponent.cs | 2 - osu.Game/Skinning/ISkinSource.cs | 6 +-- osu.Game/Skinning/ISkinnableDrawable.cs | 2 - osu.Game/Skinning/ISkinnableTarget.cs | 2 - osu.Game/Skinning/LegacyAccuracyCounter.cs | 2 - .../Skinning/LegacyColourCompatibility.cs | 2 - osu.Game/Skinning/LegacyComboCounter.cs | 2 - osu.Game/Skinning/LegacyFont.cs | 2 - osu.Game/Skinning/LegacyJudgementPieceNew.cs | 10 ++--- osu.Game/Skinning/LegacySkin.cs | 8 ++-- osu.Game/Skinning/SkinComboColourLookup.cs | 2 - osu.Game/Skinning/SkinConfigManager.cs | 2 - osu.Game/Skinning/SkinConfiguration.cs | 4 +- osu.Game/Skinning/SkinProvidingContainer.cs | 40 +++++++++---------- osu.Game/Skinning/SkinReloadableDrawable.cs | 9 ++--- osu.Game/Skinning/SkinUtils.cs | 4 +- osu.Game/Skinning/SkinnableSprite.cs | 16 ++++---- osu.Game/Skinning/SkinnableSpriteText.cs | 2 - osu.Game/Skinning/SkinnableTarget.cs | 2 - osu.Game/Skinning/SkinnableTargetComponent.cs | 2 - .../SkinnableTargetComponentsContainer.cs | 4 +- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 +-- osu.Game/Skinning/TrianglesSkin.cs | 12 +++--- .../UnsupportedSkinComponentException.cs | 2 - 31 files changed, 60 insertions(+), 119 deletions(-) diff --git a/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs b/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs index 2bc5a62983..0aa337bc20 100644 --- a/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Graphics; namespace osu.Game.Rulesets.Judgements @@ -21,7 +18,6 @@ namespace osu.Game.Rulesets.Judgements /// /// Get proxied content which should be displayed above all hitobjects. /// - [CanBeNull] - Drawable GetAboveHitObjectsProxiedContent(); + Drawable? GetAboveHitObjectsProxiedContent(); } } diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 010e2175e1..20e4290725 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.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. -#nullable disable using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -25,7 +24,7 @@ namespace osu.Game.Skinning { public static SkinInfo CreateInfo() => new SkinInfo { - ID = osu.Game.Skinning.SkinInfo.ARGON_SKIN, + ID = Skinning.SkinInfo.ARGON_SKIN, Name = "osu! \"argon\" (2022)", Creator = "team osu!", Protected = true, @@ -68,9 +67,9 @@ namespace osu.Game.Skinning }; } - public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); + public override Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); - public override ISample GetSample(ISampleInfo sampleInfo) + public override ISample? GetSample(ISampleInfo sampleInfo) { foreach (string lookup in sampleInfo.LookupNames) { @@ -82,7 +81,7 @@ namespace osu.Game.Skinning return null; } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (base.GetDrawableComponent(component) is Drawable c) return c; @@ -192,7 +191,7 @@ namespace osu.Game.Skinning return null; } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { // todo: this code is pulled from LegacySkin and should not exist. // will likely change based on how databased storage of skin configuration goes. @@ -202,7 +201,7 @@ namespace osu.Game.Skinning switch (global) { case GlobalSkinColours.ComboColours: - return SkinUtils.As(new Bindable>(Configuration.ComboColours)); + return SkinUtils.As(new Bindable?>(Configuration.ComboColours)); } break; diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs index b80275a1e8..fd9653e3e5 100644 --- a/osu.Game/Skinning/DefaultLegacySkin.cs +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using JetBrains.Annotations; using osu.Framework.IO.Stores; diff --git a/osu.Game/Skinning/GameplaySkinComponent.cs b/osu.Game/Skinning/GameplaySkinComponent.cs index cdd3638375..6f5dad2207 100644 --- a/osu.Game/Skinning/GameplaySkinComponent.cs +++ b/osu.Game/Skinning/GameplaySkinComponent.cs @@ -1,13 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; namespace osu.Game.Skinning { public class GameplaySkinComponent : ISkinComponent + where T : notnull { public readonly T Component; diff --git a/osu.Game/Skinning/GlobalSkinColours.cs b/osu.Game/Skinning/GlobalSkinColours.cs index e2b5799048..f889371b98 100644 --- a/osu.Game/Skinning/GlobalSkinColours.cs +++ b/osu.Game/Skinning/GlobalSkinColours.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public enum GlobalSkinColours diff --git a/osu.Game/Skinning/IAnimationTimeReference.cs b/osu.Game/Skinning/IAnimationTimeReference.cs index a65d15d24b..b6a944ddf8 100644 --- a/osu.Game/Skinning/IAnimationTimeReference.cs +++ b/osu.Game/Skinning/IAnimationTimeReference.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Textures; diff --git a/osu.Game/Skinning/IPooledSampleProvider.cs b/osu.Game/Skinning/IPooledSampleProvider.cs index 46cd824e95..3ea299f5e2 100644 --- a/osu.Game/Skinning/IPooledSampleProvider.cs +++ b/osu.Game/Skinning/IPooledSampleProvider.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Game.Audio; namespace osu.Game.Skinning @@ -18,7 +15,6 @@ namespace osu.Game.Skinning /// /// The describing the sample to retrieve. /// The . - [CanBeNull] - PoolableSkinnableSample GetPooledSample(ISampleInfo sampleInfo); + PoolableSkinnableSample? GetPooledSample(ISampleInfo sampleInfo); } } diff --git a/osu.Game/Skinning/ISkinComponent.cs b/osu.Game/Skinning/ISkinComponent.cs index 34922b98b6..4bd9f21b6b 100644 --- a/osu.Game/Skinning/ISkinComponent.cs +++ b/osu.Game/Skinning/ISkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public interface ISkinComponent diff --git a/osu.Game/Skinning/ISkinSource.cs b/osu.Game/Skinning/ISkinSource.cs index 94940fd549..89f656a12c 100644 --- a/osu.Game/Skinning/ISkinSource.cs +++ b/osu.Game/Skinning/ISkinSource.cs @@ -1,11 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; -using JetBrains.Annotations; namespace osu.Game.Skinning { @@ -24,8 +21,7 @@ namespace osu.Game.Skinning /// This should be used for cases where subsequent lookups (for related components) need to occur on the same skin. /// /// The skin to be used for subsequent lookups, or null if none is available. - [CanBeNull] - ISkin FindProvider(Func lookupFunction); + ISkin? FindProvider(Func lookupFunction); /// /// Retrieve all sources available for lookup, with highest priority source first. diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISkinnableDrawable.cs index ca643af17a..3fc6a2fdd8 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISkinnableDrawable.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 17279ef178..8d4f4dd0c3 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; diff --git a/osu.Game/Skinning/LegacyAccuracyCounter.cs b/osu.Game/Skinning/LegacyAccuracyCounter.cs index ffb463faae..bdcb85456a 100644 --- a/osu.Game/Skinning/LegacyAccuracyCounter.cs +++ b/osu.Game/Skinning/LegacyAccuracyCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Screens.Play.HUD; diff --git a/osu.Game/Skinning/LegacyColourCompatibility.cs b/osu.Game/Skinning/LegacyColourCompatibility.cs index 0673d0a8d3..38e43432ce 100644 --- a/osu.Game/Skinning/LegacyColourCompatibility.cs +++ b/osu.Game/Skinning/LegacyColourCompatibility.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osuTK.Graphics; diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index bfa6d5a255..f4caef26c2 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game/Skinning/LegacyFont.cs b/osu.Game/Skinning/LegacyFont.cs index f738caf3f3..d1971cb84c 100644 --- a/osu.Game/Skinning/LegacyFont.cs +++ b/osu.Game/Skinning/LegacyFont.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { /// diff --git a/osu.Game/Skinning/LegacyJudgementPieceNew.cs b/osu.Game/Skinning/LegacyJudgementPieceNew.cs index 2cb055d8ba..39b266ab9f 100644 --- a/osu.Game/Skinning/LegacyJudgementPieceNew.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceNew.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -20,13 +18,13 @@ namespace osu.Game.Skinning { private readonly HitResult result; - private readonly LegacyJudgementPieceOld temporaryOldStyle; + private readonly LegacyJudgementPieceOld? temporaryOldStyle; private readonly Drawable mainPiece; - private readonly ParticleExplosion particles; + private readonly ParticleExplosion? particles; - public LegacyJudgementPieceNew(HitResult result, Func createMainDrawable, Texture particleTexture) + public LegacyJudgementPieceNew(HitResult result, Func createMainDrawable, Texture? particleTexture) { this.result = result; @@ -124,6 +122,6 @@ namespace osu.Game.Skinning } } - public Drawable GetAboveHitObjectsProxiedContent() => temporaryOldStyle?.CreateProxy(); // for new style judgements, only the old style temporary display is in front of objects. + public Drawable? GetAboveHitObjectsProxiedContent() => temporaryOldStyle?.CreateProxy(); // for new style judgements, only the old style temporary display is in front of objects. } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index eaca0de11a..bfc60de2c9 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -9,6 +9,7 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; @@ -379,12 +380,13 @@ namespace osu.Game.Skinning return null; case GameplaySkinComponent resultComponent: - // TODO: this should be inside the judgement pieces. - Func createDrawable = () => getJudgementAnimation(resultComponent.Component); // kind of wasteful that we throw this away, but should do for now. - if (createDrawable() != null) + if (getJudgementAnimation(resultComponent.Component) != null) { + // TODO: this should be inside the judgement pieces. + Func createDrawable = () => getJudgementAnimation(resultComponent.Component).AsNonNull(); + var particle = getParticleTexture(resultComponent.Component); if (particle != null) diff --git a/osu.Game/Skinning/SkinComboColourLookup.cs b/osu.Game/Skinning/SkinComboColourLookup.cs index 2eb4af6289..33e35a96fb 100644 --- a/osu.Game/Skinning/SkinComboColourLookup.cs +++ b/osu.Game/Skinning/SkinComboColourLookup.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Skinning diff --git a/osu.Game/Skinning/SkinConfigManager.cs b/osu.Game/Skinning/SkinConfigManager.cs index 8a34ab3db4..682138a2e9 100644 --- a/osu.Game/Skinning/SkinConfigManager.cs +++ b/osu.Game/Skinning/SkinConfigManager.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Configuration; diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a9f660312e..937cca0aeb 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps.Formats; using osuTK.Graphics; @@ -52,7 +50,7 @@ namespace osu.Game.Skinning public List CustomComboColours { get; set; } = new List(); - public IReadOnlyList ComboColours + public IReadOnlyList? ComboColours { get { diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 42c39e581f..5c5e9ae0fc 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; @@ -22,10 +19,9 @@ namespace osu.Game.Skinning /// public class SkinProvidingContainer : Container, ISkinSource { - public event Action SourceChanged; + public event Action? SourceChanged; - [CanBeNull] - protected ISkinSource ParentSource { get; private set; } + protected ISkinSource? ParentSource { get; private set; } /// /// Whether falling back to parent s is allowed in this container. @@ -52,7 +48,7 @@ namespace osu.Game.Skinning /// /// Constructs a new initialised with a single skin source. /// - public SkinProvidingContainer([CanBeNull] ISkin skin) + public SkinProvidingContainer(ISkin? skin) : this() { if (skin != null) @@ -82,7 +78,7 @@ namespace osu.Game.Skinning return dependencies; } - public ISkin FindProvider(Func lookupFunction) + public ISkin? FindProvider(Func lookupFunction) { foreach (var (skin, lookupWrapper) in skinSources) { @@ -111,11 +107,11 @@ namespace osu.Game.Skinning } } - public Drawable GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinComponent component) { foreach (var (_, lookupWrapper) in skinSources) { - Drawable sourceDrawable; + Drawable? sourceDrawable; if ((sourceDrawable = lookupWrapper.GetDrawableComponent(component)) != null) return sourceDrawable; } @@ -126,11 +122,11 @@ namespace osu.Game.Skinning return ParentSource?.GetDrawableComponent(component); } - public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) + public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { foreach (var (_, lookupWrapper) in skinSources) { - Texture sourceTexture; + Texture? sourceTexture; if ((sourceTexture = lookupWrapper.GetTexture(componentName, wrapModeS, wrapModeT)) != null) return sourceTexture; } @@ -141,11 +137,11 @@ namespace osu.Game.Skinning return ParentSource?.GetTexture(componentName, wrapModeS, wrapModeT); } - public ISample GetSample(ISampleInfo sampleInfo) + public ISample? GetSample(ISampleInfo sampleInfo) { foreach (var (_, lookupWrapper) in skinSources) { - ISample sourceSample; + ISample? sourceSample; if ((sourceSample = lookupWrapper.GetSample(sampleInfo)) != null) return sourceSample; } @@ -156,11 +152,13 @@ namespace osu.Game.Skinning return ParentSource?.GetSample(sampleInfo); } - public IBindable GetConfig(TLookup lookup) + public IBindable? GetConfig(TLookup lookup) + where TLookup : notnull + where TValue : notnull { foreach (var (_, lookupWrapper) in skinSources) { - IBindable bindable; + IBindable? bindable; if ((bindable = lookupWrapper.GetConfig(lookup)) != null) return bindable; } @@ -240,7 +238,7 @@ namespace osu.Game.Skinning this.provider = provider; } - public Drawable GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinComponent component) { if (provider.AllowDrawableLookup(component)) return skin.GetDrawableComponent(component); @@ -248,7 +246,7 @@ namespace osu.Game.Skinning return null; } - public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) + public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { if (provider.AllowTextureLookup(componentName)) return skin.GetTexture(componentName, wrapModeS, wrapModeT); @@ -256,7 +254,7 @@ namespace osu.Game.Skinning return null; } - public ISample GetSample(ISampleInfo sampleInfo) + public ISample? GetSample(ISampleInfo sampleInfo) { if (provider.AllowSampleLookup(sampleInfo)) return skin.GetSample(sampleInfo); @@ -264,7 +262,9 @@ namespace osu.Game.Skinning return null; } - public IBindable GetConfig(TLookup lookup) + public IBindable? GetConfig(TLookup lookup) + where TLookup : notnull + where TValue : notnull { switch (lookup) { diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index c6332fc4d2..f1c8388f71 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Pooling; namespace osu.Game.Skinning @@ -17,12 +16,12 @@ namespace osu.Game.Skinning /// /// Invoked when has changed. /// - public event Action OnSkinChanged; + public event Action? OnSkinChanged; /// /// The current skin source. /// - protected ISkinSource CurrentSkin { get; private set; } + protected ISkinSource CurrentSkin { get; private set; } = null!; [BackgroundDependencyLoader] private void load(ISkinSource source) @@ -60,7 +59,7 @@ namespace osu.Game.Skinning { base.Dispose(isDisposing); - if (CurrentSkin != null) + if (CurrentSkin.IsNotNull()) CurrentSkin.SourceChanged -= onChange; OnSkinChanged = null; diff --git a/osu.Game/Skinning/SkinUtils.cs b/osu.Game/Skinning/SkinUtils.cs index 8e01bd2853..75eae82401 100644 --- a/osu.Game/Skinning/SkinUtils.cs +++ b/osu.Game/Skinning/SkinUtils.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; namespace osu.Game.Skinning @@ -18,6 +16,6 @@ namespace osu.Game.Skinning /// The value. /// The type of value , and the type of the resulting bindable. /// The resulting bindable. - public static Bindable As(object value) => (Bindable)value; + public static Bindable? As(object? value) => (Bindable?)value; } } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 5a39121b16..f8130f31c3 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -27,13 +25,13 @@ namespace osu.Game.Skinning protected override bool ApplySizeRestrictionsToDefault => true; [Resolved] - private TextureStore textures { get; set; } + private TextureStore textures { get; set; } = null!; [SettingSource("Sprite name", "The filename of the sprite", SettingControlType = typeof(SpriteSelectorControl))] public Bindable SpriteName { get; } = new Bindable(string.Empty); [Resolved] - private ISkinSource source { get; set; } + private ISkinSource source { get; set; } = null!; public SkinnableSprite(string textureName, ConfineMode confineMode = ConfineMode.NoScaling) : base(new SpriteComponent(textureName), confineMode) @@ -88,15 +86,15 @@ namespace osu.Game.Skinning // but that requires further thought. var highestPrioritySkin = getHighestPriorityUserSkin(((SkinnableSprite)SettingSourceObject).source.AllSources) as Skin; - string[] availableFiles = highestPrioritySkin?.SkinInfo.PerformRead(s => s.Files - .Where(f => f.Filename.EndsWith(".png", StringComparison.Ordinal) - || f.Filename.EndsWith(".jpg", StringComparison.Ordinal)) - .Select(f => f.Filename).Distinct()).ToArray(); + string[]? availableFiles = highestPrioritySkin?.SkinInfo.PerformRead(s => s.Files + .Where(f => f.Filename.EndsWith(".png", StringComparison.Ordinal) + || f.Filename.EndsWith(".jpg", StringComparison.Ordinal)) + .Select(f => f.Filename).Distinct()).ToArray(); if (availableFiles?.Length > 0) Items = availableFiles; - static ISkin getHighestPriorityUserSkin(IEnumerable skins) + static ISkin? getHighestPriorityUserSkin(IEnumerable skins) { foreach (var skin in skins) { diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 3e9462b83e..2bde3c4180 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; diff --git a/osu.Game/Skinning/SkinnableTarget.cs b/osu.Game/Skinning/SkinnableTarget.cs index bca0d499f7..09de8a5d71 100644 --- a/osu.Game/Skinning/SkinnableTarget.cs +++ b/osu.Game/Skinning/SkinnableTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public enum SkinnableTarget diff --git a/osu.Game/Skinning/SkinnableTargetComponent.cs b/osu.Game/Skinning/SkinnableTargetComponent.cs index 51af1c23c9..a17aafe6e7 100644 --- a/osu.Game/Skinning/SkinnableTargetComponent.cs +++ b/osu.Game/Skinning/SkinnableTargetComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public class SkinnableTargetComponent : ISkinComponent diff --git a/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs b/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs index dd7290a858..e38afedeb9 100644 --- a/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using Newtonsoft.Json; using osu.Framework.Graphics; @@ -21,7 +19,7 @@ namespace osu.Game.Skinning public bool UsesFixedAnchor { get; set; } - private readonly Action applyDefaults; + private readonly Action? applyDefaults; /// /// Construct a wrapper with defaults that should be applied once. diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 2faaa9a905..708ad4ec47 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using System.Threading; @@ -13,7 +11,7 @@ namespace osu.Game.Skinning { public class SkinnableTargetContainer : SkinReloadableDrawable, ISkinnableTarget { - private SkinnableTargetComponentsContainer content; + private SkinnableTargetComponentsContainer? content; public SkinnableTarget Target { get; } @@ -25,7 +23,7 @@ namespace osu.Game.Skinning public bool ComponentsLoaded { get; private set; } - private CancellationTokenSource cancellationSource; + private CancellationTokenSource? cancellationSource; public SkinnableTargetContainer(SkinnableTarget target) { diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 2c70963524..d00874aa8f 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -47,9 +45,9 @@ namespace osu.Game.Skinning this.resources = resources; } - public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); + public override Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); - public override ISample GetSample(ISampleInfo sampleInfo) + public override ISample? GetSample(ISampleInfo sampleInfo) { foreach (string lookup in sampleInfo.LookupNames) { @@ -61,7 +59,7 @@ namespace osu.Game.Skinning return null; } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (base.GetDrawableComponent(component) is Drawable c) return c; @@ -171,7 +169,7 @@ namespace osu.Game.Skinning return null; } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { // todo: this code is pulled from LegacySkin and should not exist. // will likely change based on how databased storage of skin configuration goes. @@ -181,7 +179,7 @@ namespace osu.Game.Skinning switch (global) { case GlobalSkinColours.ComboColours: - return SkinUtils.As(new Bindable>(Configuration.ComboColours)); + return SkinUtils.As(new Bindable?>(Configuration.ComboColours)); } break; diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 3713b7c200..7f0dd51d5b 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; namespace osu.Game.Skinning From d4251271d87b1244ac31a5ac04f75db669d739c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:50:39 +0900 Subject: [PATCH 239/261] Apply nullability to `SkinnableDrawable` --- osu.Game/Skinning/SkinnableDrawable.cs | 44 ++++++++++++-------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 480d66c557..c6321553c7 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Caching; using osu.Framework.Graphics; @@ -19,7 +17,7 @@ namespace osu.Game.Skinning /// /// The displayed component. /// - public Drawable Drawable { get; private set; } + public Drawable Drawable { get; private set; } = null!; /// /// Whether the drawable component should be centered in available space. @@ -43,7 +41,7 @@ namespace osu.Game.Skinning /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(ISkinComponent component, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public SkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : this(component, confineMode) { createDefault = defaultImplementation; @@ -62,7 +60,7 @@ namespace osu.Game.Skinning /// public void ResetAnimation() => (Drawable as IFramedAnimation)?.GotoFrame(0); - private readonly Func createDefault; + private readonly Func? createDefault; private readonly Cached scaling = new Cached(); @@ -77,30 +75,28 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin) { - Drawable = skin.GetDrawableComponent(Component); + var retrieved = skin.GetDrawableComponent(Component); - isDefault = false; - - if (Drawable == null) + if (retrieved == null) { Drawable = CreateDefault(Component); isDefault = true; } - - if (Drawable != null) - { - scaling.Invalidate(); - - if (CentreComponent) - { - Drawable.Origin = Anchor.Centre; - Drawable.Anchor = Anchor.Centre; - } - - InternalChild = Drawable; - } else - ClearInternal(); + { + Drawable = retrieved; + isDefault = false; + } + + scaling.Invalidate(); + + if (CentreComponent) + { + Drawable.Origin = Anchor.Centre; + Drawable.Anchor = Anchor.Centre; + } + + InternalChild = Drawable; } protected override void Update() @@ -111,7 +107,7 @@ namespace osu.Game.Skinning { try { - if (Drawable == null || (isDefault && !ApplySizeRestrictionsToDefault)) return; + if (isDefault && !ApplySizeRestrictionsToDefault) return; switch (confineMode) { From 4457648b1cc45d0752b26730edff24e4b1829d02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 17:42:33 +0900 Subject: [PATCH 240/261] Fix editor playing too many sounds when user performs a manual seek during playback --- osu.Game/Screens/Edit/Editor.cs | 48 +++++++++++++++------------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index df3c1f7ec4..d7406e6289 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -234,7 +234,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, loadableBeatmap.GetSkin(), loadableBeatmap.BeatmapInfo)); dependencies.CacheAs(editorBeatmap); - editorBeatmap.UpdateInProgress.BindValueChanged(updateInProgress); + editorBeatmap.UpdateInProgress.BindValueChanged(_ => updateSampleDisabledState()); canSave = editorBeatmap.BeatmapInfo.Ruleset.CreateInstance() is ILegacyRuleset; @@ -659,7 +659,7 @@ namespace osu.Game.Screens.Edit if (isNewBeatmap || HasUnsavedChanges) { - samplePlaybackDisabled.Value = true; + updateSampleDisabledState(); dialogOverlay?.Push(new PromptForSaveDialog(confirmExit, confirmExitWithSave, cancelExit)); return true; } @@ -729,27 +729,6 @@ namespace osu.Game.Screens.Edit this.Exit(); } - #region Mute from update application - - private ScheduledDelegate temporaryMuteRestorationDelegate; - private bool temporaryMuteFromUpdateInProgress; - - private void updateInProgress(ValueChangedEvent obj) - { - temporaryMuteFromUpdateInProgress = true; - updateSampleDisabledState(); - - // Debounce is arbitrarily high enough to avoid flip-flopping the value each other frame. - temporaryMuteRestorationDelegate?.Cancel(); - temporaryMuteRestorationDelegate = Scheduler.AddDelayed(() => - { - temporaryMuteFromUpdateInProgress = false; - updateSampleDisabledState(); - }, 50); - } - - #endregion - #region Clipboard support private EditorMenuItem cutMenuItem; @@ -883,11 +862,28 @@ namespace osu.Game.Screens.Edit } } + [CanBeNull] + private ScheduledDelegate playbackDisabledDebounce; + private void updateSampleDisabledState() { - samplePlaybackDisabled.Value = clock.SeekingOrStopped.Value - || currentScreen is not ComposeScreen - || temporaryMuteFromUpdateInProgress; + bool shouldDisableSamples = clock.SeekingOrStopped.Value + || currentScreen is not ComposeScreen + || editorBeatmap.UpdateInProgress.Value + || dialogOverlay?.CurrentDialog != null; + + playbackDisabledDebounce?.Cancel(); + + if (shouldDisableSamples) + { + samplePlaybackDisabled.Value = true; + } + else + { + // Debounce re-enabling arbitrarily high enough to avoid flip-flopping during beatmap updates + // or rapid user seeks. + playbackDisabledDebounce = Scheduler.AddDelayed(() => samplePlaybackDisabled.Value = false, 50); + } } private void seek(UIEvent e, int direction) From ab458320c46b461de0a43c50cb8d3f654e3f9b42 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:45:06 +0900 Subject: [PATCH 241/261] Fix some lingering inspections --- .../TestSceneCatchSkinConfiguration.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs | 2 +- .../Objects/Drawables/DrawableOsuJudgement.cs | 2 +- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Skins/LegacySkinDecoderTest.cs | 4 ++-- osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs | 3 ++- osu.Game/Skinning/PoolableSkinnableSample.cs | 3 ++- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs index a4b2b26624..a2d4e7fb1e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Tests public bool FlipCatcherPlate { get; set; } public TestSkin() - : base(null) + : base(null!) { } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs index 57734236da..20aed514db 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - Child = new SkinProvidingContainer(new TrianglesSkin(null)) + Child = new SkinProvidingContainer(new TrianglesSkin(null!)) { RelativeSizeAxes = Axes.Both, Child = drawableHitCircle = new DrawableHitCircle(hitCircle) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs index e137a503a5..b4abdde911 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Lighting.Alpha = 0; - if (hitLightingEnabled && Lighting.Drawable != null) + if (hitLightingEnabled) { // todo: this animation changes slightly based on new/old legacy skin versions. Lighting.ScaleTo(0.8f).ScaleTo(1.2f, 600, Easing.Out); diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index fdd0167ed3..c6bdd25e8b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -308,7 +308,7 @@ namespace osu.Game.Tests.Beatmaps.Formats new Color4(255, 177, 140, 255), new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored. }; - Assert.AreEqual(expectedColors.Length, comboColors.Count); + Assert.AreEqual(expectedColors.Length, comboColors?.Count); for (int i = 0; i < expectedColors.Length; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } diff --git a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs index 6756f27ecd..9466fdf888 100644 --- a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs +++ b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Skins new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored. }; - Assert.AreEqual(expectedColors.Count, comboColors.Count); + Assert.AreEqual(expectedColors.Count, comboColors?.Count); for (int i = 0; i < expectedColors.Count; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Skins var comboColors = decoder.Decode(stream).ComboColours; var expectedColors = SkinConfiguration.DefaultComboColours; - Assert.AreEqual(expectedColors.Count, comboColors.Count); + Assert.AreEqual(expectedColors.Count, comboColors?.Count); for (int i = 0; i < expectedColors.Count; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index b0c26f7280..3f62bd038f 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -146,7 +146,8 @@ namespace osu.Game.Tests.Skins AddStep("Disallow default colours fallback in beatmap skin", () => beatmapSource.Configuration.AllowDefaultComboColoursFallback = false); AddAssert("Check retrieved combo colours from user skin", () => - requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(userSource.Configuration.ComboColours) ?? false); + userSource.Configuration.ComboColours != null && + (requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(userSource.Configuration.ComboColours) ?? false)); } [Test] diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index 49bc71064c..d0a22f9656 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -9,6 +9,7 @@ using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; @@ -175,7 +176,7 @@ namespace osu.Game.Skinning { base.Dispose(isDisposing); - if (CurrentSkin != null) + if (CurrentSkin.IsNotNull()) CurrentSkin.SourceChanged -= skinChangedImmediate; } From c908969d9b78f36538dc0cd2a788dfa311fc6c50 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 14:11:41 +0900 Subject: [PATCH 242/261] Rename `ISkinComponent` to `ISkinLookup` --- ...tchSkinComponent.cs => CatchSkinLookup.cs} | 4 ++-- .../Objects/Drawables/CaughtObject.cs | 4 ++-- .../Objects/Drawables/DrawableBanana.cs | 2 +- .../Objects/Drawables/DrawableDroplet.cs | 2 +- .../Objects/Drawables/DrawableFruit.cs | 2 +- .../Argon/CatchArgonSkinTransformer.cs | 8 +++---- .../Legacy/CatchLegacySkinTransformer.cs | 14 ++++++------ .../UI/CatchComboDisplay.cs | 2 +- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 2 +- .../UI/SkinnableCatcher.cs | 2 +- .../Skinning/TestSceneColumnBackground.cs | 4 ++-- .../Skinning/TestSceneStageBackground.cs | 2 +- .../Skinning/TestSceneStageForeground.cs | 2 +- ...niaSkinComponent.cs => ManiaSkinLookup.cs} | 6 ++--- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableNote.cs | 2 +- .../Argon/ManiaArgonSkinTransformer.cs | 10 ++++----- .../Legacy/ManiaLegacySkinTransformer.cs | 12 +++++----- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- .../UI/Components/ColumnHitObjectArea.cs | 2 +- .../UI/PoolableHitExplosion.cs | 2 +- osu.Game.Rulesets.Mania/UI/Stage.cs | 4 ++-- .../TestSceneCursorTrail.cs | 2 +- .../TestSceneGameplayCursor.cs | 2 +- .../TestSceneSkinFallbacks.cs | 4 ++-- .../Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/DrawableHitCircle.cs | 8 +++---- .../Objects/Drawables/DrawableSlider.cs | 2 +- .../Objects/Drawables/DrawableSliderBall.cs | 4 ++-- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 2 +- .../Objects/Drawables/DrawableSliderTick.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../{OsuSkinComponent.cs => OsuSkinLookup.cs} | 4 ++-- .../Skinning/Argon/OsuArgonSkinTransformer.cs | 10 ++++----- .../Skinning/Default/DefaultApproachCircle.cs | 4 ++-- .../Skinning/Default/NumberPiece.cs | 2 +- .../Skinning/Default/ReverseArrowPiece.cs | 2 +- .../Skinning/Legacy/LegacyApproachCircle.cs | 4 ++-- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 2 +- .../Skinning/Legacy/LegacyReverseArrow.cs | 2 +- .../Legacy/OsuLegacySkinTransformer.cs | 12 +++++----- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 2 +- .../UI/Cursor/OsuCursorContainer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/SmokeContainer.cs | 6 ++--- .../Skinning/TestSceneTaikoScroller.cs | 2 +- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Objects/Drawables/DrawableDrumRoll.cs | 2 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 4 ++-- .../Objects/Drawables/DrawableSwell.cs | 2 +- .../Objects/Drawables/DrawableSwellTick.cs | 2 +- .../Legacy/TaikoLegacySkinTransformer.cs | 10 ++++----- ...ikoSkinComponent.cs => TaikoSkinLookup.cs} | 4 ++-- .../UI/DrawableTaikoRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 +- .../UI/KiaiHitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +++---- .../TestSceneHitObjectAccentColour.cs | 2 +- .../Skinning/LegacySkinAnimationTest.cs | 2 +- .../TestSceneRulesetSkinProvidingContainer.cs | 2 +- .../TestSceneBeatmapSkinLookupDisables.cs | 12 +++++----- .../Skins/TestSceneSkinConfigurationLookup.cs | 2 +- .../Skins/TestSceneSkinProvidingContainer.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 2 +- .../Gameplay/TestSceneSkinnableDrawable.cs | 22 +++++++++---------- .../Gameplay/TestSceneSkinnableSound.cs | 2 +- .../Rulesets/Judgements/DrawableJudgement.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmapSkin.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 12 +++++----- .../Skinning/BeatmapSkinProvidingContainer.cs | 2 +- ...SkinComponent.cs => GameplaySkinLookup.cs} | 4 ++-- osu.Game/Skinning/ISkin.cs | 4 ++-- osu.Game/Skinning/ISkinComponent.cs | 10 --------- osu.Game/Skinning/ISkinLookup.cs | 21 ++++++++++++++++++ osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 ++--- osu.Game/Skinning/LegacySkin.cs | 12 +++++----- osu.Game/Skinning/ResourceStoreBackedSkin.cs | 2 +- osu.Game/Skinning/Skin.cs | 6 ++--- osu.Game/Skinning/SkinManager.cs | 2 +- osu.Game/Skinning/SkinProvidingContainer.cs | 14 ++++++------ osu.Game/Skinning/SkinTransformer.cs | 2 +- osu.Game/Skinning/SkinnableDrawable.cs | 20 ++++++++--------- osu.Game/Skinning/SkinnableSprite.cs | 16 +++++++------- osu.Game/Skinning/SkinnableSpriteText.cs | 4 ++-- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- ...tComponent.cs => SkinnableTargetLookup.cs} | 4 ++-- osu.Game/Skinning/TrianglesSkin.cs | 12 +++++----- .../UnsupportedSkinComponentException.cs | 4 ++-- 90 files changed, 224 insertions(+), 213 deletions(-) rename osu.Game.Rulesets.Catch/{CatchSkinComponent.cs => CatchSkinLookup.cs} (76%) rename osu.Game.Rulesets.Mania/{ManiaSkinComponent.cs => ManiaSkinLookup.cs} (79%) rename osu.Game.Rulesets.Osu/{OsuSkinComponent.cs => OsuSkinLookup.cs} (76%) rename osu.Game.Rulesets.Taiko/{TaikoSkinComponent.cs => TaikoSkinLookup.cs} (75%) rename osu.Game/Skinning/{GameplaySkinComponent.cs => GameplaySkinLookup.cs} (85%) delete mode 100644 osu.Game/Skinning/ISkinComponent.cs create mode 100644 osu.Game/Skinning/ISkinLookup.cs rename osu.Game/Skinning/{SkinnableTargetComponent.cs => SkinnableTargetLookup.cs} (73%) diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinLookup.cs similarity index 76% rename from osu.Game.Rulesets.Catch/CatchSkinComponent.cs rename to osu.Game.Rulesets.Catch/CatchSkinLookup.cs index 07c613d6ff..65bfc7ee30 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { - public class CatchSkinComponent : GameplaySkinComponent + public class CatchSkinLookup : GameplaySkinLookup { - public CatchSkinComponent(CatchSkinComponents component) + public CatchSkinLookup(CatchSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index ddfbb34435..20d348fe3d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -37,8 +37,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public override bool RemoveWhenNotAlive => true; - protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) - : base(new CatchSkinComponent(skinComponent), defaultImplementation) + protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) + : base(new CatchSkinLookup(skinComponent), defaultImplementation) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index b46a452bd0..a2b32ea9e4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Banana), + new CatchSkinLookup(CatchSkinComponents.Banana), _ => new BananaPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index d367ad0a00..210a4495e4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Droplet), + new CatchSkinLookup(CatchSkinComponents.Droplet), _ => new DropletPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index ce4c7e5aff..6359a5b35c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Fruit), + new CatchSkinLookup(CatchSkinComponents.Fruit), _ => new FruitPiece()); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 8dae0a2b78..606cd339a9 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -13,11 +13,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case CatchSkinComponent catchComponent: + case CatchSkinLookup catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) { @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon break; } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } } } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index ef83e67876..5fda40d8c0 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -25,14 +25,14 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is SkinnableTargetComponent targetComponent) + if (lookup is SkinnableTargetLookup targetComponent) { switch (targetComponent.Target) { case SkinnableTarget.MainHUDComponents: - var components = base.GetDrawableComponent(component) as SkinnableTargetComponentsContainer; + var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer; if (providesComboCounter && components != null) { @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy } } - if (component is CatchSkinComponent catchSkinComponent) + if (lookup is CatchSkinLookup catchSkinComponent) { switch (catchSkinComponent.Component) { @@ -95,11 +95,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy return null; default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } private bool hasOldStyleCatcherSprite() => @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { case CatchSkinConfiguration.FlipCatcherPlate: // Don't flip catcher plate contents if the catcher is provided by this legacy skin. - if (GetDrawableComponent(new CatchSkinComponent(CatchSkinComponents.Catcher)) != null) + if (GetDrawableComponent(new CatchSkinLookup(CatchSkinComponents.Catcher)) != null) return (IBindable)new Bindable(); break; diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index a5b7d8d0af..802e837746 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly IBindable showCombo = new BindableBool(true); public CatchComboDisplay() - : base(new CatchSkinComponent(CatchSkinComponents.CatchComboCounter), _ => Empty()) + : base(new CatchSkinLookup(CatchSkinComponents.CatchComboCounter), _ => Empty()) { } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 1ea188d463..fb55864c49 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; - InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { CentreComponent = false, Anchor = Anchor.BottomCentre, diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index 25bbc814bf..2e07e39943 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI public readonly Bindable AnimationState = new Bindable(); public SkinnableCatcher() - : base(new CatchSkinComponent(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) + : base(new CatchSkinLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) { Anchor = Anchor.TopCentre; // Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling. diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs index cd26e2a9de..8dc8e72479 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs index 0744d7e2e7..19ccf20870 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), + SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs index 979c90c802..171d2951be 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null) + SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs similarity index 79% rename from osu.Game.Rulesets.Mania/ManiaSkinComponent.cs rename to osu.Game.Rulesets.Mania/ManiaSkinLookup.cs index a074aab9da..6e6d00fee6 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs @@ -5,13 +5,13 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { - public class ManiaSkinComponent : GameplaySkinComponent + public class ManiaSkinLookup : GameplaySkinLookup { /// - /// Creates a new . + /// Creates a new . /// /// The component. - public ManiaSkinComponent(ManiaSkinComponents component) + public ManiaSkinLookup(ManiaSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 14dbc432ff..5b003e3c19 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables headContainer = new Container { RelativeSizeAxes = Axes.Both } } }, - bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece + bodyPiece = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece { RelativeSizeAxes = Axes.Both, }) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 3c8b1b53b7..25347d3dfa 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { rulesetConfig?.BindWith(ManiaRulesetSetting.TimingBasedNoteColouring, configTimingBasedNoteColouring); - AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponent(Component), _ => new DefaultNotePiece()) + AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinLookup(Component), _ => new DefaultNotePiece()) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index ae313e0b91..cf9f9f36f0 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon this.beatmap = (ManiaBeatmap)beatmap; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case ManiaSkinComponent maniaComponent: + case ManiaSkinLookup maniaComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (maniaComponent.Component) { @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon break; } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } public override IBindable? GetConfig(TLookup lookup) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs index a07dbea368..5b7ccc7bb6 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs @@ -74,14 +74,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy }); } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: return getResult(resultComponent.Component); - case ManiaSkinComponent maniaComponent: + case ManiaSkinLookup maniaComponent: if (!isLegacySkin.Value || !hasKeyTexture.Value) return null; @@ -120,11 +120,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy return new LegacyStageForeground(); default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } private Drawable getResult(HitResult result) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 3d46bdaa7b..4eed75a90d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.UI skin.SourceChanged += onSourceChanged; onSourceChanged(); - Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Drawable background = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both, }; @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI // For input purposes, the background is added at the highest depth, but is then proxied back below all other elements background.CreateProxy(), HitObjectArea, - keyArea = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) + keyArea = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index b26b62f8a5..d02e4afc81 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components RelativeSizeAxes = Axes.Both, Depth = 2, }, - hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) + hitTarget = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) { RelativeSizeAxes = Axes.X, Depth = 1 diff --git a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs index a7b94f9f22..faf345545d 100644 --- a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 1273cb3d32..5d08e38aef 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI AutoSizeAxes = Axes.X, Children = new Drawable[] { - new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) + new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { RelativeSizeAxes = Axes.Both }, @@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y, } }, - new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null) + new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs index d3e70a0a01..aeadbea510 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Tests RelativeSizeAxes = Axes.Both; } - public Drawable GetDrawableComponent(ISkinComponent component) => null; + public Drawable GetDrawableComponent(ISkinLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index 360815afbf..f88948ce13 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests private class TopLeftCursorSkin : ISkin { - public Drawable GetDrawableComponent(ISkinComponent component) => null; + public Drawable GetDrawableComponent(ISkinLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null; public ISample GetSample(ISampleInfo sampleInfo) => null; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 036f90b962..c012dae635 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -149,11 +149,11 @@ namespace osu.Game.Rulesets.Osu.Tests this.identifier = identifier; } - public Drawable GetDrawableComponent(ISkinComponent component) + public Drawable GetDrawableComponent(ISkinLookup lookup) { if (!enabled) return null; - if (component is OsuSkinComponent osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) + if (lookup is OsuSkinLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) return null; return new OsuSpriteText diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 36d8ba0189..22037c873c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections { Origin = Anchor.Centre; - InternalChild = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new CircularContainer + InternalChild = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer { Masking = true, AutoSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index d420091499..bcb3ccae41 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -81,12 +81,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - CirclePiece = new SkinnableDrawable(new OsuSkinComponent(CirclePieceComponent), _ => new MainCirclePiece()) + CirclePiece = new SkinnableDrawable(new OsuSkinLookup(CirclePieceComponent), _ => new MainCirclePiece()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) + ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -278,8 +278,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public override bool RemoveWhenNotAlive => false; - public ProxyableSkinnableDrawable(ISkinComponent component, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) - : base(component, defaultImplementation, confineMode) + public ProxyableSkinnableDrawable(ISkinLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + : base(lookup, defaultImplementation, confineMode) { } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 785d15c15b..3fdbc3dacd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), + Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), tailContainer = new Container { RelativeSizeAxes = Axes.Both }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, repeatContainer = new Container { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index 9966ad3a90..86d41f0cbf 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new[] { - new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) + new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Masking = true }, - ball = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) + ball = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index a02cc9227e..1b8a17b6df 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index 6270d6709b..e8c6e80109 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) } }, }); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 4bd98fc8b2..f591cd15d4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Origin = Anchor.Centre; - AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer + AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer { Masking = true, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 6ae9d5bc34..7d0e29bd93 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Y, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), + Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), RotationTracker = new SpinnerRotationTracker(this) } }, diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinLookup.cs similarity index 76% rename from osu.Game.Rulesets.Osu/OsuSkinComponent.cs rename to osu.Game.Rulesets.Osu/OsuSkinLookup.cs index aa59bd572e..4048e95e4b 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { - public class OsuSkinComponent : GameplaySkinComponent + public class OsuSkinLookup : GameplaySkinLookup { - public OsuSkinComponent(OsuSkinComponents component) + public OsuSkinLookup(OsuSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs index bf507db50c..bf664bb606 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs @@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case OsuSkinComponent osuComponent: + case OsuSkinLookup osuComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (osuComponent.Component) { @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon break; } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index e991bc6cf3..2b2c31dcf7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -35,9 +35,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default accentColour.BindValueChanged(colour => Colour = colour.NewValue, true); } - protected override Drawable CreateDefault(ISkinComponent component) + protected override Drawable CreateDefault(ISkinLookup lookup) { - var drawable = base.CreateDefault(component); + var drawable = base.CreateDefault(lookup); // Although this is a non-legacy component, osu-resources currently stores approach circle as a legacy-like texture. // See LegacyApproachCircle for documentation as to why this is required. diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index 43d8d1e27f..39e07ebb99 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Colour = Color4.White.Opacity(0.5f), }, }, - number = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + number = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 1fce512f53..338e7abcfc 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon + Child = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index fa5c5b84e4..20a1e3064e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -35,9 +35,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); } - protected override Drawable CreateDefault(ISkinComponent component) + protected override Drawable CreateDefault(ISkinLookup lookup) { - var drawable = base.CreateDefault(component); + var drawable = base.CreateDefault(lookup); // account for the sprite being used for the default approach circle being taken from stable, // when hitcircles have 5px padding on each size. this should be removed if we update the sprite. diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index a6e62b83e4..357be4cda8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy if (hasNumber) { - OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index 7e9626eb7f..f374af1cba 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { AutoSizeAxes = Axes.Both; - string lookupName = new OsuSkinComponent(OsuSkinComponents.ReverseArrow).LookupName; + string lookupName = new OsuSkinLookup(OsuSkinComponents.ReverseArrow).LookupName; var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null); InternalChild = skin?.GetAnimation(lookupName, true, true) ?? Empty(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 3bc2668733..2faa2d678e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -28,17 +28,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null); } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is OsuSkinComponent osuComponent) + if (lookup is OsuSkinLookup osuComponent) { switch (osuComponent.Component) { case OsuSkinComponents.FollowPoint: - return this.GetAnimation(component.LookupName, true, true, true, startAtCurrentTime: false); + return this.GetAnimation(lookup.LookupName, true, true, true, startAtCurrentTime: false); case OsuSkinComponents.SliderScorePoint: - return this.GetAnimation(component.LookupName, false, false); + return this.GetAnimation(lookup.LookupName, false, false); case OsuSkinComponents.SliderFollowCircle: var followCircleContent = this.GetAnimation("sliderfollowcircle", true, true, true); @@ -136,11 +136,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return new LegacyApproachCircle(); default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } public override IBindable? GetConfig(TLookup lookup) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 15ef7e538b..78b920c771 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, - Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) + Child = cursorSprite = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 533db3ddfe..396492c104 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -47,8 +47,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Children = new[] { - cursorTrail = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), - new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), + cursorTrail = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), + new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; } diff --git a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs index beba834e88..2616bb0325 100644 --- a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.UI { if (e.Action == OsuAction.Smoke) { - AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); + AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); // Add initial position immediately. addPosition(); @@ -68,8 +68,8 @@ namespace osu.Game.Rulesets.Osu.UI public override double LifetimeStart => Drawable.LifetimeStart; public override double LifetimeEnd => Drawable.LifetimeEnd; - public SmokeSkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) - : base(component, defaultImplementation, confineMode) + public SmokeSkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + : base(lookup, defaultImplementation, confineMode) { } } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs index 954b4be7f3..3076172d46 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning public TestSceneTaikoScroller() { AddStep("Load scroller", () => SetContents(_ => - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty()) + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) { Clock = new FramedClock(clock), Height = 0.4f, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index e4806c4a12..715add7914 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables AddRangeInternal(new Drawable[] { - line = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new Box + line = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.BarLine), _ => new Box { RelativeSizeAxes = Axes.Both, EdgeSmoothness = new Vector2(0.5f, 0), diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 98dad96cf6..f5ebecdee5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return base.CreateNestedHitObject(hitObject); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollBody), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollBody), _ => new ElongatedCirclePiece()); public override bool OnPressed(KeyBindingPressEvent e) => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 451c5a793b..1ec2562f67 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 484f125a09..0fe17f81f5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -90,8 +90,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre - ? new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) - : new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); + ? new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) + : new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); public override IEnumerable GetSamples() { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index a6f6edba09..5b498e4cb3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Swell), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Swell), _ => new SwellCirclePiece { // to allow for rotation transform diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index b2a54176fb..4d915c91d3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public override bool OnPressed(KeyBindingPressEvent e) => false; - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs index 020cdab4dc..6cf7d3da0a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs @@ -27,16 +27,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy hasExplosion = new Lazy(() => GetTexture(getHitName(TaikoSkinComponents.TaikoExplosionGreat)) != null); } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is GameplaySkinComponent) + if (lookup is GameplaySkinLookup) { // if a taiko skin is providing explosion sprites, hide the judgements completely if (hasExplosion.Value) return Drawable.Empty().With(d => d.Expire()); } - if (component is TaikoSkinComponent taikoComponent) + if (lookup is TaikoSkinLookup taikoComponent) { switch (taikoComponent.Component) { @@ -130,11 +130,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy return new DrawableTaikoMascot(); default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } private string getHitName(TaikoSkinComponents component) diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs similarity index 75% rename from osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs rename to osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs index 30bfb605aa..cb8bbd8b18 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko { - public class TaikoSkinComponent : GameplaySkinComponent + public class TaikoSkinLookup : GameplaySkinLookup { - public TaikoSkinComponent(TaikoSkinComponents component) + public TaikoSkinLookup(TaikoSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 58e703b8be..db45c8bb70 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.UI { new BarLineGenerator(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar)); - FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty()) + FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) { RelativeSizeAxes = Axes.X, Depth = float.MaxValue diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 10a7495c62..560f7b1748 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinComponent(getComponentName(result)), _ => new DefaultHitExplosion(result)); + InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinLookup(getComponentName(result)), _ => new DefaultHitExplosion(result)); skinnable.OnSkinChanged += runAnimation; } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 6d5b6c5f5d..4458fb1bc0 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.UI { Children = new Drawable[] { - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) { RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index c4cff00d2a..b0d853f1f1 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); + Child = skinnable = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index f2d7811f44..0de7bf233d 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.UI InternalChildren = new[] { - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), new Container { Name = "Left overlay", @@ -86,11 +86,11 @@ namespace osu.Game.Rulesets.Taiko.UI BorderColour = colours.Gray0, Children = new[] { - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), inputDrum.CreateProxy(), } }, - mascot = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Mascot), _ => Empty()) + mascot = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Mascot), _ => Empty()) { Origin = Anchor.BottomLeft, Anchor = Anchor.TopLeft, @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - HitTarget = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) + HitTarget = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 9701a32951..fc72fddcae 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Gameplay Color4.Green }; - public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotImplementedException(); + public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs index 6297d9cdc7..9e03663a49 100644 --- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs +++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.NonVisual.Skinning return lookup_names.Contains(componentName) ? renderer.WhitePixel : null; } - public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotSupportedException(); + public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotSupportedException(); public ISample GetSample(ISampleInfo sampleInfo) => throw new NotSupportedException(); public IBindable GetConfig(TLookup lookup) => throw new NotSupportedException(); } diff --git a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs index 320373699d..6f14b933ee 100644 --- a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs +++ b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Rulesets OnLoadAsync?.Invoke(); } - public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS = default, WrapMode wrapModeT = default) => skin.GetTexture(componentName); diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs index 004e253c1f..7c02d34b1c 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Skins string expected = allowBeatmapLookups ? "beatmap" : "user"; - AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinComponent())?.Name == expected); + AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinLookup())?.Name == expected); } [TestCase(false)] @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Skins ISkin expected() => allowBeatmapLookups ? beatmapSource : userSource; - AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinComponent()) != null) == expected()); + AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinLookup()) != null) == expected()); } public class UserSkinSource : LegacySkin @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable GetDrawableComponent(ISkinLookup lookup) { return new Container { Name = "user" }; } @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable GetDrawableComponent(ISkinLookup lookup) { return new Container { Name = "beatmap" }; } @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Skins public ISkin FindProvider(Func lookupFunction) => skin.FindProvider(lookupFunction); } - private class TestSkinComponent : ISkinComponent + private class TestSkinLookup : ISkinLookup { public string LookupName => string.Empty; } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index 3f62bd038f..4cbc1cf4df 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -221,7 +221,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs index f7c88643fe..712d5ce969 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Skins this.renderer = renderer; } - public Drawable GetDrawableComponent(ISkinComponent component) => throw new System.NotImplementedException(); + public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new System.NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 01cc856a4a..6fe6a85b8f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); - var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetComponent(target)); + var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetLookup(target)); if (expectedComponentsContainer == null) return false; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index d4fba76c37..81c5211878 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private bool allow = true; - protected override bool AllowDrawableLookup(ISkinComponent component) => allow; + protected override bool AllowDrawableLookup(ISkinLookup lookup) => allow; public void Disable() { @@ -182,8 +182,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public new Drawable Drawable => base.Drawable; - public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) - : base(new TestSkinComponent(name), defaultImplementation, confineMode) + public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) + : base(new TestSkinLookup(name), defaultImplementation, confineMode) { } } @@ -251,8 +251,8 @@ namespace osu.Game.Tests.Visual.Gameplay public new Drawable Drawable => base.Drawable; public int SkinChangedCount { get; private set; } - public SkinConsumer(string name, Func defaultImplementation) - : base(new TestSkinComponent(name), defaultImplementation) + public SkinConsumer(string name, Func defaultImplementation) + : base(new TestSkinLookup(name), defaultImplementation) { } @@ -288,8 +288,8 @@ namespace osu.Game.Tests.Visual.Gameplay this.size = size; } - public Drawable GetDrawableComponent(ISkinComponent componentName) => - componentName.LookupName == "available" + public Drawable GetDrawableComponent(ISkinLookup lookupName) => + lookupName.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, @@ -306,7 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class SecondarySource : ISkin { - public Drawable GetDrawableComponent(ISkinComponent componentName) => new SecondarySourceBox(); + public Drawable GetDrawableComponent(ISkinLookup lookupName) => new SecondarySourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -318,7 +318,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached(typeof(ISkinSource))] private class SkinSourceContainer : Container, ISkinSource { - public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox(); + public Drawable GetDrawableComponent(ISkinLookup lookupName) => new BaseSourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -337,9 +337,9 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class TestSkinComponent : ISkinComponent + private class TestSkinLookup : ISkinLookup { - public TestSkinComponent(string name) + public TestSkinLookup(string name) { LookupName = name; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 0ba112ec40..43206ac591 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual.Gameplay IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled; - public Drawable GetDrawableComponent(ISkinComponent component) => source?.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => source?.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => source?.GetConfig(lookup); diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 7e1196d4ca..bfcdd384a0 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Judgements if (JudgementBody != null) RemoveInternal(JudgementBody, true); - AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponent(type), _ => + AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinLookup(type), _ => CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling) { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs index a106a60379..bc63ad063c 100644 --- a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs +++ b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit #region Delegated ISkin implementation - public Drawable GetDrawableComponent(ISkinComponent component) => Skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Skin.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => Skin.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => Skin.GetConfig(lookup); diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 20e4290725..f65cee8a69 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -81,14 +81,14 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (base.GetDrawableComponent(component) is Drawable c) + if (base.GetDrawableComponent(lookup) is Drawable c) return c; - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: switch (target.Target) { case SkinnableTarget.SongSelect: @@ -178,14 +178,14 @@ namespace osu.Game.Skinning return null; } - switch (component.LookupName) + switch (lookup.LookupName) { // Temporary until default skin has a valid hit lighting. case @"lighting": return Drawable.Empty(); } - if (GetTexture(component.LookupName) is Texture t) + if (GetTexture(lookup.LookupName) is Texture t) return new Sprite { Texture = t }; return null; diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index f0caef9fa1..ec9d52f5c6 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Skinning } } - protected override bool AllowDrawableLookup(ISkinComponent component) + protected override bool AllowDrawableLookup(ISkinLookup lookup) { if (beatmapSkins == null) throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); diff --git a/osu.Game/Skinning/GameplaySkinComponent.cs b/osu.Game/Skinning/GameplaySkinLookup.cs similarity index 85% rename from osu.Game/Skinning/GameplaySkinComponent.cs rename to osu.Game/Skinning/GameplaySkinLookup.cs index 6f5dad2207..cec9dbde7d 100644 --- a/osu.Game/Skinning/GameplaySkinComponent.cs +++ b/osu.Game/Skinning/GameplaySkinLookup.cs @@ -5,12 +5,12 @@ using System.Linq; namespace osu.Game.Skinning { - public class GameplaySkinComponent : ISkinComponent + public class GameplaySkinLookup : ISkinLookup where T : notnull { public readonly T Component; - public GameplaySkinComponent(T component) + public GameplaySkinLookup(T component) { Component = component; } diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index c093dc2f32..c352dfef5c 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -17,9 +17,9 @@ namespace osu.Game.Skinning /// /// Retrieve a component implementation. /// - /// The requested component. + /// The requested component. /// A drawable representation for the requested component, or null if unavailable. - Drawable? GetDrawableComponent(ISkinComponent component); + Drawable? GetDrawableComponent(ISkinLookup lookup); /// /// Retrieve a . diff --git a/osu.Game/Skinning/ISkinComponent.cs b/osu.Game/Skinning/ISkinComponent.cs deleted file mode 100644 index 4bd9f21b6b..0000000000 --- a/osu.Game/Skinning/ISkinComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public interface ISkinComponent - { - string LookupName { get; } - } -} diff --git a/osu.Game/Skinning/ISkinLookup.cs b/osu.Game/Skinning/ISkinLookup.cs new file mode 100644 index 0000000000..4daea35e82 --- /dev/null +++ b/osu.Game/Skinning/ISkinLookup.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + /// + /// A lookup type which can be used with . + /// + /// + /// Implementations of should match on types implementing this interface + /// to scope particular lookup variations. Using this, a ruleset or skin implementation could make its own lookup + /// type to scope away from more global contexts. + /// + /// More commonly, a ruleset could make use of to do a simple lookup based on + /// a provided enum. + /// + public interface ISkinLookup + { + string LookupName { get; } + } +} diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index e8414b4c11..2aa76b5871 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -43,9 +43,9 @@ namespace osu.Game.Skinning return new RealmBackedResourceStore(beatmapInfo.BeatmapSet.ToLive(resources.RealmAccess), resources.Files, resources.RealmAccess); } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is SkinnableTargetComponent targetComponent) + if (lookup is SkinnableTargetLookup targetComponent) { switch (targetComponent.Target) { @@ -59,7 +59,7 @@ namespace osu.Game.Skinning } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } public override IBindable? GetConfig(TLookup lookup) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index bfc60de2c9..97833d0e28 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -322,14 +322,14 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (base.GetDrawableComponent(component) is Drawable c) + if (base.GetDrawableComponent(lookup) is Drawable c) return c; - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: switch (target.Target) { case SkinnableTarget.MainHUDComponents: @@ -379,7 +379,7 @@ namespace osu.Game.Skinning return null; - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: // kind of wasteful that we throw this away, but should do for now. if (getJudgementAnimation(resultComponent.Component) != null) @@ -397,7 +397,7 @@ namespace osu.Game.Skinning return null; - case SkinnableSprite.SpriteComponent sprite: + case SkinnableSprite.SpriteLookup sprite: return this.GetAnimation(sprite.LookupName, false, false); } diff --git a/osu.Game/Skinning/ResourceStoreBackedSkin.cs b/osu.Game/Skinning/ResourceStoreBackedSkin.cs index efdbb0a207..1b846438f5 100644 --- a/osu.Game/Skinning/ResourceStoreBackedSkin.cs +++ b/osu.Game/Skinning/ResourceStoreBackedSkin.cs @@ -27,7 +27,7 @@ namespace osu.Game.Skinning samples = audio.GetSampleStore(new NamespacedResourceStore(resources, @"Samples")); } - public Drawable? GetDrawableComponent(ISkinComponent component) => null; + public Drawable? GetDrawableComponent(ISkinLookup lookup) => null; public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => textures.Get(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index dd43e4dc54..a14b1e1359 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -154,11 +154,11 @@ namespace osu.Game.Skinning DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSkinnableInfo().ToArray(); } - public virtual Drawable? GetDrawableComponent(ISkinComponent component) + public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: if (!DrawableComponentInfo.TryGetValue(target.Target, out var skinnableInfo)) return null; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 0e66278fc0..bd4078b985 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -201,7 +201,7 @@ namespace osu.Game.Skinning public event Action SourceChanged; - public Drawable GetDrawableComponent(ISkinComponent component) => lookupWithFallback(s => s.GetDrawableComponent(component)); + public Drawable GetDrawableComponent(ISkinLookup lookup) => lookupWithFallback(s => s.GetDrawableComponent(lookup)); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => lookupWithFallback(s => s.GetTexture(componentName, wrapModeS, wrapModeT)); diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 5c5e9ae0fc..0ed5c6b736 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Skinning /// protected virtual bool AllowFallingBackToParent => true; - protected virtual bool AllowDrawableLookup(ISkinComponent component) => true; + protected virtual bool AllowDrawableLookup(ISkinLookup lookup) => true; protected virtual bool AllowTextureLookup(string componentName) => true; @@ -107,19 +107,19 @@ namespace osu.Game.Skinning } } - public Drawable? GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinLookup lookup) { foreach (var (_, lookupWrapper) in skinSources) { Drawable? sourceDrawable; - if ((sourceDrawable = lookupWrapper.GetDrawableComponent(component)) != null) + if ((sourceDrawable = lookupWrapper.GetDrawableComponent(lookup)) != null) return sourceDrawable; } if (!AllowFallingBackToParent) return null; - return ParentSource?.GetDrawableComponent(component); + return ParentSource?.GetDrawableComponent(lookup); } public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) @@ -238,10 +238,10 @@ namespace osu.Game.Skinning this.provider = provider; } - public Drawable? GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (provider.AllowDrawableLookup(component)) - return skin.GetDrawableComponent(component); + if (provider.AllowDrawableLookup(lookup)) + return skin.GetDrawableComponent(lookup); return null; } diff --git a/osu.Game/Skinning/SkinTransformer.cs b/osu.Game/Skinning/SkinTransformer.cs index 4da60f1e43..9772d98fde 100644 --- a/osu.Game/Skinning/SkinTransformer.cs +++ b/osu.Game/Skinning/SkinTransformer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning Skin = skin ?? throw new ArgumentNullException(nameof(skin)); } - public virtual Drawable? GetDrawableComponent(ISkinComponent component) => Skin.GetDrawableComponent(component); + public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); public virtual Texture? GetTexture(string componentName) => GetTexture(componentName, default, default); diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index c6321553c7..4398dda413 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -31,25 +31,25 @@ namespace osu.Game.Skinning set => base.AutoSizeAxes = value; } - protected readonly ISkinComponent Component; + protected readonly ISkinLookup Lookup; private readonly ConfineMode confineMode; /// /// Create a new skinnable drawable. /// - /// The namespace-complete resource name for this skinnable element. + /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) - : this(component, confineMode) + public SkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + : this(lookup, confineMode) { createDefault = defaultImplementation; } - protected SkinnableDrawable(ISkinComponent component, ConfineMode confineMode = ConfineMode.NoScaling) + protected SkinnableDrawable(ISkinLookup lookup, ConfineMode confineMode = ConfineMode.NoScaling) { - Component = component; + Lookup = lookup; this.confineMode = confineMode; RelativeSizeAxes = Axes.Both; @@ -60,13 +60,13 @@ namespace osu.Game.Skinning /// public void ResetAnimation() => (Drawable as IFramedAnimation)?.GotoFrame(0); - private readonly Func? createDefault; + private readonly Func? createDefault; private readonly Cached scaling = new Cached(); private bool isDefault; - protected virtual Drawable CreateDefault(ISkinComponent component) => createDefault?.Invoke(component) ?? Empty(); + protected virtual Drawable CreateDefault(ISkinLookup lookup) => createDefault?.Invoke(lookup) ?? Empty(); /// /// Whether to apply size restrictions (specified via ) to the default implementation. @@ -75,11 +75,11 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin) { - var retrieved = skin.GetDrawableComponent(Component); + var retrieved = skin.GetDrawableComponent(Lookup); if (retrieved == null) { - Drawable = CreateDefault(Component); + Drawable = CreateDefault(Lookup); isDefault = true; } else diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index f8130f31c3..8f456fce0a 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -34,42 +34,42 @@ namespace osu.Game.Skinning private ISkinSource source { get; set; } = null!; public SkinnableSprite(string textureName, ConfineMode confineMode = ConfineMode.NoScaling) - : base(new SpriteComponent(textureName), confineMode) + : base(new SpriteLookup(textureName), confineMode) { SpriteName.Value = textureName; } public SkinnableSprite() - : base(new SpriteComponent(string.Empty), ConfineMode.NoScaling) + : base(new SpriteLookup(string.Empty), ConfineMode.NoScaling) { RelativeSizeAxes = Axes.None; AutoSizeAxes = Axes.Both; SpriteName.BindValueChanged(name => { - ((SpriteComponent)Component).LookupName = name.NewValue ?? string.Empty; + ((SpriteLookup)Lookup).LookupName = name.NewValue ?? string.Empty; if (IsLoaded) SkinChanged(CurrentSkin); }); } - protected override Drawable CreateDefault(ISkinComponent component) + protected override Drawable CreateDefault(ISkinLookup lookup) { - var texture = textures.Get(component.LookupName); + var texture = textures.Get(lookup.LookupName); if (texture == null) - return new SpriteNotFound(component.LookupName); + return new SpriteNotFound(lookup.LookupName); return new Sprite { Texture = texture }; } public bool UsesFixedAnchor { get; set; } - internal class SpriteComponent : ISkinComponent + internal class SpriteLookup : ISkinLookup { public string LookupName { get; set; } - public SpriteComponent(string textureName) + public SpriteLookup(string textureName) { LookupName = textureName; } diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 2bde3c4180..8cc48a76ed 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -9,8 +9,8 @@ namespace osu.Game.Skinning { public class SkinnableSpriteText : SkinnableDrawable, IHasText { - public SkinnableSpriteText(ISkinComponent component, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) - : base(component, defaultImplementation, confineMode) + public SkinnableSpriteText(ISkinLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) + : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 708ad4ec47..b0262ce07a 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -39,7 +39,7 @@ namespace osu.Game.Skinning components.Clear(); ComponentsLoaded = false; - content = CurrentSkin.GetDrawableComponent(new SkinnableTargetComponent(Target)) as SkinnableTargetComponentsContainer; + content = CurrentSkin.GetDrawableComponent(new SkinnableTargetLookup(Target)) as SkinnableTargetComponentsContainer; cancellationSource?.Cancel(); cancellationSource = null; diff --git a/osu.Game/Skinning/SkinnableTargetComponent.cs b/osu.Game/Skinning/SkinnableTargetLookup.cs similarity index 73% rename from osu.Game/Skinning/SkinnableTargetComponent.cs rename to osu.Game/Skinning/SkinnableTargetLookup.cs index a17aafe6e7..df03123e85 100644 --- a/osu.Game/Skinning/SkinnableTargetComponent.cs +++ b/osu.Game/Skinning/SkinnableTargetLookup.cs @@ -3,13 +3,13 @@ namespace osu.Game.Skinning { - public class SkinnableTargetComponent : ISkinComponent + public class SkinnableTargetLookup : ISkinLookup { public readonly SkinnableTarget Target; public string LookupName => Target.ToString(); - public SkinnableTargetComponent(SkinnableTarget target) + public SkinnableTargetLookup(SkinnableTarget target) { Target = target; } diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index d00874aa8f..32b4b6b4d4 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -59,14 +59,14 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (base.GetDrawableComponent(component) is Drawable c) + if (base.GetDrawableComponent(lookup) is Drawable c) return c; - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: switch (target.Target) { case SkinnableTarget.SongSelect: @@ -156,14 +156,14 @@ namespace osu.Game.Skinning return null; } - switch (component.LookupName) + switch (lookup.LookupName) { // Temporary until default skin has a valid hit lighting. case @"lighting": return Drawable.Empty(); } - if (GetTexture(component.LookupName) is Texture t) + if (GetTexture(lookup.LookupName) is Texture t) return new Sprite { Texture = t }; return null; diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 7f0dd51d5b..32fc6661b0 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -7,8 +7,8 @@ namespace osu.Game.Skinning { public class UnsupportedSkinComponentException : Exception { - public UnsupportedSkinComponentException(ISkinComponent component) - : base($@"Unsupported component type: {component.GetType()} (lookup: ""{component.LookupName}"").") + public UnsupportedSkinComponentException(ISkinLookup lookup) + : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup.LookupName}"").") { } } From e75c3b3f94fa17bd18ff58e0c9ec2419453e606d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:03:29 +0900 Subject: [PATCH 243/261] Rename `SkinnableTarget` to `GlobalSkinLookup` --- .../Legacy/CatchLegacySkinTransformer.cs | 6 ++--- .../Skins/SkinDeserialisationTest.cs | 16 ++++++------- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 6 ++--- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 8 +++---- osu.Game/Skinning/Editor/SkinEditor.cs | 2 +- osu.Game/Skinning/GlobalSkinLookup.cs | 23 +++++++++++++++++++ osu.Game/Skinning/ISkinnableDrawable.cs | 5 ++++ osu.Game/Skinning/ISkinnableTarget.cs | 2 +- osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 ++--- osu.Game/Skinning/LegacySkin.cs | 6 ++--- osu.Game/Skinning/Skin.cs | 10 ++++---- osu.Game/Skinning/SkinnableTarget.cs | 11 --------- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 ++--- osu.Game/Skinning/SkinnableTargetLookup.cs | 17 -------------- osu.Game/Skinning/TrianglesSkin.cs | 8 +++---- 17 files changed, 68 insertions(+), 68 deletions(-) create mode 100644 osu.Game/Skinning/GlobalSkinLookup.cs delete mode 100644 osu.Game/Skinning/SkinnableTarget.cs delete mode 100644 osu.Game/Skinning/SkinnableTargetLookup.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 5fda40d8c0..83a8a37676 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -27,11 +27,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (lookup is SkinnableTargetLookup targetComponent) + if (lookup is GlobalSkinLookup targetComponent) { - switch (targetComponent.Target) + switch (targetComponent.Lookup) { - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer; if (providesComboCounter && components != null) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 989459632e..4398d870a0 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(9)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); } } @@ -93,10 +93,10 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(6)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.SongSelect], Has.Length.EqualTo(1)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); - var skinnableInfo = skin.DrawableComponentInfo[SkinnableTarget.SongSelect].First(); + var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect].First(); Assert.That(skinnableInfo.Type, Is.EqualTo(typeof(SkinnableSprite))); Assert.That(skinnableInfo.Settings.First().Key, Is.EqualTo("sprite_name")); @@ -107,10 +107,10 @@ namespace osu.Game.Tests.Skins using (var storage = new ZipArchiveReader(stream)) { var skin = new TestSkin(new SkinInfo(), null, storage); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(8)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 6fe6a85b8f..69a50a1cd1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Gameplay { CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null)); AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); - AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value)); + AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); } protected void CreateSkinTest(SkinInfo gameCurrentSkin, Func getBeatmapSkin) @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - protected bool AssertComponentsFromExpectedSource(SkinnableTarget target, ISkin expectedSource) + protected bool AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType target, ISkin expectedSource) { var actualComponentsContainer = Player.ChildrenOfType().First(s => s.Target == target) .ChildrenOfType().SingleOrDefault(); @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); - var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetLookup(target)); + var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinLookup(target)); if (expectedComponentsContainer == null) return false; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 2791f5ff8f..932ebe7d18 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -391,7 +391,7 @@ namespace osu.Game.Screens.Play private OsuConfigManager config { get; set; } public MainComponentsContainer() - : base(SkinnableTarget.MainHUDComponents) + : base(GlobalSkinLookup.LookupType.MainHUDComponents) { RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 4b2417aab4..e525d5a368 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -250,7 +250,7 @@ namespace osu.Game.Screens.Select } } }, - new SkinnableTargetContainer(SkinnableTarget.SongSelect) + new SkinnableTargetContainer(GlobalSkinLookup.LookupType.SongSelect) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index f65cee8a69..7aaf1a0e89 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -88,10 +88,10 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinnableTargetLookup target: - switch (target.Target) + case GlobalSkinLookup globalLookup: + switch (globalLookup.Lookup) { - case SkinnableTarget.SongSelect: + case GlobalSkinLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -99,7 +99,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index c1ff161f25..fdc8b6b2ad 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -314,7 +314,7 @@ namespace osu.Game.Skinning.Editor private ISkinnableTarget getFirstTarget() => availableTargets.FirstOrDefault(); - private ISkinnableTarget getTarget(SkinnableTarget target) + private ISkinnableTarget getTarget(GlobalSkinLookup.LookupType target) { return availableTargets.FirstOrDefault(c => c.Target == target); } diff --git a/osu.Game/Skinning/GlobalSkinLookup.cs b/osu.Game/Skinning/GlobalSkinLookup.cs new file mode 100644 index 0000000000..c63c0315a3 --- /dev/null +++ b/osu.Game/Skinning/GlobalSkinLookup.cs @@ -0,0 +1,23 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + public class GlobalSkinLookup : ISkinLookup + { + public readonly LookupType Lookup; + + public string LookupName => Lookup.ToString(); + + public GlobalSkinLookup(LookupType lookup) + { + Lookup = lookup; + } + + public enum LookupType + { + MainHUDComponents, + SongSelect + } + } +} diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISkinnableDrawable.cs index 3fc6a2fdd8..1ecd6f967e 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISkinnableDrawable.cs @@ -5,12 +5,17 @@ using System; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; +using osu.Game.Configuration; namespace osu.Game.Skinning { /// /// Denotes a drawable which, as a drawable, can be adjusted via skinning specifications. /// + /// + /// Attaching this interface to any will make it serialisable to skin settings. + /// Adding annotated bindables will also serialise these settings alongside each instance. + /// public interface ISkinnableDrawable : IDrawable { /// diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 8d4f4dd0c3..b1a0f6714b 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -18,7 +18,7 @@ namespace osu.Game.Skinning /// /// The definition of this target. /// - SkinnableTarget Target { get; } + GlobalSkinLookup.LookupType Target { get; } /// /// A bindable list of components which are being tracked by this skinnable target. diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 2aa76b5871..1d6ded6fee 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -45,11 +45,11 @@ namespace osu.Game.Skinning public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (lookup is SkinnableTargetLookup targetComponent) + if (lookup is GlobalSkinLookup targetComponent) { - switch (targetComponent.Target) + switch (targetComponent.Lookup) { - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: // this should exist in LegacySkin instead, but there isn't a fallback skin for LegacySkins yet. // therefore keep the check here until fallback default legacy skin is supported. if (!this.HasFont(LegacyFont.Score)) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 97833d0e28..75957bb560 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -329,10 +329,10 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinnableTargetLookup target: - switch (target.Target) + case GlobalSkinLookup target: + switch (target.Lookup) { - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index a14b1e1359..67b74229bb 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -37,9 +37,9 @@ namespace osu.Game.Skinning public SkinConfiguration Configuration { get; set; } - public IDictionary DrawableComponentInfo => drawableComponentInfo; + public IDictionary DrawableComponentInfo => drawableComponentInfo; - private readonly Dictionary drawableComponentInfo = new Dictionary(); + private readonly Dictionary drawableComponentInfo = new Dictionary(); public abstract ISample? GetSample(ISampleInfo sampleInfo); @@ -97,7 +97,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); // skininfo files may be null for default skin. - foreach (SkinnableTarget skinnableTarget in Enum.GetValues(typeof(SkinnableTarget))) + foreach (GlobalSkinLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinLookup.LookupType))) { string filename = $"{skinnableTarget}.json"; @@ -158,8 +158,8 @@ namespace osu.Game.Skinning { switch (lookup) { - case SkinnableTargetLookup target: - if (!DrawableComponentInfo.TryGetValue(target.Target, out var skinnableInfo)) + case GlobalSkinLookup target: + if (!DrawableComponentInfo.TryGetValue(target.Lookup, out var skinnableInfo)) return null; var components = new List(); diff --git a/osu.Game/Skinning/SkinnableTarget.cs b/osu.Game/Skinning/SkinnableTarget.cs deleted file mode 100644 index 09de8a5d71..0000000000 --- a/osu.Game/Skinning/SkinnableTarget.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public enum SkinnableTarget - { - MainHUDComponents, - SongSelect - } -} diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index b0262ce07a..bea29b0da3 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private SkinnableTargetComponentsContainer? content; - public SkinnableTarget Target { get; } + public GlobalSkinLookup.LookupType Target { get; } public IBindableList Components => components; @@ -25,7 +25,7 @@ namespace osu.Game.Skinning private CancellationTokenSource? cancellationSource; - public SkinnableTargetContainer(SkinnableTarget target) + public SkinnableTargetContainer(GlobalSkinLookup.LookupType target) { Target = target; } @@ -39,7 +39,7 @@ namespace osu.Game.Skinning components.Clear(); ComponentsLoaded = false; - content = CurrentSkin.GetDrawableComponent(new SkinnableTargetLookup(Target)) as SkinnableTargetComponentsContainer; + content = CurrentSkin.GetDrawableComponent(new GlobalSkinLookup(Target)) as SkinnableTargetComponentsContainer; cancellationSource?.Cancel(); cancellationSource = null; diff --git a/osu.Game/Skinning/SkinnableTargetLookup.cs b/osu.Game/Skinning/SkinnableTargetLookup.cs deleted file mode 100644 index df03123e85..0000000000 --- a/osu.Game/Skinning/SkinnableTargetLookup.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public class SkinnableTargetLookup : ISkinLookup - { - public readonly SkinnableTarget Target; - - public string LookupName => Target.ToString(); - - public SkinnableTargetLookup(SkinnableTarget target) - { - Target = target; - } - } -} diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 32b4b6b4d4..e3729136b9 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -66,10 +66,10 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinnableTargetLookup target: - switch (target.Target) + case GlobalSkinLookup target: + switch (target.Lookup) { - case SkinnableTarget.SongSelect: + case GlobalSkinLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -77,7 +77,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); From 1aa0e40f2f4111d6c52e6aca33fb8190662689b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:04:56 +0900 Subject: [PATCH 244/261] Add "Component" prefix to lookup naming --- ...nLookup.cs => CatchSkinComponentLookup.cs} | 4 ++-- .../Objects/Drawables/CaughtObject.cs | 4 ++-- .../Objects/Drawables/DrawableBanana.cs | 2 +- .../Objects/Drawables/DrawableDroplet.cs | 2 +- .../Objects/Drawables/DrawableFruit.cs | 2 +- .../Argon/CatchArgonSkinTransformer.cs | 4 ++-- .../Legacy/CatchLegacySkinTransformer.cs | 10 ++++----- .../UI/CatchComboDisplay.cs | 2 +- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 2 +- .../UI/SkinnableCatcher.cs | 2 +- .../Skinning/TestSceneColumnBackground.cs | 4 ++-- .../Skinning/TestSceneStageBackground.cs | 2 +- .../Skinning/TestSceneStageForeground.cs | 2 +- ...nLookup.cs => ManiaSkinComponentLookup.cs} | 6 ++--- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableNote.cs | 2 +- .../Argon/ManiaArgonSkinTransformer.cs | 6 ++--- .../Legacy/ManiaLegacySkinTransformer.cs | 6 ++--- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- .../UI/Components/ColumnHitObjectArea.cs | 2 +- .../UI/PoolableHitExplosion.cs | 2 +- osu.Game.Rulesets.Mania/UI/Stage.cs | 4 ++-- .../TestSceneCursorTrail.cs | 2 +- .../TestSceneGameplayCursor.cs | 2 +- .../TestSceneSkinFallbacks.cs | 4 ++-- .../Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/DrawableHitCircle.cs | 6 ++--- .../Objects/Drawables/DrawableSlider.cs | 2 +- .../Objects/Drawables/DrawableSliderBall.cs | 4 ++-- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 2 +- .../Objects/Drawables/DrawableSliderTick.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- ...kinLookup.cs => OsuSkinComponentLookup.cs} | 4 ++-- .../Skinning/Argon/OsuArgonSkinTransformer.cs | 6 ++--- .../Skinning/Default/DefaultApproachCircle.cs | 2 +- .../Skinning/Default/NumberPiece.cs | 2 +- .../Skinning/Default/ReverseArrowPiece.cs | 2 +- .../Skinning/Legacy/LegacyApproachCircle.cs | 2 +- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 2 +- .../Skinning/Legacy/LegacyReverseArrow.cs | 2 +- .../Legacy/OsuLegacySkinTransformer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 2 +- .../UI/Cursor/OsuCursorContainer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/SmokeContainer.cs | 4 ++-- .../Skinning/TestSceneTaikoScroller.cs | 2 +- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Objects/Drawables/DrawableDrumRoll.cs | 2 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 4 ++-- .../Objects/Drawables/DrawableSwell.cs | 2 +- .../Objects/Drawables/DrawableSwellTick.cs | 2 +- .../Legacy/TaikoLegacySkinTransformer.cs | 6 ++--- ...nLookup.cs => TaikoSkinComponentLookup.cs} | 4 ++-- .../UI/DrawableTaikoRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 +- .../UI/KiaiHitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +++---- .../TestSceneHitObjectAccentColour.cs | 2 +- .../Skinning/LegacySkinAnimationTest.cs | 2 +- .../TestSceneRulesetSkinProvidingContainer.cs | 2 +- .../Skins/SkinDeserialisationTest.cs | 16 +++++++------- .../TestSceneBeatmapSkinLookupDisables.cs | 12 +++++----- .../Skins/TestSceneSkinConfigurationLookup.cs | 2 +- .../Skins/TestSceneSkinProvidingContainer.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 6 ++--- .../Gameplay/TestSceneSkinnableDrawable.cs | 22 +++++++++---------- .../Gameplay/TestSceneSkinnableSound.cs | 2 +- .../Rulesets/Judgements/DrawableJudgement.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmapSkin.cs | 2 +- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 8 +++---- .../Skinning/BeatmapSkinProvidingContainer.cs | 2 +- osu.Game/Skinning/Editor/SkinEditor.cs | 2 +- ...okup.cs => GameplaySkinComponentLookup.cs} | 4 ++-- ...Lookup.cs => GlobalSkinComponentLookup.cs} | 4 ++-- osu.Game/Skinning/ISkin.cs | 2 +- ...ISkinLookup.cs => ISkinComponentLookup.cs} | 4 ++-- osu.Game/Skinning/ISkinnableTarget.cs | 2 +- osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 ++--- osu.Game/Skinning/LegacySkin.cs | 10 ++++----- osu.Game/Skinning/ResourceStoreBackedSkin.cs | 2 +- osu.Game/Skinning/Skin.cs | 10 ++++----- osu.Game/Skinning/SkinManager.cs | 2 +- osu.Game/Skinning/SkinProvidingContainer.cs | 6 ++--- osu.Game/Skinning/SkinTransformer.cs | 2 +- osu.Game/Skinning/SkinnableDrawable.cs | 16 +++++++------- osu.Game/Skinning/SkinnableSprite.cs | 12 +++++----- osu.Game/Skinning/SkinnableSpriteText.cs | 2 +- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 ++--- osu.Game/Skinning/TrianglesSkin.cs | 8 +++---- .../UnsupportedSkinComponentException.cs | 2 +- 94 files changed, 186 insertions(+), 186 deletions(-) rename osu.Game.Rulesets.Catch/{CatchSkinLookup.cs => CatchSkinComponentLookup.cs} (74%) rename osu.Game.Rulesets.Mania/{ManiaSkinLookup.cs => ManiaSkinComponentLookup.cs} (77%) rename osu.Game.Rulesets.Osu/{OsuSkinLookup.cs => OsuSkinComponentLookup.cs} (73%) rename osu.Game.Rulesets.Taiko/{TaikoSkinLookup.cs => TaikoSkinComponentLookup.cs} (73%) rename osu.Game/Skinning/{GameplaySkinLookup.cs => GameplaySkinComponentLookup.cs} (83%) rename osu.Game/Skinning/{GlobalSkinLookup.cs => GlobalSkinComponentLookup.cs} (78%) rename osu.Game/Skinning/{ISkinLookup.cs => ISkinComponentLookup.cs} (88%) diff --git a/osu.Game.Rulesets.Catch/CatchSkinLookup.cs b/osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs similarity index 74% rename from osu.Game.Rulesets.Catch/CatchSkinLookup.cs rename to osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs index 65bfc7ee30..149aae1cb4 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinLookup.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { - public class CatchSkinLookup : GameplaySkinLookup + public class CatchSkinComponentLookup : GameplaySkinComponentLookup { - public CatchSkinLookup(CatchSkinComponents component) + public CatchSkinComponentLookup(CatchSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index 20d348fe3d..8ac5eac227 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -37,8 +37,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public override bool RemoveWhenNotAlive => true; - protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) - : base(new CatchSkinLookup(skinComponent), defaultImplementation) + protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) + : base(new CatchSkinComponentLookup(skinComponent), defaultImplementation) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index a2b32ea9e4..80a4150d98 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinLookup(CatchSkinComponents.Banana), + new CatchSkinComponentLookup(CatchSkinComponents.Banana), _ => new BananaPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index 210a4495e4..a81d87480a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinLookup(CatchSkinComponents.Droplet), + new CatchSkinComponentLookup(CatchSkinComponents.Droplet), _ => new DropletPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index 6359a5b35c..d7fd79929b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinLookup(CatchSkinComponents.Fruit), + new CatchSkinComponentLookup(CatchSkinComponents.Fruit), _ => new FruitPiece()); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 606cd339a9..520c2de248 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -13,11 +13,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case CatchSkinLookup catchComponent: + case CatchSkinComponentLookup catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) { diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 83a8a37676..08ac55508a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -25,13 +25,13 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GlobalSkinLookup targetComponent) + if (lookup is GlobalSkinComponentLookup targetComponent) { switch (targetComponent.Lookup) { - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer; if (providesComboCounter && components != null) @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy } } - if (lookup is CatchSkinLookup catchSkinComponent) + if (lookup is CatchSkinComponentLookup catchSkinComponent) { switch (catchSkinComponent.Component) { @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { case CatchSkinConfiguration.FlipCatcherPlate: // Don't flip catcher plate contents if the catcher is provided by this legacy skin. - if (GetDrawableComponent(new CatchSkinLookup(CatchSkinComponents.Catcher)) != null) + if (GetDrawableComponent(new CatchSkinComponentLookup(CatchSkinComponents.Catcher)) != null) return (IBindable)new Bindable(); break; diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index 802e837746..03f0bc6a55 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly IBindable showCombo = new BindableBool(true); public CatchComboDisplay() - : base(new CatchSkinLookup(CatchSkinComponents.CatchComboCounter), _ => Empty()) + : base(new CatchSkinComponentLookup(CatchSkinComponents.CatchComboCounter), _ => Empty()) { } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index fb55864c49..9b32893efe 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; - InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponentLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { CentreComponent = false, Anchor = Anchor.BottomCentre, diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index 2e07e39943..fa6ccf6bd6 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI public readonly Bindable AnimationState = new Bindable(); public SkinnableCatcher() - : base(new CatchSkinLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) + : base(new CatchSkinComponentLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) { Anchor = Anchor.TopCentre; // Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling. diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs index 8dc8e72479..3dece20308 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs index 19ccf20870..5c8e038eed 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), + SetContents(_ => new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs index 171d2951be..f9c17ee7f4 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) + SetContents(_ => new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageForeground), _ => null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs similarity index 77% rename from osu.Game.Rulesets.Mania/ManiaSkinLookup.cs rename to osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs index 6e6d00fee6..c9ee5af809 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs @@ -5,13 +5,13 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { - public class ManiaSkinLookup : GameplaySkinLookup + public class ManiaSkinComponentLookup : GameplaySkinComponentLookup { /// - /// Creates a new . + /// Creates a new . /// /// The component. - public ManiaSkinLookup(ManiaSkinComponents component) + public ManiaSkinComponentLookup(ManiaSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 5b003e3c19..c68eec610c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables headContainer = new Container { RelativeSizeAxes = Axes.Both } } }, - bodyPiece = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece + bodyPiece = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece { RelativeSizeAxes = Axes.Both, }) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 25347d3dfa..cf3149b065 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { rulesetConfig?.BindWith(ManiaRulesetSetting.TimingBasedNoteColouring, configTimingBasedNoteColouring); - AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinLookup(Component), _ => new DefaultNotePiece()) + AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponentLookup(Component), _ => new DefaultNotePiece()) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index cf9f9f36f0..eb7f63fbe2 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon this.beatmap = (ManiaBeatmap)beatmap; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case ManiaSkinLookup maniaComponent: + case ManiaSkinComponentLookup maniaComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (maniaComponent.Component) { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs index 5b7ccc7bb6..f8519beb22 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs @@ -74,14 +74,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy }); } - public override Drawable GetDrawableComponent(ISkinLookup lookup) + public override Drawable GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: return getResult(resultComponent.Component); - case ManiaSkinLookup maniaComponent: + case ManiaSkinComponentLookup maniaComponent: if (!isLegacySkin.Value || !hasKeyTexture.Value) return null; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 4eed75a90d..de7424773b 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.UI skin.SourceChanged += onSourceChanged; onSourceChanged(); - Drawable background = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Drawable background = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both, }; @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI // For input purposes, the background is added at the highest depth, but is then proxied back below all other elements background.CreateProxy(), HitObjectArea, - keyArea = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) + keyArea = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index d02e4afc81..e5a9ca1e85 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components RelativeSizeAxes = Axes.Both, Depth = 2, }, - hitTarget = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) + hitTarget = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) { RelativeSizeAxes = Axes.X, Depth = 1 diff --git a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs index faf345545d..8e5c8f9b75 100644 --- a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 5d08e38aef..8aeaa9cf35 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI AutoSizeAxes = Axes.X, Children = new Drawable[] { - new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) + new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { RelativeSizeAxes = Axes.Both }, @@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y, } }, - new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) + new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageForeground), _ => null) { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs index aeadbea510..30f0891344 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Tests RelativeSizeAxes = Axes.Both; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => null; + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index f88948ce13..628082c2a9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests private class TopLeftCursorSkin : ISkin { - public Drawable GetDrawableComponent(ISkinLookup lookup) => null; + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null; public ISample GetSample(ISampleInfo sampleInfo) => null; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index c012dae635..878150e467 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -149,11 +149,11 @@ namespace osu.Game.Rulesets.Osu.Tests this.identifier = identifier; } - public Drawable GetDrawableComponent(ISkinLookup lookup) + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) { if (!enabled) return null; - if (lookup is OsuSkinLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) + if (lookup is OsuSkinComponentLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) return null; return new OsuSpriteText diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 22037c873c..8c95da9be1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections { Origin = Anchor.Centre; - InternalChild = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer + InternalChild = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer { Masking = true, AutoSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index bcb3ccae41..6201199cc3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -81,12 +81,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - CirclePiece = new SkinnableDrawable(new OsuSkinLookup(CirclePieceComponent), _ => new MainCirclePiece()) + CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(CirclePieceComponent), _ => new MainCirclePiece()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) + ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -278,7 +278,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public override bool RemoveWhenNotAlive => false; - public ProxyableSkinnableDrawable(ISkinLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public ProxyableSkinnableDrawable(ISkinComponentLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 3fdbc3dacd..a4745b365b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), + Body = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), tailContainer = new Container { RelativeSizeAxes = Axes.Both }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, repeatContainer = new Container { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index 86d41f0cbf..35d5c1f478 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new[] { - new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) + new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Masking = true }, - ball = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) + ball = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 1b8a17b6df..08602e168c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index e8c6e80109..a59cd92d62 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) } }, }); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index f591cd15d4..563c7e85aa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Origin = Anchor.Centre; - AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer + AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer { Masking = true, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 7d0e29bd93..83a9408570 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Y, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), + Body = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), RotationTracker = new SpinnerRotationTracker(this) } }, diff --git a/osu.Game.Rulesets.Osu/OsuSkinLookup.cs b/osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs similarity index 73% rename from osu.Game.Rulesets.Osu/OsuSkinLookup.cs rename to osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs index 4048e95e4b..81d5811f85 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinLookup.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { - public class OsuSkinLookup : GameplaySkinLookup + public class OsuSkinComponentLookup : GameplaySkinComponentLookup { - public OsuSkinLookup(OsuSkinComponents component) + public OsuSkinComponentLookup(OsuSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs index bf664bb606..86194d2c43 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs @@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case OsuSkinLookup osuComponent: + case OsuSkinComponentLookup osuComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (osuComponent.Component) { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index 2b2c31dcf7..3a67ad526e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default accentColour.BindValueChanged(colour => Colour = colour.NewValue, true); } - protected override Drawable CreateDefault(ISkinLookup lookup) + protected override Drawable CreateDefault(ISkinComponentLookup lookup) { var drawable = base.CreateDefault(lookup); diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index 39e07ebb99..60cfecfb5a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Colour = Color4.White.Opacity(0.5f), }, }, - number = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + number = new SkinnableSpriteText(new OsuSkinComponentLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 338e7abcfc..222e8d4348 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - Child = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon + Child = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index 20a1e3064e..4dd4f9562a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); } - protected override Drawable CreateDefault(ISkinLookup lookup) + protected override Drawable CreateDefault(ISkinComponentLookup lookup) { var drawable = base.CreateDefault(lookup); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 357be4cda8..e155c1b816 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy if (hasNumber) { - OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinComponentLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index f374af1cba..773cc7ae3c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { AutoSizeAxes = Axes.Both; - string lookupName = new OsuSkinLookup(OsuSkinComponents.ReverseArrow).LookupName; + string lookupName = new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow).LookupName; var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null); InternalChild = skin?.GetAnimation(lookupName, true, true) ?? Empty(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 2faa2d678e..ab0e9ab1c0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null); } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is OsuSkinLookup osuComponent) + if (lookup is OsuSkinComponentLookup osuComponent) { switch (osuComponent.Component) { diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 78b920c771..6d435f01b0 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, - Child = cursorSprite = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) + Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 396492c104..26fe08972e 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -47,8 +47,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Children = new[] { - cursorTrail = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), - new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), + cursorTrail = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), + new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; } diff --git a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs index 2616bb0325..bf5618dc90 100644 --- a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.UI { if (e.Action == OsuAction.Smoke) { - AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); + AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); // Add initial position immediately. addPosition(); @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.UI public override double LifetimeStart => Drawable.LifetimeStart; public override double LifetimeEnd => Drawable.LifetimeEnd; - public SmokeSkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public SmokeSkinnableDrawable(ISkinComponentLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs index 3076172d46..a9304b01ad 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning public TestSceneTaikoScroller() { AddStep("Load scroller", () => SetContents(_ => - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Scroller), _ => Empty()) { Clock = new FramedClock(clock), Height = 0.4f, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 715add7914..f6c541982e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables AddRangeInternal(new Drawable[] { - line = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.BarLine), _ => new Box + line = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.BarLine), _ => new Box { RelativeSizeAxes = Axes.Both, EdgeSmoothness = new Vector2(0.5f, 0), diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index f5ebecdee5..0bb14c791e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return base.CreateNestedHitObject(hitObject); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollBody), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody), _ => new ElongatedCirclePiece()); public override bool OnPressed(KeyBindingPressEvent e) => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 1ec2562f67..8dbcbf1ffc 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 0fe17f81f5..1e39c69acf 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -90,8 +90,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre - ? new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) - : new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); + ? new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) + : new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); public override IEnumerable GetSamples() { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 5b498e4cb3..753f85f23f 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Swell), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell), _ => new SwellCirclePiece { // to allow for rotation transform diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 4d915c91d3..5d44fce254 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public override bool OnPressed(KeyBindingPressEvent e) => false; - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs index 6cf7d3da0a..7bf99306f0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs @@ -27,16 +27,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy hasExplosion = new Lazy(() => GetTexture(getHitName(TaikoSkinComponents.TaikoExplosionGreat)) != null); } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GameplaySkinLookup) + if (lookup is GameplaySkinComponentLookup) { // if a taiko skin is providing explosion sprites, hide the judgements completely if (hasExplosion.Value) return Drawable.Empty().With(d => d.Expire()); } - if (lookup is TaikoSkinLookup taikoComponent) + if (lookup is TaikoSkinComponentLookup taikoComponent) { switch (taikoComponent.Component) { diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs similarity index 73% rename from osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs rename to osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs index cb8bbd8b18..c35971e9fd 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko { - public class TaikoSkinLookup : GameplaySkinLookup + public class TaikoSkinComponentLookup : GameplaySkinComponentLookup { - public TaikoSkinLookup(TaikoSkinComponents component) + public TaikoSkinComponentLookup(TaikoSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index db45c8bb70..c3d93a344d 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.UI { new BarLineGenerator(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar)); - FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) + FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Scroller), _ => Empty()) { RelativeSizeAxes = Axes.X, Depth = float.MaxValue diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 560f7b1748..d2b5811b56 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinLookup(getComponentName(result)), _ => new DefaultHitExplosion(result)); + InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinComponentLookup(getComponentName(result)), _ => new DefaultHitExplosion(result)); skinnable.OnSkinChanged += runAnimation; } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 4458fb1bc0..2f42a5aaf6 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.UI { Children = new Drawable[] { - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) { RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index b0d853f1f1..d2427b952c 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - Child = skinnable = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); + Child = skinnable = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 0de7bf233d..11349d8bd3 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.UI InternalChildren = new[] { - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), new Container { Name = "Left overlay", @@ -86,11 +86,11 @@ namespace osu.Game.Rulesets.Taiko.UI BorderColour = colours.Gray0, Children = new[] { - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), inputDrum.CreateProxy(), } }, - mascot = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Mascot), _ => Empty()) + mascot = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Mascot), _ => Empty()) { Origin = Anchor.BottomLeft, Anchor = Anchor.TopLeft, @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - HitTarget = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) + HitTarget = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index fc72fddcae..cccf640e27 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Gameplay Color4.Green }; - public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotImplementedException(); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs index 9e03663a49..5c247bace9 100644 --- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs +++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.NonVisual.Skinning return lookup_names.Contains(componentName) ? renderer.WhitePixel : null; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotSupportedException(); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new NotSupportedException(); public ISample GetSample(ISampleInfo sampleInfo) => throw new NotSupportedException(); public IBindable GetConfig(TLookup lookup) => throw new NotSupportedException(); } diff --git a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs index 6f14b933ee..a29fc9f1fb 100644 --- a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs +++ b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Rulesets OnLoadAsync?.Invoke(); } - public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS = default, WrapMode wrapModeT = default) => skin.GetTexture(componentName); diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 4398d870a0..cd6895b176 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); } } @@ -93,10 +93,10 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); - var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect].First(); + var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect].First(); Assert.That(skinnableInfo.Type, Is.EqualTo(typeof(SkinnableSprite))); Assert.That(skinnableInfo.Settings.First().Key, Is.EqualTo("sprite_name")); @@ -107,10 +107,10 @@ namespace osu.Game.Tests.Skins using (var storage = new ZipArchiveReader(stream)) { var skin = new TestSkin(new SkinInfo(), null, storage); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); } } diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs index 7c02d34b1c..a31c624f78 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Skins string expected = allowBeatmapLookups ? "beatmap" : "user"; - AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinLookup())?.Name == expected); + AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinComponentLookup())?.Name == expected); } [TestCase(false)] @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Skins ISkin expected() => allowBeatmapLookups ? beatmapSource : userSource; - AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinLookup()) != null) == expected()); + AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinComponentLookup()) != null) == expected()); } public class UserSkinSource : LegacySkin @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinLookup lookup) + public override Drawable GetDrawableComponent(ISkinComponentLookup lookup) { return new Container { Name = "user" }; } @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinLookup lookup) + public override Drawable GetDrawableComponent(ISkinComponentLookup lookup) { return new Container { Name = "beatmap" }; } @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Skins public ISkin FindProvider(Func lookupFunction) => skin.FindProvider(lookupFunction); } - private class TestSkinLookup : ISkinLookup + private class TestSkinComponentLookup : ISkinComponentLookup { public string LookupName => string.Empty; } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index 4cbc1cf4df..8c6f137dc0 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -221,7 +221,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs index 712d5ce969..ad71296a11 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Skins this.renderer = renderer; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new System.NotImplementedException(); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new System.NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 69a50a1cd1..8ad97eb33c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Gameplay { CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null)); AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); - AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); + AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); } protected void CreateSkinTest(SkinInfo gameCurrentSkin, Func getBeatmapSkin) @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - protected bool AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType target, ISkin expectedSource) + protected bool AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType target, ISkin expectedSource) { var actualComponentsContainer = Player.ChildrenOfType().First(s => s.Target == target) .ChildrenOfType().SingleOrDefault(); @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); - var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinLookup(target)); + var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinComponentLookup(target)); if (expectedComponentsContainer == null) return false; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index 81c5211878..e050273652 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private bool allow = true; - protected override bool AllowDrawableLookup(ISkinLookup lookup) => allow; + protected override bool AllowDrawableLookup(ISkinComponentLookup lookup) => allow; public void Disable() { @@ -182,8 +182,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public new Drawable Drawable => base.Drawable; - public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) - : base(new TestSkinLookup(name), defaultImplementation, confineMode) + public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) + : base(new TestSkinComponentLookup(name), defaultImplementation, confineMode) { } } @@ -251,8 +251,8 @@ namespace osu.Game.Tests.Visual.Gameplay public new Drawable Drawable => base.Drawable; public int SkinChangedCount { get; private set; } - public SkinConsumer(string name, Func defaultImplementation) - : base(new TestSkinLookup(name), defaultImplementation) + public SkinConsumer(string name, Func defaultImplementation) + : base(new TestSkinComponentLookup(name), defaultImplementation) { } @@ -288,8 +288,8 @@ namespace osu.Game.Tests.Visual.Gameplay this.size = size; } - public Drawable GetDrawableComponent(ISkinLookup lookupName) => - lookupName.LookupName == "available" + public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => + componentLookupName.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, @@ -306,7 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class SecondarySource : ISkin { - public Drawable GetDrawableComponent(ISkinLookup lookupName) => new SecondarySourceBox(); + public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new SecondarySourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -318,7 +318,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached(typeof(ISkinSource))] private class SkinSourceContainer : Container, ISkinSource { - public Drawable GetDrawableComponent(ISkinLookup lookupName) => new BaseSourceBox(); + public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new BaseSourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -337,9 +337,9 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class TestSkinLookup : ISkinLookup + private class TestSkinComponentLookup : ISkinComponentLookup { - public TestSkinLookup(string name) + public TestSkinComponentLookup(string name) { LookupName = name; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 43206ac591..8122d8defb 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual.Gameplay IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled; - public Drawable GetDrawableComponent(ISkinLookup lookup) => source?.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => source?.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => source?.GetConfig(lookup); diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index bfcdd384a0..6fc1deaf11 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Judgements if (JudgementBody != null) RemoveInternal(JudgementBody, true); - AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinLookup(type), _ => + AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponentLookup(type), _ => CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling) { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs index bc63ad063c..80239504d8 100644 --- a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs +++ b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit #region Delegated ISkin implementation - public Drawable GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => Skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Skin.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => Skin.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => Skin.GetConfig(lookup); diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 932ebe7d18..fa38eeb9aa 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -391,7 +391,7 @@ namespace osu.Game.Screens.Play private OsuConfigManager config { get; set; } public MainComponentsContainer() - : base(GlobalSkinLookup.LookupType.MainHUDComponents) + : base(GlobalSkinComponentLookup.LookupType.MainHUDComponents) { RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e525d5a368..1add51e725 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -250,7 +250,7 @@ namespace osu.Game.Screens.Select } } }, - new SkinnableTargetContainer(GlobalSkinLookup.LookupType.SongSelect) + new SkinnableTargetContainer(GlobalSkinComponentLookup.LookupType.SongSelect) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 7aaf1a0e89..c3361093a9 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -81,17 +81,17 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case GlobalSkinLookup globalLookup: + case GlobalSkinComponentLookup globalLookup: switch (globalLookup.Lookup) { - case GlobalSkinLookup.LookupType.SongSelect: + case GlobalSkinComponentLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -99,7 +99,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index ec9d52f5c6..e14287c318 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Skinning } } - protected override bool AllowDrawableLookup(ISkinLookup lookup) + protected override bool AllowDrawableLookup(ISkinComponentLookup lookup) { if (beatmapSkins == null) throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index fdc8b6b2ad..410f5d9347 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -314,7 +314,7 @@ namespace osu.Game.Skinning.Editor private ISkinnableTarget getFirstTarget() => availableTargets.FirstOrDefault(); - private ISkinnableTarget getTarget(GlobalSkinLookup.LookupType target) + private ISkinnableTarget getTarget(GlobalSkinComponentLookup.LookupType target) { return availableTargets.FirstOrDefault(c => c.Target == target); } diff --git a/osu.Game/Skinning/GameplaySkinLookup.cs b/osu.Game/Skinning/GameplaySkinComponentLookup.cs similarity index 83% rename from osu.Game/Skinning/GameplaySkinLookup.cs rename to osu.Game/Skinning/GameplaySkinComponentLookup.cs index cec9dbde7d..2d1dec4691 100644 --- a/osu.Game/Skinning/GameplaySkinLookup.cs +++ b/osu.Game/Skinning/GameplaySkinComponentLookup.cs @@ -5,12 +5,12 @@ using System.Linq; namespace osu.Game.Skinning { - public class GameplaySkinLookup : ISkinLookup + public class GameplaySkinComponentLookup : ISkinComponentLookup where T : notnull { public readonly T Component; - public GameplaySkinLookup(T component) + public GameplaySkinComponentLookup(T component) { Component = component; } diff --git a/osu.Game/Skinning/GlobalSkinLookup.cs b/osu.Game/Skinning/GlobalSkinComponentLookup.cs similarity index 78% rename from osu.Game/Skinning/GlobalSkinLookup.cs rename to osu.Game/Skinning/GlobalSkinComponentLookup.cs index c63c0315a3..3d8b61eba2 100644 --- a/osu.Game/Skinning/GlobalSkinLookup.cs +++ b/osu.Game/Skinning/GlobalSkinComponentLookup.cs @@ -3,13 +3,13 @@ namespace osu.Game.Skinning { - public class GlobalSkinLookup : ISkinLookup + public class GlobalSkinComponentLookup : ISkinComponentLookup { public readonly LookupType Lookup; public string LookupName => Lookup.ToString(); - public GlobalSkinLookup(LookupType lookup) + public GlobalSkinComponentLookup(LookupType lookup) { Lookup = lookup; } diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index c352dfef5c..45be5582f6 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning /// /// The requested component. /// A drawable representation for the requested component, or null if unavailable. - Drawable? GetDrawableComponent(ISkinLookup lookup); + Drawable? GetDrawableComponent(ISkinComponentLookup lookup); /// /// Retrieve a . diff --git a/osu.Game/Skinning/ISkinLookup.cs b/osu.Game/Skinning/ISkinComponentLookup.cs similarity index 88% rename from osu.Game/Skinning/ISkinLookup.cs rename to osu.Game/Skinning/ISkinComponentLookup.cs index 4daea35e82..ae56fb0b1c 100644 --- a/osu.Game/Skinning/ISkinLookup.cs +++ b/osu.Game/Skinning/ISkinComponentLookup.cs @@ -11,10 +11,10 @@ namespace osu.Game.Skinning /// to scope particular lookup variations. Using this, a ruleset or skin implementation could make its own lookup /// type to scope away from more global contexts. /// - /// More commonly, a ruleset could make use of to do a simple lookup based on + /// More commonly, a ruleset could make use of to do a simple lookup based on /// a provided enum. /// - public interface ISkinLookup + public interface ISkinComponentLookup { string LookupName { get; } } diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index b1a0f6714b..57c78bfe1c 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -18,7 +18,7 @@ namespace osu.Game.Skinning /// /// The definition of this target. /// - GlobalSkinLookup.LookupType Target { get; } + GlobalSkinComponentLookup.LookupType Target { get; } /// /// A bindable list of components which are being tracked by this skinnable target. diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 1d6ded6fee..8407b144f8 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -43,13 +43,13 @@ namespace osu.Game.Skinning return new RealmBackedResourceStore(beatmapInfo.BeatmapSet.ToLive(resources.RealmAccess), resources.Files, resources.RealmAccess); } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GlobalSkinLookup targetComponent) + if (lookup is GlobalSkinComponentLookup targetComponent) { switch (targetComponent.Lookup) { - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: // this should exist in LegacySkin instead, but there isn't a fallback skin for LegacySkins yet. // therefore keep the check here until fallback default legacy skin is supported. if (!this.HasFont(LegacyFont.Score)) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 75957bb560..98618e3dcd 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -322,17 +322,17 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case GlobalSkinLookup target: + case GlobalSkinComponentLookup target: switch (target.Lookup) { - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); @@ -379,7 +379,7 @@ namespace osu.Game.Skinning return null; - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: // kind of wasteful that we throw this away, but should do for now. if (getJudgementAnimation(resultComponent.Component) != null) @@ -397,7 +397,7 @@ namespace osu.Game.Skinning return null; - case SkinnableSprite.SpriteLookup sprite: + case SkinnableSprite.SpriteComponentLookup sprite: return this.GetAnimation(sprite.LookupName, false, false); } diff --git a/osu.Game/Skinning/ResourceStoreBackedSkin.cs b/osu.Game/Skinning/ResourceStoreBackedSkin.cs index 1b846438f5..f5c6192ba5 100644 --- a/osu.Game/Skinning/ResourceStoreBackedSkin.cs +++ b/osu.Game/Skinning/ResourceStoreBackedSkin.cs @@ -27,7 +27,7 @@ namespace osu.Game.Skinning samples = audio.GetSampleStore(new NamespacedResourceStore(resources, @"Samples")); } - public Drawable? GetDrawableComponent(ISkinLookup lookup) => null; + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) => null; public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => textures.Get(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 67b74229bb..e222b9017c 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -37,9 +37,9 @@ namespace osu.Game.Skinning public SkinConfiguration Configuration { get; set; } - public IDictionary DrawableComponentInfo => drawableComponentInfo; + public IDictionary DrawableComponentInfo => drawableComponentInfo; - private readonly Dictionary drawableComponentInfo = new Dictionary(); + private readonly Dictionary drawableComponentInfo = new Dictionary(); public abstract ISample? GetSample(ISampleInfo sampleInfo); @@ -97,7 +97,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); // skininfo files may be null for default skin. - foreach (GlobalSkinLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinLookup.LookupType))) + foreach (GlobalSkinComponentLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinComponentLookup.LookupType))) { string filename = $"{skinnableTarget}.json"; @@ -154,11 +154,11 @@ namespace osu.Game.Skinning DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSkinnableInfo().ToArray(); } - public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) + public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GlobalSkinLookup target: + case GlobalSkinComponentLookup target: if (!DrawableComponentInfo.TryGetValue(target.Lookup, out var skinnableInfo)) return null; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index bd4078b985..4a5277f3bf 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -201,7 +201,7 @@ namespace osu.Game.Skinning public event Action SourceChanged; - public Drawable GetDrawableComponent(ISkinLookup lookup) => lookupWithFallback(s => s.GetDrawableComponent(lookup)); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => lookupWithFallback(s => s.GetDrawableComponent(lookup)); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => lookupWithFallback(s => s.GetTexture(componentName, wrapModeS, wrapModeT)); diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 0ed5c6b736..e7d0683005 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Skinning /// protected virtual bool AllowFallingBackToParent => true; - protected virtual bool AllowDrawableLookup(ISkinLookup lookup) => true; + protected virtual bool AllowDrawableLookup(ISkinComponentLookup lookup) => true; protected virtual bool AllowTextureLookup(string componentName) => true; @@ -107,7 +107,7 @@ namespace osu.Game.Skinning } } - public Drawable? GetDrawableComponent(ISkinLookup lookup) + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { foreach (var (_, lookupWrapper) in skinSources) { @@ -238,7 +238,7 @@ namespace osu.Game.Skinning this.provider = provider; } - public Drawable? GetDrawableComponent(ISkinLookup lookup) + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (provider.AllowDrawableLookup(lookup)) return skin.GetDrawableComponent(lookup); diff --git a/osu.Game/Skinning/SkinTransformer.cs b/osu.Game/Skinning/SkinTransformer.cs index 9772d98fde..e05961d404 100644 --- a/osu.Game/Skinning/SkinTransformer.cs +++ b/osu.Game/Skinning/SkinTransformer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning Skin = skin ?? throw new ArgumentNullException(nameof(skin)); } - public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); + public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) => Skin.GetDrawableComponent(lookup); public virtual Texture? GetTexture(string componentName) => GetTexture(componentName, default, default); diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 4398dda413..15d371cdd5 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -31,7 +31,7 @@ namespace osu.Game.Skinning set => base.AutoSizeAxes = value; } - protected readonly ISkinLookup Lookup; + protected readonly ISkinComponentLookup ComponentLookup; private readonly ConfineMode confineMode; @@ -41,15 +41,15 @@ namespace osu.Game.Skinning /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public SkinnableDrawable(ISkinComponentLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : this(lookup, confineMode) { createDefault = defaultImplementation; } - protected SkinnableDrawable(ISkinLookup lookup, ConfineMode confineMode = ConfineMode.NoScaling) + protected SkinnableDrawable(ISkinComponentLookup lookup, ConfineMode confineMode = ConfineMode.NoScaling) { - Lookup = lookup; + ComponentLookup = lookup; this.confineMode = confineMode; RelativeSizeAxes = Axes.Both; @@ -60,13 +60,13 @@ namespace osu.Game.Skinning /// public void ResetAnimation() => (Drawable as IFramedAnimation)?.GotoFrame(0); - private readonly Func? createDefault; + private readonly Func? createDefault; private readonly Cached scaling = new Cached(); private bool isDefault; - protected virtual Drawable CreateDefault(ISkinLookup lookup) => createDefault?.Invoke(lookup) ?? Empty(); + protected virtual Drawable CreateDefault(ISkinComponentLookup lookup) => createDefault?.Invoke(lookup) ?? Empty(); /// /// Whether to apply size restrictions (specified via ) to the default implementation. @@ -75,11 +75,11 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin) { - var retrieved = skin.GetDrawableComponent(Lookup); + var retrieved = skin.GetDrawableComponent(ComponentLookup); if (retrieved == null) { - Drawable = CreateDefault(Lookup); + Drawable = CreateDefault(ComponentLookup); isDefault = true; } else diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 8f456fce0a..43fec11b14 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -34,26 +34,26 @@ namespace osu.Game.Skinning private ISkinSource source { get; set; } = null!; public SkinnableSprite(string textureName, ConfineMode confineMode = ConfineMode.NoScaling) - : base(new SpriteLookup(textureName), confineMode) + : base(new SpriteComponentLookup(textureName), confineMode) { SpriteName.Value = textureName; } public SkinnableSprite() - : base(new SpriteLookup(string.Empty), ConfineMode.NoScaling) + : base(new SpriteComponentLookup(string.Empty), ConfineMode.NoScaling) { RelativeSizeAxes = Axes.None; AutoSizeAxes = Axes.Both; SpriteName.BindValueChanged(name => { - ((SpriteLookup)Lookup).LookupName = name.NewValue ?? string.Empty; + ((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue ?? string.Empty; if (IsLoaded) SkinChanged(CurrentSkin); }); } - protected override Drawable CreateDefault(ISkinLookup lookup) + protected override Drawable CreateDefault(ISkinComponentLookup lookup) { var texture = textures.Get(lookup.LookupName); @@ -65,11 +65,11 @@ namespace osu.Game.Skinning public bool UsesFixedAnchor { get; set; } - internal class SpriteLookup : ISkinLookup + internal class SpriteComponentLookup : ISkinComponentLookup { public string LookupName { get; set; } - public SpriteLookup(string textureName) + public SpriteComponentLookup(string textureName) { LookupName = textureName; } diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 8cc48a76ed..c01cec2f0c 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -9,7 +9,7 @@ namespace osu.Game.Skinning { public class SkinnableSpriteText : SkinnableDrawable, IHasText { - public SkinnableSpriteText(ISkinLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) + public SkinnableSpriteText(ISkinComponentLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index bea29b0da3..a8038f5f5c 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private SkinnableTargetComponentsContainer? content; - public GlobalSkinLookup.LookupType Target { get; } + public GlobalSkinComponentLookup.LookupType Target { get; } public IBindableList Components => components; @@ -25,7 +25,7 @@ namespace osu.Game.Skinning private CancellationTokenSource? cancellationSource; - public SkinnableTargetContainer(GlobalSkinLookup.LookupType target) + public SkinnableTargetContainer(GlobalSkinComponentLookup.LookupType target) { Target = target; } @@ -39,7 +39,7 @@ namespace osu.Game.Skinning components.Clear(); ComponentsLoaded = false; - content = CurrentSkin.GetDrawableComponent(new GlobalSkinLookup(Target)) as SkinnableTargetComponentsContainer; + content = CurrentSkin.GetDrawableComponent(new GlobalSkinComponentLookup(Target)) as SkinnableTargetComponentsContainer; cancellationSource?.Cancel(); cancellationSource = null; diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index e3729136b9..3df85b6880 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -59,17 +59,17 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case GlobalSkinLookup target: + case GlobalSkinComponentLookup target: switch (target.Lookup) { - case GlobalSkinLookup.LookupType.SongSelect: + case GlobalSkinComponentLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -77,7 +77,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 32fc6661b0..1fb6641668 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -7,7 +7,7 @@ namespace osu.Game.Skinning { public class UnsupportedSkinComponentException : Exception { - public UnsupportedSkinComponentException(ISkinLookup lookup) + public UnsupportedSkinComponentException(ISkinComponentLookup lookup) : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup.LookupName}"").") { } From e19ba65f9186afab21aec536a636d7d152636dde Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:39:33 +0900 Subject: [PATCH 245/261] Remove `LookupName` from base `ISkinComponentLookup` --- .../Legacy/OsuLegacySkinTransformer.cs | 4 ++-- .../Gameplay/TestSceneSkinnableDrawable.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 21 +++++++++---------- .../Skinning/GlobalSkinComponentLookup.cs | 2 -- osu.Game/Skinning/ISkinComponentLookup.cs | 1 - osu.Game/Skinning/SkinnableSprite.cs | 4 ++-- osu.Game/Skinning/TrianglesSkin.cs | 21 +++++++++---------- .../UnsupportedSkinComponentException.cs | 2 +- 8 files changed, 26 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index ab0e9ab1c0..620540b8ef 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -35,10 +35,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy switch (osuComponent.Component) { case OsuSkinComponents.FollowPoint: - return this.GetAnimation(lookup.LookupName, true, true, true, startAtCurrentTime: false); + return this.GetAnimation("followpoint", true, true, true, startAtCurrentTime: false); case OsuSkinComponents.SliderScorePoint: - return this.GetAnimation(lookup.LookupName, false, false); + return this.GetAnimation("sliderscorepoint", false, false); case OsuSkinComponents.SliderFollowCircle: var followCircleContent = this.GetAnimation("sliderfollowcircle", true, true, true); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index e050273652..97974d2368 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -289,7 +289,7 @@ namespace osu.Game.Tests.Visual.Gameplay } public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => - componentLookupName.LookupName == "available" + (componentLookupName as TestSkinComponentLookup)?.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index c3361093a9..a2eb07eba3 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -7,7 +7,6 @@ using JetBrains.Annotations; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Beatmaps.Formats; @@ -88,6 +87,16 @@ namespace osu.Game.Skinning switch (lookup) { + case SkinnableSprite.SpriteComponentLookup spriteLookup: + switch (spriteLookup.LookupName) + { + // Temporary until default skin has a valid hit lighting. + case @"lighting": + return Drawable.Empty(); + } + + break; + case GlobalSkinComponentLookup globalLookup: switch (globalLookup.Lookup) { @@ -178,16 +187,6 @@ namespace osu.Game.Skinning return null; } - switch (lookup.LookupName) - { - // Temporary until default skin has a valid hit lighting. - case @"lighting": - return Drawable.Empty(); - } - - if (GetTexture(lookup.LookupName) is Texture t) - return new Sprite { Texture = t }; - return null; } diff --git a/osu.Game/Skinning/GlobalSkinComponentLookup.cs b/osu.Game/Skinning/GlobalSkinComponentLookup.cs index 3d8b61eba2..7dcc3c4f14 100644 --- a/osu.Game/Skinning/GlobalSkinComponentLookup.cs +++ b/osu.Game/Skinning/GlobalSkinComponentLookup.cs @@ -7,8 +7,6 @@ namespace osu.Game.Skinning { public readonly LookupType Lookup; - public string LookupName => Lookup.ToString(); - public GlobalSkinComponentLookup(LookupType lookup) { Lookup = lookup; diff --git a/osu.Game/Skinning/ISkinComponentLookup.cs b/osu.Game/Skinning/ISkinComponentLookup.cs index ae56fb0b1c..be4043d7cf 100644 --- a/osu.Game/Skinning/ISkinComponentLookup.cs +++ b/osu.Game/Skinning/ISkinComponentLookup.cs @@ -16,6 +16,5 @@ namespace osu.Game.Skinning /// public interface ISkinComponentLookup { - string LookupName { get; } } } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 43fec11b14..7fd0e43562 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -55,10 +55,10 @@ namespace osu.Game.Skinning protected override Drawable CreateDefault(ISkinComponentLookup lookup) { - var texture = textures.Get(lookup.LookupName); + var texture = textures.Get(((SpriteComponentLookup)lookup).LookupName); if (texture == null) - return new SpriteNotFound(lookup.LookupName); + return new SpriteNotFound(((SpriteComponentLookup)lookup).LookupName); return new Sprite { Texture = texture }; } diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 3df85b6880..2075cfb6f2 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -7,7 +7,6 @@ using JetBrains.Annotations; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Beatmaps.Formats; @@ -66,6 +65,16 @@ namespace osu.Game.Skinning switch (lookup) { + case SkinnableSprite.SpriteComponentLookup spriteLookup: + switch (spriteLookup.LookupName) + { + // Temporary until default skin has a valid hit lighting. + case @"lighting": + return Drawable.Empty(); + } + + break; + case GlobalSkinComponentLookup target: switch (target.Lookup) { @@ -156,16 +165,6 @@ namespace osu.Game.Skinning return null; } - switch (lookup.LookupName) - { - // Temporary until default skin has a valid hit lighting. - case @"lighting": - return Drawable.Empty(); - } - - if (GetTexture(lookup.LookupName) is Texture t) - return new Sprite { Texture = t }; - return null; } diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 1fb6641668..b8dfb7a31d 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -8,7 +8,7 @@ namespace osu.Game.Skinning public class UnsupportedSkinComponentException : Exception { public UnsupportedSkinComponentException(ISkinComponentLookup lookup) - : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup.LookupName}"").") + : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup}"").") { } } From 533a2db5ea34df67750886e8aa0632a7f9dc5071 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Wed, 9 Nov 2022 18:48:47 +0100 Subject: [PATCH 246/261] fix inaccurate tablet area dimensions when applying aspect ratio --- .../Overlays/Settings/Sections/Input/TabletSettings.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index f1e216f538..a9eeae7cc7 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -308,9 +309,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input // if lock is applied (or the specified values were out of range) aim to adjust the axis the user was not adjusting to conform. if (sizeChanged == sizeX) - sizeY.Value = (int)(areaSize.Value.X / aspectRatio.Value); + sizeY.Value = (int)Math.Round(areaSize.Value.X / aspectRatio.Value); else - sizeX.Value = (int)(areaSize.Value.Y * aspectRatio.Value); + sizeX.Value = (int)Math.Round(areaSize.Value.Y * aspectRatio.Value); } finally { @@ -324,12 +325,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input { aspectLock.Value = false; - int proposedHeight = (int)(sizeX.Value / aspectRatio); + int proposedHeight = (int)Math.Round(sizeX.Value / aspectRatio); if (proposedHeight < sizeY.MaxValue) sizeY.Value = proposedHeight; else - sizeX.Value = (int)(sizeY.Value * aspectRatio); + sizeX.Value = (int)Math.Round(sizeY.Value * aspectRatio); updateAspectRatio(); From 3909e5730ea1168709d15331b6a780bdd1c86b6f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 9 Nov 2022 21:33:28 +0300 Subject: [PATCH 247/261] Rename test steps Co-authored-by: Joseph Madamba --- osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index e69bdfb7ac..d58887c090 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -518,7 +518,7 @@ namespace osu.Game.Tests.Visual.Navigation { ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); - AddUntilStep("Wait for options to load", () => Game.Notifications.IsLoaded); + AddUntilStep("Wait for notifications to load", () => Game.Notifications.IsLoaded); AddStep("Show notifications", () => Game.Notifications.Show()); AddUntilStep("wait for notifications shown", () => Game.Notifications.IsPresent && Game.Notifications.State.Value == Visibility.Visible); AddStep("Show changelog listing", () => Game.ShowChangelogListing()); @@ -535,7 +535,7 @@ namespace osu.Game.Tests.Visual.Navigation { ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); - AddUntilStep("Wait for options to load", () => Game.Settings.IsLoaded); + AddUntilStep("Wait for settings to load", () => Game.Settings.IsLoaded); AddStep("Show settings", () => Game.Settings.Show()); AddUntilStep("wait for settings shown", () => Game.Settings.IsPresent && Game.Settings.State.Value == Visibility.Visible); AddStep("Show changelog listing", () => Game.ShowChangelogListing()); From be81c658af8f20cf7618c73011f8c55a4f627798 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Wed, 9 Nov 2022 20:14:01 +0100 Subject: [PATCH 248/261] move tablet area calculations to functions --- .../Settings/Sections/Input/TabletSettings.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index a9eeae7cc7..59c7ff04a2 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -309,9 +309,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input // if lock is applied (or the specified values were out of range) aim to adjust the axis the user was not adjusting to conform. if (sizeChanged == sizeX) - sizeY.Value = (int)Math.Round(areaSize.Value.X / aspectRatio.Value); + sizeY.Value = getHeight(areaSize.Value.X, aspectRatio.Value); else - sizeX.Value = (int)Math.Round(areaSize.Value.Y * aspectRatio.Value); + sizeX.Value = getWidth(areaSize.Value.Y, aspectRatio.Value); } finally { @@ -325,12 +325,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input { aspectLock.Value = false; - int proposedHeight = (int)Math.Round(sizeX.Value / aspectRatio); + int proposedHeight = getHeight(sizeX.Value, aspectRatio); if (proposedHeight < sizeY.MaxValue) sizeY.Value = proposedHeight; else - sizeX.Value = (int)Math.Round(sizeY.Value * aspectRatio); + sizeX.Value = getWidth(sizeY.Value, aspectRatio); updateAspectRatio(); @@ -341,5 +341,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input private void updateAspectRatio() => aspectRatio.Value = currentAspectRatio; private float currentAspectRatio => sizeX.Value / sizeY.Value; + + private static int getHeight(float width, float aspectRatio) => (int)Math.Round(width / aspectRatio); + + private static int getWidth(float height, float aspectRatio) => (int)Math.Round(height * aspectRatio); } } From 1f8824a75495d826d2544dbfd930a29138af9610 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Nov 2022 16:14:40 +0900 Subject: [PATCH 249/261] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b6ddeeb41a..8237a570ff 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9a6866d264..09b1bb7162 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index b2854d7ddd..4264d9220e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 6303b88e5666a4d7527bb8ed3cfc0da602913386 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 10 Nov 2022 14:31:24 +0100 Subject: [PATCH 250/261] Fix NRT causing CI failure --- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 612756ba08..ccde8e6ac9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default { case ArmedState.Hit: using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) - flashBox?.FadeTo(0.9f).FadeOut(300); + flashBox.FadeTo(0.9f).FadeOut(300); break; } } From efc0325bef884e3c12c2a4d5ee1217ad28f36b0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Nov 2022 23:41:15 +0900 Subject: [PATCH 251/261] Fix nullability issue --- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 612756ba08..ccde8e6ac9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default { case ArmedState.Hit: using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) - flashBox?.FadeTo(0.9f).FadeOut(300); + flashBox.FadeTo(0.9f).FadeOut(300); break; } } From 5b1e39abd5d522e1c4dc6f2486bc43bb6b13f731 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 10 Nov 2022 22:56:24 +0100 Subject: [PATCH 252/261] Fix parsing of `Language` when using default system locale --- osu.Game/Extensions/LanguageExtensions.cs | 25 +++++++++++++++++++ .../Overlays/FirstRunSetup/ScreenWelcome.cs | 10 +++++--- .../Sections/General/LanguageSettings.cs | 18 ++++++------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/osu.Game/Extensions/LanguageExtensions.cs b/osu.Game/Extensions/LanguageExtensions.cs index b67e7fb6fc..04231c384c 100644 --- a/osu.Game/Extensions/LanguageExtensions.cs +++ b/osu.Game/Extensions/LanguageExtensions.cs @@ -3,6 +3,8 @@ using System; using System.Globalization; +using osu.Framework.Configuration; +using osu.Framework.Localisation; using osu.Game.Localisation; namespace osu.Game.Extensions @@ -29,5 +31,28 @@ namespace osu.Game.Extensions /// Whether the parsing succeeded. public static bool TryParseCultureCode(string cultureCode, out Language language) => Enum.TryParse(cultureCode.Replace("-", "_"), out language); + + /// + /// Parses the that is specified in , + /// or if that is not valid, the language of the current as exposed by . + /// + /// The current . + /// The current of the . + /// The parsed language. + public static Language GetLanguageFor(string frameworkLocale, LocalisationParameters localisationParameters) + { + // the usual case when the user has changed the language + if (TryParseCultureCode(frameworkLocale, out var language)) + return language; + + if (localisationParameters.Store != null) + { + // startup case, locale not explicitly set, or the set language was removed in an update + if (TryParseCultureCode(localisationParameters.Store.EffectiveCulture.Name, out language)) + return language; + } + + return Language.en; + } } } diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index cb1e96d2f2..992f538e82 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -63,11 +63,12 @@ namespace osu.Game.Overlays.FirstRunSetup private class LanguageSelectionFlow : FillFlowContainer { private Bindable frameworkLocale = null!; + private IBindable localisationParameters = null!; private ScheduledDelegate? updateSelectedDelegate; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig) + private void load(FrameworkConfigManager frameworkConfig, LocalisationManager localisation) { Direction = FillDirection.Full; Spacing = new Vector2(5); @@ -80,10 +81,11 @@ namespace osu.Game.Overlays.FirstRunSetup }); frameworkLocale = frameworkConfig.GetBindable(FrameworkSetting.Locale); - frameworkLocale.BindValueChanged(locale => + + localisationParameters = localisation.CurrentParameters.GetBoundCopy(); + localisationParameters.BindValueChanged(p => { - if (!LanguageExtensions.TryParseCultureCode(locale.NewValue, out var language)) - language = Language.en; + var language = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, p.NewValue); // Changing language may cause a short period of blocking the UI thread while the new glyphs are loaded. // Scheduling ensures the button animation plays smoothly after any blocking operation completes. diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index 0f77e6609b..b7e3bd90b0 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Configuration; @@ -16,15 +14,17 @@ namespace osu.Game.Overlays.Settings.Sections.General { public class LanguageSettings : SettingsSubsection { - private SettingsDropdown languageSelection; - private Bindable frameworkLocale; + private SettingsDropdown languageSelection = null!; + private Bindable frameworkLocale = null!; + private IBindable localisationParameters = null!; protected override LocalisableString Header => GeneralSettingsStrings.LanguageHeader; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager config) + private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager config, LocalisationManager localisation) { frameworkLocale = frameworkConfig.GetBindable(FrameworkSetting.Locale); + localisationParameters = localisation.CurrentParameters.GetBoundCopy(); Children = new Drawable[] { @@ -44,12 +44,8 @@ namespace osu.Game.Overlays.Settings.Sections.General }, }; - frameworkLocale.BindValueChanged(locale => - { - if (!LanguageExtensions.TryParseCultureCode(locale.NewValue, out var language)) - language = Language.en; - languageSelection.Current.Value = language; - }, true); + localisationParameters.BindValueChanged(p + => languageSelection.Current.Value = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, p.NewValue), true); languageSelection.Current.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToCultureCode()); } From 6ac19615fa2669c53a86d6aee51c19f90e7158dd Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 11 Nov 2022 14:55:41 +0900 Subject: [PATCH 253/261] Fix test failure --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 12 +++++++++++- osu.Game/Online/Chat/Channel.cs | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index e7eb06c795..32fc2604ba 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -55,6 +55,14 @@ namespace osu.Game.Tests.Chat case MarkChannelAsReadRequest markRead: handleMarkChannelAsReadRequest(markRead); return true; + + case GetUpdatesRequest updatesRequest: + updatesRequest.TriggerSuccess(new GetUpdatesResponse + { + Messages = sentMessages.ToList(), + Presence = new List() + }); + return true; } return false; @@ -95,6 +103,7 @@ namespace osu.Game.Tests.Chat }); AddStep("post message", () => channelManager.PostMessage("Something interesting")); + AddUntilStep("message postesd", () => !channel.Messages.Any(m => m is LocalMessage)); AddStep("post /help command", () => channelManager.PostCommand("help", channel)); AddStep("post /me command with no action", () => channelManager.PostCommand("me", channel)); @@ -115,7 +124,8 @@ namespace osu.Game.Tests.Chat Content = request.Message.Content, Links = request.Message.Links, Timestamp = request.Message.Timestamp, - Sender = request.Message.Sender + Sender = request.Message.Sender, + Uuid = request.Message.Uuid }; sentMessages.Add(message); diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 9bfaecc46b..ada9e22027 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -179,6 +179,10 @@ namespace osu.Game.Online.Chat throw new InvalidOperationException("Attempted to add the same message again"); Messages.Add(final); + + if (final.Id > LastMessageId) + LastMessageId = final.Id; + PendingMessageResolved?.Invoke(echo, final); } From 392d4e778eaf3fd4dd3ad433260154bdaff5cbf4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 Nov 2022 17:07:37 +0900 Subject: [PATCH 254/261] Change default beatmap listing key binding to `Ctrl`+`B` --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index a58c6723ef..ebdc446ec8 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F6, GlobalAction.ToggleNowPlaying), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleBeatmapListing), + new KeyBinding(new[] { InputKey.Control, InputKey.B }, GlobalAction.ToggleBeatmapListing), new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), new KeyBinding(new[] { InputKey.Control, InputKey.N }, GlobalAction.ToggleNotifications), }; From 0af4bdaf5c3d0acc1b532770adb7a122c303ca48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 Nov 2022 18:29:15 +0900 Subject: [PATCH 255/261] Add back removed configuration elements --- osu.Game/Configuration/OsuConfigManager.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1286a07eeb..3cabd6a21b 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -172,7 +172,9 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); - SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); + SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f); + SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); + SetDefault(OsuSetting.EditorShowHitMarkers, true); SetDefault(OsuSetting.LastProcessedMetadataId, -1); @@ -294,6 +296,7 @@ namespace osu.Game.Configuration GameplayCursorDuringTouch, DimLevel, BlurLevel, + EditorDim, LightenDuringBreaks, ShowStoryboard, KeyOverlay, @@ -366,6 +369,7 @@ namespace osu.Game.Configuration GameplayDisableWinKey, SeasonalBackgroundMode, EditorWaveformOpacity, + EditorShowHitMarkers, DiscordRichPresence, AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, From 151dd7c62f8c516a11f416883630c9e057785160 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 Nov 2022 22:10:27 +0900 Subject: [PATCH 256/261] Fix one more reverted change --- osu.Game/Configuration/OsuConfigManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3cabd6a21b..6cbb677a64 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; -using System.Globalization; using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; @@ -116,7 +115,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.MenuParallax, true); // See https://stackoverflow.com/a/63307411 for default sourcing. - SetDefault(OsuSetting.Prefer24HourTime, CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); + SetDefault(OsuSetting.Prefer24HourTime, !CultureInfoHelper.SystemCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); // Gameplay SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); From 7ef11cab8b76ea75ec5f1671fa0dbc6f73685361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 02:10:10 +0900 Subject: [PATCH 257/261] Adjust taiko argon transformer to new naming --- .../Skinning/Argon/TaikoArgonSkinTransformer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index f0d14f657d..379c675a0f 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponentLookup component) { switch (component) { - case GameplaySkinComponent resultComponent: + case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case TaikoSkinComponent catchComponent: + case TaikoSkinComponentLookup catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) { From 6a4c97b4f119bb91e73eb48c832691665da4fffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 02:20:19 +0900 Subject: [PATCH 258/261] Fix code inspection --- osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index 91f34e1f0e..22f96da61e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon EarlyActivationMilliseconds = pre_beat_transition_time; - AddRangeInternal(new Drawable[] + AddRangeInternal(new[] { new Circle { From 8b8147c3212d4475992f48df3ab3498b17c9925c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 03:05:03 +0900 Subject: [PATCH 259/261] Rename `{catch -> taiko}Component` --- .../Skinning/Argon/TaikoArgonSkinTransformer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 379c675a0f..6d1087793d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case TaikoSkinComponentLookup catchComponent: + case TaikoSkinComponentLookup taikoComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. - switch (catchComponent.Component) + switch (taikoComponent.Component) { case TaikoSkinComponents.CentreHit: return new ArgonCentreCirclePiece(); @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.TaikoExplosionGreat: case TaikoSkinComponents.TaikoExplosionMiss: case TaikoSkinComponents.TaikoExplosionOk: - return new ArgonHitExplosion(catchComponent.Component); + return new ArgonHitExplosion(taikoComponent.Component); } break; From b0314c67aa6f21aaae6e9b32be23ceac8b86cafe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 14:16:46 +0900 Subject: [PATCH 260/261] Fix failing gameplay bindings test --- .../Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs index 5bd879de14..c3d7bde68f 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs @@ -56,6 +56,7 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => new PlaySongSelect()); AddUntilStep("wait for selection", () => !Game.Beatmap.IsDefault); + AddUntilStep("wait for carousel load", () => songSelect.BeatmapSetsLoaded); AddStep("enter gameplay", () => InputManager.Key(Key.Enter)); @@ -92,6 +93,8 @@ namespace osu.Game.Tests.Visual.Navigation .AsEnumerable() .First(k => k.RulesetName == "osu" && k.ActionInt == 0); + private Screens.Select.SongSelect songSelect => Game.ScreenStack.CurrentScreen as Screens.Select.SongSelect; + private Player player => Game.ScreenStack.CurrentScreen as Player; private KeyCounter keyCounter => player.ChildrenOfType().First(); From aef25df80844444e517f9bdd9be2bab17dc5a979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 17:06:08 +0900 Subject: [PATCH 261/261] Add helper scripts for using local resources --- UseLocalResources.ps1 | 12 ++++++++++++ UseLocalResources.sh | 11 +++++++++++ 2 files changed, 23 insertions(+) create mode 100644 UseLocalResources.ps1 create mode 100755 UseLocalResources.sh diff --git a/UseLocalResources.ps1 b/UseLocalResources.ps1 new file mode 100644 index 0000000000..f9d9df01bb --- /dev/null +++ b/UseLocalResources.ps1 @@ -0,0 +1,12 @@ +$CSPROJ="osu.Game/osu.Game.csproj" +$SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Game.Resources; +dotnet sln $SLN add ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj +dotnet add $CSPROJ reference ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj + +$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json +$TMP=New-TemporaryFile +$SLNF.solution.projects += ("../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj") +ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8 +Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force diff --git a/UseLocalResources.sh b/UseLocalResources.sh new file mode 100755 index 0000000000..6d9d2b6016 --- /dev/null +++ b/UseLocalResources.sh @@ -0,0 +1,11 @@ +CSPROJ="osu.Game/osu.Game.csproj" +SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Game.Resources; +dotnet sln $SLN add ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj +dotnet add $CSPROJ reference ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj + +SLNF="osu.Desktop.slnf" +TMP=$(mktemp) +jq '.solution.projects += ["../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj"]' $SLNF > $TMP +mv -f $TMP $SLNF