From beb18006dacb2ae2ba2cddbb078bd8ec6a0c0c12 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 19 Feb 2020 20:18:02 +0100 Subject: [PATCH 01/82] Show 0 pp if map is loved --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index f1250679c1..7baf6c7fcb 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -154,7 +154,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { new OsuSpriteText { - Text = $@"{score.PP:N0}", + Text = $@"{score.PP ?? 0:N0}", Font = OsuFont.GetFont(size: text_size) }, new FillFlowContainer diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index a15dc57d23..0616871897 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -96,7 +96,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores totalScoreColumn.Text = $@"{value.TotalScore:N0}"; accuracyColumn.Text = value.DisplayAccuracy; maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; - ppColumn.Text = $@"{value.PP:N0}"; + ppColumn.Text = $@"{value.PP ?? 0:N0}"; statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); modsColumn.Mods = value.Mods; From 397e35d0a0128adf174a7539f13a2a70da153762 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 26 Feb 2020 21:36:52 +0100 Subject: [PATCH 02/82] Hide pp column if map is loved or qualified --- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 36 +++++++++---------- .../Scores/TopScoreStatisticsSection.cs | 3 +- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 7baf6c7fcb..c9008adc85 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -88,11 +88,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95))); - columns.AddRange(new[] - { - new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30)), - new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), - }); + if (score.PP.HasValue) + columns.Add(new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30))); + + columns.Add(new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize))); return columns.ToArray(); } @@ -150,24 +149,25 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } - content.AddRange(new Drawable[] + if (score.PP.HasValue) { - new OsuSpriteText + content.Add(new OsuSpriteText { - Text = $@"{score.PP ?? 0:N0}", + Text = $@"{score.PP:N0}", Font = OsuFont.GetFont(size: text_size) - }, - new FillFlowContainer + }); + } + + content.Add(new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(1), + ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) { - Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Spacing = new Vector2(1), - ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f) - }) - }, + Scale = new Vector2(0.3f) + }) }); return content.ToArray(); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 0616871897..12ad014f61 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -96,7 +96,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores totalScoreColumn.Text = $@"{value.TotalScore:N0}"; accuracyColumn.Text = value.DisplayAccuracy; maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; - ppColumn.Text = $@"{value.PP ?? 0:N0}"; + ppColumn.Alpha = value.PP.HasValue ? 1 : 0; + ppColumn.Text = $@"{value.PP:N0}"; statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); modsColumn.Mods = value.Mods; From d71b51690235187b31fb73a28f70d1cedf583dd8 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Fri, 28 Feb 2020 21:58:37 +0100 Subject: [PATCH 03/82] Check beatmap ranking status instead of the pp value --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 10 +++++++--- .../BeatmapSet/Scores/TopScoreStatisticsSection.cs | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index c9008adc85..25537537d9 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -28,6 +29,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly FillFlowContainer backgroundFlow; private Color4 highAccuracyColour; + private bool isBeatmapRanked; public ScoreTable() { @@ -65,7 +67,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores for (int i = 0; i < value.Count; i++) backgroundFlow.Add(new ScoreTableRowBackground(i, value[i], row_height)); - Columns = createHeaders(value[0]); + isBeatmapRanked = value.First().Beatmap.Status == BeatmapSetOnlineStatus.Ranked; + + Columns = createHeaders(value.First()); Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); } } @@ -88,7 +92,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95))); - if (score.PP.HasValue) + if (isBeatmapRanked) columns.Add(new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30))); columns.Add(new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize))); @@ -149,7 +153,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } - if (score.PP.HasValue) + if (isBeatmapRanked) { content.Add(new OsuSpriteText { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 12ad014f61..9ecc40eed2 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; @@ -96,7 +97,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores totalScoreColumn.Text = $@"{value.TotalScore:N0}"; accuracyColumn.Text = value.DisplayAccuracy; maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; - ppColumn.Alpha = value.PP.HasValue ? 1 : 0; + ppColumn.Alpha = value.Beatmap.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0; ppColumn.Text = $@"{value.PP:N0}"; statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); From f661806513767adaf69f5989bcf4b3b90397f994 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sat, 29 Feb 2020 15:29:00 +0100 Subject: [PATCH 04/82] Move checking logic out of ScoreTable --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 9 ++++----- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 3 ++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 25537537d9..3a58f481e1 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -29,7 +29,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly FillFlowContainer backgroundFlow; private Color4 highAccuracyColour; - private bool isBeatmapRanked; public ScoreTable() { @@ -67,13 +66,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores for (int i = 0; i < value.Count; i++) backgroundFlow.Add(new ScoreTableRowBackground(i, value[i], row_height)); - isBeatmapRanked = value.First().Beatmap.Status == BeatmapSetOnlineStatus.Ranked; - Columns = createHeaders(value.First()); Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); } } + public bool IsBeatmapRanked { get; set; } + private TableColumn[] createHeaders(ScoreInfo score) { var columns = new List @@ -92,7 +91,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95))); - if (isBeatmapRanked) + if (IsBeatmapRanked) columns.Add(new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30))); columns.Add(new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize))); @@ -153,7 +152,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } - if (isBeatmapRanked) + if (IsBeatmapRanked) { content.Add(new OsuSpriteText { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index e831c8ce42..5a931fffcb 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -59,11 +59,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } var scoreInfos = value.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToList(); + var topScore = scoreInfos.First(); scoreTable.Scores = scoreInfos; + scoreTable.IsBeatmapRanked = topScore.Beatmap.Status == BeatmapSetOnlineStatus.Ranked; scoreTable.Show(); - var topScore = scoreInfos.First(); var userScore = value.UserScore; var userScoreInfo = userScore?.Score.CreateScoreInfo(rulesets); From 4d19278df498a940b2356d84a00eeb77456cc6e7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sat, 29 Feb 2020 15:43:48 +0100 Subject: [PATCH 05/82] Remove using directive --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 3a58f481e1..af6bf8299f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; From 6d939e9d415609f7d64dea9874456529d32b48f4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 12:42:48 +0900 Subject: [PATCH 06/82] Add failing test scenes --- .../TestSceneCatchModPerfect.cs | 54 +++++++++++++++ .../TestSceneManiaModPerfect.cs | 26 ++++++++ .../TestSceneOsuModPerfect.cs | 52 +++++++++++++++ .../TestSceneTaikoModPerfect.cs | 30 +++++++++ osu.Game/Tests/Visual/ModPerfectTestScene.cs | 66 +++++++++++++++++++ 5 files changed, 228 insertions(+) create mode 100644 osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs create mode 100644 osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs create mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs create mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs create mode 100644 osu.Game/Tests/Visual/ModPerfectTestScene.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs new file mode 100644 index 0000000000..f5bd3b1133 --- /dev/null +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs @@ -0,0 +1,54 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Catch.Mods; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Tests.Visual; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Tests +{ + public class TestSceneCatchModPerfect : ModPerfectTestScene + { + public TestSceneCatchModPerfect() + : base(new CatchRuleset(), new CatchModPerfect()) + { + } + + [TestCase(false)] + [TestCase(true)] + public void TestBananaShower(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new BananaShower { StartTime = 1000, EndTime = 3000 }, false), shouldMiss); + + [TestCase(false)] + [TestCase(true)] + public void TestFruit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Fruit { StartTime = 1000 }), shouldMiss); + + [TestCase(false)] + [TestCase(true)] + public void TestTestJuiceStream(bool shouldMiss) + { + var stream = new JuiceStream + { + StartTime = 1000, + Path = new SliderPath(PathType.Linear, new[] + { + Vector2.Zero, + new Vector2(100, 0), + }) + }; + + CreateHitObjectTest(new HitObjectTestCase(stream), shouldMiss); + } + + // We only care about testing misses, hits are tested via JuiceStream + [TestCase(true)] + public void TestDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Droplet { StartTime = 1000 }), shouldMiss); + + // We only care about testing misses, hits are tested via JuiceStream + [TestCase(true)] + public void TestTinyDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new TinyDroplet { StartTime = 1000 }), shouldMiss); + } +} diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs new file mode 100644 index 0000000000..f49a19e218 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs @@ -0,0 +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 NUnit.Framework; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests +{ + public class TestSceneManiaModPerfect : ModPerfectTestScene + { + public TestSceneManiaModPerfect() + : base(new ManiaRuleset(), new ManiaModPerfect()) + { + } + + [TestCase(false)] + [TestCase(true)] + public void TestNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Note { StartTime = 1000 }), shouldMiss); + + [TestCase(false)] + [TestCase(true)] + public void TestHoldNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new HoldNote { StartTime = 1000, EndTime = 3000 }), shouldMiss); + } +} diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs new file mode 100644 index 0000000000..02fd5b5a79 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs @@ -0,0 +1,52 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Tests.Visual; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Tests +{ + public class TestSceneOsuModPerfect : ModPerfectTestScene + { + public TestSceneOsuModPerfect() + : base(new OsuRuleset(), new OsuModPerfect()) + { + } + + [TestCase(false)] + [TestCase(true)] + public void TestHitCircle(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new HitCircle { StartTime = 1000 }), shouldMiss); + + [TestCase(false)] + [TestCase(true)] + public void TestSlider(bool shouldMiss) + { + var slider = new Slider + { + StartTime = 1000, + Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) + }; + + CreateHitObjectTest(new HitObjectTestCase(slider), shouldMiss); + } + + [TestCase(false)] + [TestCase(true)] + public void TestSpinner(bool shouldMiss) + { + var spinner = new Spinner + { + StartTime = 1000, + EndTime = 3000, + Position = new Vector2(256, 192) + }; + + CreateHitObjectTest(new HitObjectTestCase(spinner), shouldMiss); + } + } +} diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs new file mode 100644 index 0000000000..4069ee7983 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Taiko.Mods; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Taiko.Tests +{ + public class TestSceneTaikoModPerfect : ModPerfectTestScene + { + public TestSceneTaikoModPerfect() + : base(new TaikoRuleset(), new TaikoModPerfect()) + { + } + + [TestCase(false)] + [TestCase(true)] + public void TestHit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new CentreHit { StartTime = 1000 }), shouldMiss); + + [TestCase(false)] + [TestCase(true)] + public void TestDrumRoll(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new DrumRoll { StartTime = 1000, EndTime = 3000 }), shouldMiss); + + [TestCase(false)] + [TestCase(true)] + public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Swell { StartTime = 1000, EndTime = 3000 }), shouldMiss); + } +} diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs new file mode 100644 index 0000000000..272b5366a9 --- /dev/null +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -0,0 +1,66 @@ +// 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.TypeExtensions; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Scoring; + +namespace osu.Game.Tests.Visual +{ + public abstract class ModPerfectTestScene : ModSandboxTestScene + { + private readonly ModPerfect perfectMod; + + protected ModPerfectTestScene(Ruleset ruleset, ModPerfect perfectMod) + : base(ruleset) + { + this.perfectMod = perfectMod; + } + + protected void CreateHitObjectTest(HitObjectTestCase testCaseData, bool shouldMiss) => CreateModTest(new ModTestCaseData(testCaseData.HitObject.GetType().ReadableName(), perfectMod) + { + Beatmap = new Beatmap + { + BeatmapInfo = { Ruleset = Ruleset.Value }, + HitObjects = { testCaseData.HitObject } + }, + Autoplay = !shouldMiss, + PassCondition = () => ((PerfectModTestPlayer)Player).CheckFailed(shouldMiss && testCaseData.FailOnMiss) + }); + + protected sealed override TestPlayer CreateReplayPlayer(Score score) => new PerfectModTestPlayer(score); + + private class PerfectModTestPlayer : TestPlayer + { + public PerfectModTestPlayer(Score score) + : base(score) + { + } + + protected override bool AllowFail => true; + + public bool CheckFailed(bool failed) + { + if (!failed) + return ScoreProcessor.HasCompleted && !HealthProcessor.HasFailed; + + return ScoreProcessor.JudgedHits > 0 && HealthProcessor.HasFailed; + } + } + + protected class HitObjectTestCase + { + public readonly HitObject HitObject; + public readonly bool FailOnMiss; + + public HitObjectTestCase(HitObject hitObject, bool failOnMiss = true) + { + HitObject = hitObject; + FailOnMiss = failOnMiss; + } + } + } +} From e801ad514bacd08de9b09f4669278ac51a777223 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 13:24:02 +0900 Subject: [PATCH 07/82] Fix ruleset nullref --- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index 272b5366a9..ded1b3676e 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -12,11 +12,13 @@ namespace osu.Game.Tests.Visual { public abstract class ModPerfectTestScene : ModSandboxTestScene { + private readonly Ruleset ruleset; private readonly ModPerfect perfectMod; protected ModPerfectTestScene(Ruleset ruleset, ModPerfect perfectMod) : base(ruleset) { + this.ruleset = ruleset; this.perfectMod = perfectMod; } @@ -24,7 +26,7 @@ namespace osu.Game.Tests.Visual { Beatmap = new Beatmap { - BeatmapInfo = { Ruleset = Ruleset.Value }, + BeatmapInfo = { Ruleset = ruleset.RulesetInfo }, HitObjects = { testCaseData.HitObject } }, Autoplay = !shouldMiss, From cd43a0c9e8071c818fa289972076ff61fcc1b5c3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 13:24:07 +0900 Subject: [PATCH 08/82] Better check for failing state --- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index ded1b3676e..31d2ce9281 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual if (!failed) return ScoreProcessor.HasCompleted && !HealthProcessor.HasFailed; - return ScoreProcessor.JudgedHits > 0 && HealthProcessor.HasFailed; + return HealthProcessor.HasFailed; } } From bb4193d985cb47e450adafe03059b03fcff38705 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 13:24:55 +0900 Subject: [PATCH 09/82] Fix taiko infinity health drain on some beatmaps --- osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs index edb089dbac..dd3c2289ea 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; @@ -39,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring { base.ApplyBeatmap(beatmap); - hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.OfType().Count() * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98)); + hpMultiplier = 1 / (object_count_factor * Math.Max(1, beatmap.HitObjects.OfType().Count()) * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98)); hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120); } From e58fb3f52823a4feb1ead00097000e4e689cac48 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 13:25:16 +0900 Subject: [PATCH 10/82] Make default taiko HP 1 for test scene --- .../TestSceneTaikoModPerfect.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs index 4069ee7983..b67810846e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs @@ -2,8 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Scoring; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests @@ -11,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Tests public class TestSceneTaikoModPerfect : ModPerfectTestScene { public TestSceneTaikoModPerfect() - : base(new TaikoRuleset(), new TaikoModPerfect()) + : base(new TestTaikoRuleset(), new TaikoModPerfect()) { } @@ -26,5 +28,20 @@ namespace osu.Game.Rulesets.Taiko.Tests [TestCase(false)] [TestCase(true)] public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Swell { StartTime = 1000, EndTime = 3000 }), shouldMiss); + + private class TestTaikoRuleset : TaikoRuleset + { + public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new TestTaikoHealthProcessor(); + + private class TestTaikoHealthProcessor : TaikoHealthProcessor + { + protected override void Reset(bool storeResults) + { + base.Reset(storeResults); + + Health.Value = 1; // Don't care about the health condition (only the mod condition) + } + } + } } } From 6fb52e5370c67de6a5f67bff3d8f19b13dc5bc22 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 13:25:36 +0900 Subject: [PATCH 11/82] Fix custom rulesets not being testable --- osu.Game/Tests/Visual/PlayerTestScene.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 0d5aac8cfd..3d8eefaa9d 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -67,6 +67,7 @@ namespace osu.Game.Tests.Visual var beatmap = CreateBeatmap(ruleset.RulesetInfo); Beatmap.Value = CreateWorkingBeatmap(beatmap); + Ruleset.Value = ruleset.RulesetInfo; if (!AllowFail) { From 6d051d9e42599c694d9a989c3c6a897451d968b8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Mar 2020 13:25:56 +0900 Subject: [PATCH 12/82] Fix perfect mod failure cases --- osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs | 6 ++++++ osu.Game/Rulesets/Mods/ModPerfect.cs | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs b/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs index fb92399102..e3391c47f1 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs @@ -1,11 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Catch.Judgements; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Mods { public class CatchModPerfect : ModPerfect { + protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) + => !(result.Judgement is CatchBananaJudgement) + && base.FailCondition(healthProcessor, result); } } diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs index 882d3ebd6a..7fe606d584 100644 --- a/osu.Game/Rulesets/Mods/ModPerfect.cs +++ b/osu.Game/Rulesets/Mods/ModPerfect.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Mods public override IconUsage? Icon => OsuIcon.ModPerfect; public override string Description => "SS or quit."; - protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) => result.Type != result.Judgement.MaxResult; + protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) + => !(result.Judgement is IgnoreJudgement) + && result.Type != result.Judgement.MaxResult; } } From d11d29c1f7303988baad64f2efcb4979af6425db Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Mar 2020 15:30:53 +0900 Subject: [PATCH 13/82] Adjust namespaces --- .../{ => Mods}/TestSceneCatchModPerfect.cs | 2 +- .../{ => Mods}/TestSceneManiaModPerfect.cs | 2 +- .../{ => Mods}/TestSceneOsuModPerfect.cs | 2 +- .../{ => Mods}/TestSceneTaikoModPerfect.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game.Rulesets.Catch.Tests/{ => Mods}/TestSceneCatchModPerfect.cs (97%) rename osu.Game.Rulesets.Mania.Tests/{ => Mods}/TestSceneManiaModPerfect.cs (95%) rename osu.Game.Rulesets.Osu.Tests/{ => Mods}/TestSceneOsuModPerfect.cs (97%) rename osu.Game.Rulesets.Taiko.Tests/{ => Mods}/TestSceneTaikoModPerfect.cs (97%) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs similarity index 97% rename from osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs rename to osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs index f5bd3b1133..3e28bac02f 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModPerfect.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Tests.Visual; using osuTK; -namespace osu.Game.Rulesets.Catch.Tests +namespace osu.Game.Rulesets.Catch.Tests.Mods { public class TestSceneCatchModPerfect : ModPerfectTestScene { diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs similarity index 95% rename from osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs rename to osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs index f49a19e218..4e11a302c9 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaModPerfect.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Tests.Visual; -namespace osu.Game.Rulesets.Mania.Tests +namespace osu.Game.Rulesets.Mania.Tests.Mods { public class TestSceneManiaModPerfect : ModPerfectTestScene { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs similarity index 97% rename from osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs rename to osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs index 02fd5b5a79..fc2dfa16ec 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuModPerfect.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Visual; using osuTK; -namespace osu.Game.Rulesets.Osu.Tests +namespace osu.Game.Rulesets.Osu.Tests.Mods { public class TestSceneOsuModPerfect : ModPerfectTestScene { diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs similarity index 97% rename from osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs rename to osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs index b67810846e..fd9d01a3db 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoModPerfect.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Scoring; using osu.Game.Tests.Visual; -namespace osu.Game.Rulesets.Taiko.Tests +namespace osu.Game.Rulesets.Taiko.Tests.Mods { public class TestSceneTaikoModPerfect : ModPerfectTestScene { From a26ac31c64076d68335ba53018132eb860907101 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Mar 2020 15:33:54 +0900 Subject: [PATCH 14/82] Fix test name --- osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs index 3e28bac02f..56d2fe1ee0 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods [TestCase(false)] [TestCase(true)] - public void TestTestJuiceStream(bool shouldMiss) + public void TestJuiceStream(bool shouldMiss) { var stream = new JuiceStream { From 8dcdd6db6fc39b1e33a65675a5eb4c8cdccde8e5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 3 Mar 2020 16:20:36 +0300 Subject: [PATCH 15/82] Rename UpdateStream components to ChangelogUpdateStream --- .../Visual/Online/TestSceneChangelogOverlay.cs | 4 ++-- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 4 ++-- ...ateStreamBadge.cs => ChangelogUpdateStreamBadge.cs} | 4 ++-- ...mBadgeArea.cs => ChangelogUpdateStreamBadgeArea.cs} | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) rename osu.Game/Overlays/Changelog/{UpdateStreamBadge.cs => ChangelogUpdateStreamBadge.cs} (97%) rename osu.Game/Overlays/Changelog/{UpdateStreamBadgeArea.cs => ChangelogUpdateStreamBadgeArea.cs} (84%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs index 7a8570c09b..530a486de8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs @@ -17,8 +17,8 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { - typeof(UpdateStreamBadgeArea), - typeof(UpdateStreamBadge), + typeof(ChangelogUpdateStreamBadgeArea), + typeof(ChangelogUpdateStreamBadge), typeof(ChangelogHeader), typeof(ChangelogContent), typeof(ChangelogListing), diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index dcadbf4cf5..0667bedfc6 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Changelog public Action ListingSelected; - public UpdateStreamBadgeArea Streams; + public ChangelogUpdateStreamBadgeArea Streams; private const string listing_string = "listing"; @@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Changelog Horizontal = 65, Vertical = 20 }, - Child = Streams = new UpdateStreamBadgeArea() + Child = Streams = new ChangelogUpdateStreamBadgeArea() } } }; diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadge.cs similarity index 97% rename from osu.Game/Overlays/Changelog/UpdateStreamBadge.cs rename to osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadge.cs index 6786bbc49f..20cc564013 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadge.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadge.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Changelog { - public class UpdateStreamBadge : TabItem + public class ChangelogUpdateStreamBadge : TabItem { private const float badge_width = 100; private const float transition_duration = 100; @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Changelog private FillFlowContainer text; private ExpandingBar expandingBar; - public UpdateStreamBadge(APIUpdateStream stream) + public ChangelogUpdateStreamBadge(APIUpdateStream stream) : base(stream) { this.stream = stream; diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadgeArea.cs similarity index 84% rename from osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs rename to osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadgeArea.cs index ffb622dd37..5ab86a72f3 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadgeArea.cs @@ -10,9 +10,9 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Overlays.Changelog { - public class UpdateStreamBadgeArea : TabControl + public class ChangelogUpdateStreamBadgeArea : TabControl { - public UpdateStreamBadgeArea() + public ChangelogUpdateStreamBadgeArea() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Changelog protected override bool OnHover(HoverEvent e) { - foreach (var streamBadge in TabContainer.Children.OfType()) + foreach (var streamBadge in TabContainer.Children.OfType()) streamBadge.UserHoveringArea = true; return base.OnHover(e); @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Changelog protected override void OnHoverLost(HoverLostEvent e) { - foreach (var streamBadge in TabContainer.Children.OfType()) + foreach (var streamBadge in TabContainer.Children.OfType()) streamBadge.UserHoveringArea = false; base.OnHoverLost(e); @@ -50,6 +50,6 @@ namespace osu.Game.Overlays.Changelog protected override Dropdown CreateDropdown() => null; protected override TabItem CreateTabItem(APIUpdateStream value) => - new UpdateStreamBadge(value) { SelectedTab = { BindTarget = Current } }; + new ChangelogUpdateStreamBadge(value) { SelectedTab = { BindTarget = Current } }; } } From 937d9da43b183104f4cca9a4de427922a960bf37 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 3 Mar 2020 17:01:58 +0300 Subject: [PATCH 16/82] Implement OverlayUpdateStreamControl component --- .../Online/TestSceneChangelogOverlay.cs | 4 +- .../Overlays/Changelog/ChangelogHeader.cs | 4 +- .../Changelog/ChangelogUpdateStreamControl.cs | 12 +++ .../Changelog/ChangelogUpdateStreamItem.cs | 25 ++++++ ...eArea.cs => OverlayUpdateStreamControl.cs} | 53 ++++++------ ...eamBadge.cs => OverlayUpdateStreamItem.cs} | 80 ++++++++++--------- 6 files changed, 111 insertions(+), 67 deletions(-) create mode 100644 osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs create mode 100644 osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs rename osu.Game/Overlays/{Changelog/ChangelogUpdateStreamBadgeArea.cs => OverlayUpdateStreamControl.cs} (61%) rename osu.Game/Overlays/{Changelog/ChangelogUpdateStreamBadge.cs => OverlayUpdateStreamItem.cs} (78%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs index 530a486de8..864fd31a0f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs @@ -17,8 +17,8 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { - typeof(ChangelogUpdateStreamBadgeArea), - typeof(ChangelogUpdateStreamBadge), + typeof(ChangelogUpdateStreamControl), + typeof(ChangelogUpdateStreamItem), typeof(ChangelogHeader), typeof(ChangelogContent), typeof(ChangelogListing), diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 0667bedfc6..532efeb4bd 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Changelog public Action ListingSelected; - public ChangelogUpdateStreamBadgeArea Streams; + public ChangelogUpdateStreamControl Streams; private const string listing_string = "listing"; @@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Changelog Horizontal = 65, Vertical = 20 }, - Child = Streams = new ChangelogUpdateStreamBadgeArea() + Child = Streams = new ChangelogUpdateStreamControl() } } }; diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs new file mode 100644 index 0000000000..555f0904d6 --- /dev/null +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs @@ -0,0 +1,12 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Changelog +{ + public class ChangelogUpdateStreamControl : OverlayUpdateStreamControl + { + protected override OverlayUpdateStreamItem CreateStreamItem(APIUpdateStream value) => new ChangelogUpdateStreamItem(value); + } +} diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs new file mode 100644 index 0000000000..6a4801bc4b --- /dev/null +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Humanizer; +using osu.Game.Online.API.Requests.Responses; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Changelog +{ + public class ChangelogUpdateStreamItem : OverlayUpdateStreamItem + { + public ChangelogUpdateStreamItem(APIUpdateStream stream) + : base(stream) + { + } + + protected override string GetMainText() => Value.DisplayName; + + protected override string GetAdditionalText() => Value.LatestBuild.DisplayVersion; + + protected override string GetInfoText() => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null; + + protected override Color4 GetBarColour() => Value.Colour; + } +} diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadgeArea.cs b/osu.Game/Overlays/OverlayUpdateStreamControl.cs similarity index 61% rename from osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadgeArea.cs rename to osu.Game/Overlays/OverlayUpdateStreamControl.cs index 5ab86a72f3..0fdf6c0111 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadgeArea.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamControl.cs @@ -3,42 +3,32 @@ using osu.Framework.Graphics; using osu.Framework.Input.Events; -using osu.Game.Online.API.Requests.Responses; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.UserInterface; +using JetBrains.Annotations; -namespace osu.Game.Overlays.Changelog +namespace osu.Game.Overlays { - public class ChangelogUpdateStreamBadgeArea : TabControl + public abstract class OverlayUpdateStreamControl : TabControl { - public ChangelogUpdateStreamBadgeArea() + protected OverlayUpdateStreamControl() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; } - public void Populate(List streams) + public void Populate(List streams) => streams.ForEach(AddItem); + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(T value) => CreateStreamItem(value).With(item => { - foreach (var updateStream in streams) - AddItem(updateStream); - } + item.SelectedItem.BindTo(Current); + }); - protected override bool OnHover(HoverEvent e) - { - foreach (var streamBadge in TabContainer.Children.OfType()) - streamBadge.UserHoveringArea = true; - - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - foreach (var streamBadge in TabContainer.Children.OfType()) - streamBadge.UserHoveringArea = false; - - base.OnHoverLost(e); - } + [NotNull] + protected abstract OverlayUpdateStreamItem CreateStreamItem(T value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { @@ -47,9 +37,20 @@ namespace osu.Game.Overlays.Changelog AllowMultiline = true, }; - protected override Dropdown CreateDropdown() => null; + protected override bool OnHover(HoverEvent e) + { + foreach (var streamBadge in TabContainer.Children.OfType>()) + streamBadge.UserHoveringArea = true; - protected override TabItem CreateTabItem(APIUpdateStream value) => - new ChangelogUpdateStreamBadge(value) { SelectedTab = { BindTarget = Current } }; + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + foreach (var streamBadge in TabContainer.Children.OfType>()) + streamBadge.UserHoveringArea = false; + + base.OnHoverLost(e); + } } } diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadge.cs b/osu.Game/Overlays/OverlayUpdateStreamItem.cs similarity index 78% rename from osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadge.cs rename to osu.Game/Overlays/OverlayUpdateStreamItem.cs index 20cc564013..5014aac5b0 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamBadge.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamItem.cs @@ -1,44 +1,54 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using Humanizer; -using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Online.API.Requests.Responses; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics.Sprites; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Allocation; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics; using osuTK; +using osuTK.Graphics; -namespace osu.Game.Overlays.Changelog +namespace osu.Game.Overlays { - public class ChangelogUpdateStreamBadge : TabItem + public abstract class OverlayUpdateStreamItem : TabItem { - private const float badge_width = 100; private const float transition_duration = 100; + private const float tab_width = 100; - public readonly Bindable SelectedTab = new Bindable(); + public readonly Bindable SelectedItem = new Bindable(); - private readonly APIUpdateStream stream; + private bool userHoveringArea; + + public bool UserHoveringArea + { + set + { + if (value == userHoveringArea) + return; + + userHoveringArea = value; + updateState(); + } + } private FillFlowContainer text; private ExpandingBar expandingBar; - public ChangelogUpdateStreamBadge(APIUpdateStream stream) - : base(stream) + public OverlayUpdateStreamItem(T value) + : base(value) { - this.stream = stream; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - Size = new Vector2(stream.IsFeatured ? badge_width * 2 : badge_width, 60); + Size = new Vector2(GetWidth(), 60); Padding = new MarginPadding(5); AddRange(new Drawable[] @@ -52,17 +62,17 @@ namespace osu.Game.Overlays.Changelog { new OsuSpriteText { - Text = stream.DisplayName, + Text = GetMainText(), Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), }, new OsuSpriteText { - Text = stream.LatestBuild.DisplayVersion, + Text = GetAdditionalText(), Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), }, new OsuSpriteText { - Text = stream.LatestBuild.Users > 0 ? $"{"user".ToQuantity(stream.LatestBuild.Users, "N0")} online" : null, + Text = GetInfoText(), Font = OsuFont.GetFont(size: 10), Colour = colourProvider.Foreground1 }, @@ -71,7 +81,7 @@ namespace osu.Game.Overlays.Changelog expandingBar = new ExpandingBar { Anchor = Anchor.TopCentre, - Colour = stream.Colour, + Colour = GetBarColour(), ExpandedSize = 4, CollapsedSize = 2, Expanded = true @@ -79,9 +89,19 @@ namespace osu.Game.Overlays.Changelog new HoverClickSounds() }); - SelectedTab.BindValueChanged(_ => updateState(), true); + SelectedItem.BindValueChanged(_ => updateState(), true); } + protected abstract string GetMainText(); + + protected abstract string GetAdditionalText(); + + protected virtual string GetInfoText() => string.Empty; + + protected abstract Color4 GetBarColour(); + + protected virtual float GetWidth() => tab_width; + protected override void OnActivated() => updateState(); protected override void OnDeactivated() => updateState(); @@ -104,7 +124,7 @@ namespace osu.Game.Overlays.Changelog bool textHighlighted = IsHovered; bool barExpanded = IsHovered; - if (SelectedTab.Value == null) + if (SelectedItem.Value == null) { // at listing, all badges are highlighted when user is not hovering any badge. textHighlighted |= !userHoveringArea; @@ -122,19 +142,5 @@ namespace osu.Game.Overlays.Changelog expandingBar.Expanded = barExpanded; text.FadeTo(textHighlighted ? 1 : 0.5f, transition_duration, Easing.OutQuint); } - - private bool userHoveringArea; - - public bool UserHoveringArea - { - set - { - if (value == userHoveringArea) - return; - - userHoveringArea = value; - updateState(); - } - } } } From c0f7a83f6f3d4aaab9ce0d4d9ee2ae9674d238de Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 3 Mar 2020 17:10:25 +0300 Subject: [PATCH 17/82] Fix featured stream item width --- osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 6a4801bc4b..b796348242 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -14,6 +14,14 @@ namespace osu.Game.Overlays.Changelog { } + protected override float GetWidth() + { + if (Value.IsFeatured) + return base.GetWidth() * 2; + + return base.GetWidth(); + } + protected override string GetMainText() => Value.DisplayName; protected override string GetAdditionalText() => Value.LatestBuild.DisplayVersion; From 160d64eecf1cff32ed662fbfcbc129fcfe2b928f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 3 Mar 2020 17:37:01 +0300 Subject: [PATCH 18/82] FriendsOnlineStatusControl basic implementation --- .../TestSceneFriendsOnlineStatusControl.cs | 52 +++++++++++++++++++ .../Overlays/Home/Friends/FriendsBundle.cs | 48 +++++++++++++++++ .../Friends/FriendsOnlineStatusControl.cs | 10 ++++ .../Home/Friends/FriendsOnlineStatusItem.cs | 21 ++++++++ 4 files changed, 131 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs create mode 100644 osu.Game/Overlays/Home/Friends/FriendsBundle.cs create mode 100644 osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs create mode 100644 osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs new file mode 100644 index 0000000000..bb64593088 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs @@ -0,0 +1,52 @@ +// 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 NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Overlays; +using osu.Game.Overlays.Home.Friends; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneFriendsOnlineStatusControl : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(FriendsOnlineStatusControl), + typeof(FriendsOnlineStatusItem), + typeof(OverlayUpdateStreamControl<>), + typeof(OverlayUpdateStreamItem<>), + typeof(FriendsBundle) + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + private FriendsOnlineStatusControl control; + + [SetUp] + public void SetUp() => Schedule(() => + { + Clear(); + Add(control = new FriendsOnlineStatusControl + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + }); + + [Test] + public void Populate() + { + AddStep(@"Populate", () => control.Populate(new List + { + new FriendsBundle(FriendsOnlineStatus.All, 100), + new FriendsBundle(FriendsOnlineStatus.Online, 50), + new FriendsBundle(FriendsOnlineStatus.Offline, 50), + })); + } + } +} diff --git a/osu.Game/Overlays/Home/Friends/FriendsBundle.cs b/osu.Game/Overlays/Home/Friends/FriendsBundle.cs new file mode 100644 index 0000000000..e0f841da9a --- /dev/null +++ b/osu.Game/Overlays/Home/Friends/FriendsBundle.cs @@ -0,0 +1,48 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Home.Friends +{ + public class FriendsBundle + { + public FriendsOnlineStatus Status { get; } + + public int Amount { get; } + + public Color4 Colour => getColour(); + + public FriendsBundle(FriendsOnlineStatus status, int amount) + { + Status = status; + Amount = amount; + } + + private Color4 getColour() + { + switch (Status) + { + default: + throw new ArgumentException($@"{Status} status does not provide a colour in {nameof(getColour)}."); + + case FriendsOnlineStatus.All: + return Color4.White; + + case FriendsOnlineStatus.Online: + return Color4.Lime; + + case FriendsOnlineStatus.Offline: + return Color4.Black; + } + } + } + + public enum FriendsOnlineStatus + { + All, + Online, + Offline + } +} diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs new file mode 100644 index 0000000000..abcd04bb0e --- /dev/null +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs @@ -0,0 +1,10 @@ +// 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.Home.Friends +{ + public class FriendsOnlineStatusControl : OverlayUpdateStreamControl + { + protected override OverlayUpdateStreamItem CreateStreamItem(FriendsBundle value) => new FriendsOnlineStatusItem(value); + } +} diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs new file mode 100644 index 0000000000..0c77ef20b9 --- /dev/null +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.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 osuTK.Graphics; + +namespace osu.Game.Overlays.Home.Friends +{ + public class FriendsOnlineStatusItem : OverlayUpdateStreamItem + { + public FriendsOnlineStatusItem(FriendsBundle value) + : base(value) + { + } + + protected override string GetMainText() => Value.Status.ToString(); + + protected override string GetAdditionalText() => Value.Amount.ToString(); + + protected override Color4 GetBarColour() => Value.Colour; + } +} From 83dad93b6d499555d8c015049599dc3df153dff6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 3 Mar 2020 18:08:51 +0300 Subject: [PATCH 19/82] Make Populate() accept list of users --- .../TestSceneFriendsOnlineStatusControl.cs | 23 +++++++++++++++---- .../Friends/FriendsOnlineStatusControl.cs | 16 +++++++++++++ osu.Game/Overlays/OverlayUpdateStreamItem.cs | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs index bb64593088..87e7d848a8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Overlays; using osu.Game.Overlays.Home.Friends; +using osu.Game.Users; namespace osu.Game.Tests.Visual.UserInterface { @@ -41,12 +43,25 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void Populate() { - AddStep(@"Populate", () => control.Populate(new List + AddStep("Populate", () => control.Populate(new List { - new FriendsBundle(FriendsOnlineStatus.All, 100), - new FriendsBundle(FriendsOnlineStatus.Online, 50), - new FriendsBundle(FriendsOnlineStatus.Offline, 50), + new User + { + IsOnline = true + }, + new User + { + IsOnline = false + }, + new User + { + IsOnline = false + } })); + + AddAssert("3 users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.All)?.Amount == 3); + AddAssert("1 online user", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Online)?.Amount == 1); + AddAssert("2 offline users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Offline)?.Amount == 2); } } } diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs index abcd04bb0e..a92de9dbeb 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs @@ -1,10 +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 System.Collections.Generic; +using System.Linq; +using osu.Game.Users; + namespace osu.Game.Overlays.Home.Friends { public class FriendsOnlineStatusControl : OverlayUpdateStreamControl { protected override OverlayUpdateStreamItem CreateStreamItem(FriendsBundle value) => new FriendsOnlineStatusItem(value); + + public void Populate(List users) + { + var userCount = users.Count; + var onlineUsersCount = users.Count(user => user.IsOnline); + + AddItem(new FriendsBundle(FriendsOnlineStatus.All, userCount)); + AddItem(new FriendsBundle(FriendsOnlineStatus.Online, onlineUsersCount)); + AddItem(new FriendsBundle(FriendsOnlineStatus.Offline, userCount - onlineUsersCount)); + + Current.Value = Items.FirstOrDefault(); + } } } diff --git a/osu.Game/Overlays/OverlayUpdateStreamItem.cs b/osu.Game/Overlays/OverlayUpdateStreamItem.cs index 5014aac5b0..bf8e6ac3b9 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamItem.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamItem.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays private FillFlowContainer text; private ExpandingBar expandingBar; - public OverlayUpdateStreamItem(T value) + protected OverlayUpdateStreamItem(T value) : base(value) { } From 06b23b626ecaab8754c602087e9af752979e51f2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 00:15:10 +0300 Subject: [PATCH 20/82] Simplify test scene setup --- .../TestSceneFriendsOnlineStatusControl.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs index 87e7d848a8..614e99ee0e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs @@ -30,14 +30,10 @@ namespace osu.Game.Tests.Visual.UserInterface private FriendsOnlineStatusControl control; [SetUp] - public void SetUp() => Schedule(() => + public void SetUp() => Schedule(() => Child = control = new FriendsOnlineStatusControl { - Clear(); - Add(control = new FriendsOnlineStatusControl - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); + Anchor = Anchor.Centre, + Origin = Anchor.Centre, }); [Test] From c22f61b2b1ad9ec6663727b79eddb3616d9799f3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 00:28:47 +0300 Subject: [PATCH 21/82] Move colour selection to the FriendsOnlineStatusItem --- .../Changelog/ChangelogUpdateStreamItem.cs | 3 ++- .../Overlays/Home/Friends/FriendsBundle.cs | 23 ------------------- .../Home/Friends/FriendsOnlineStatusItem.cs | 20 +++++++++++++++- osu.Game/Overlays/OverlayUpdateStreamItem.cs | 6 ++--- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index b796348242..189c156b35 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using Humanizer; +using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using osuTK.Graphics; @@ -28,6 +29,6 @@ namespace osu.Game.Overlays.Changelog protected override string GetInfoText() => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null; - protected override Color4 GetBarColour() => Value.Colour; + protected override Color4 GetBarColour(OsuColour colours) => Value.Colour; } } diff --git a/osu.Game/Overlays/Home/Friends/FriendsBundle.cs b/osu.Game/Overlays/Home/Friends/FriendsBundle.cs index e0f841da9a..aa403feffc 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsBundle.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsBundle.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. -using System; -using osuTK.Graphics; - namespace osu.Game.Overlays.Home.Friends { public class FriendsBundle @@ -12,31 +9,11 @@ namespace osu.Game.Overlays.Home.Friends public int Amount { get; } - public Color4 Colour => getColour(); - public FriendsBundle(FriendsOnlineStatus status, int amount) { Status = status; Amount = amount; } - - private Color4 getColour() - { - switch (Status) - { - default: - throw new ArgumentException($@"{Status} status does not provide a colour in {nameof(getColour)}."); - - case FriendsOnlineStatus.All: - return Color4.White; - - case FriendsOnlineStatus.Online: - return Color4.Lime; - - case FriendsOnlineStatus.Offline: - return Color4.Black; - } - } } public enum FriendsOnlineStatus diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs index 0c77ef20b9..bd480aebe8 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using osu.Game.Graphics; using osuTK.Graphics; namespace osu.Game.Overlays.Home.Friends @@ -16,6 +18,22 @@ namespace osu.Game.Overlays.Home.Friends protected override string GetAdditionalText() => Value.Amount.ToString(); - protected override Color4 GetBarColour() => Value.Colour; + protected override Color4 GetBarColour(OsuColour colours) + { + switch (Value.Status) + { + default: + throw new ArgumentException($@"{Value.Status} status does not provide a colour in {nameof(GetBarColour)}."); + + case FriendsOnlineStatus.All: + return Color4.White; + + case FriendsOnlineStatus.Online: + return colours.GreenLight; + + case FriendsOnlineStatus.Offline: + return Color4.Black; + } + } } } diff --git a/osu.Game/Overlays/OverlayUpdateStreamItem.cs b/osu.Game/Overlays/OverlayUpdateStreamItem.cs index bf8e6ac3b9..ce9aca6f1f 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamItem.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamItem.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load(OverlayColourProvider colourProvider, OsuColour colours) { Size = new Vector2(GetWidth(), 60); Padding = new MarginPadding(5); @@ -81,7 +81,7 @@ namespace osu.Game.Overlays expandingBar = new ExpandingBar { Anchor = Anchor.TopCentre, - Colour = GetBarColour(), + Colour = GetBarColour(colours), ExpandedSize = 4, CollapsedSize = 2, Expanded = true @@ -98,7 +98,7 @@ namespace osu.Game.Overlays protected virtual string GetInfoText() => string.Empty; - protected abstract Color4 GetBarColour(); + protected abstract Color4 GetBarColour(OsuColour colours); protected virtual float GetWidth() => tab_width; From 4d5445b5dc63d8b2c3ff889c70cd5f573b37d25d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 00:31:06 +0300 Subject: [PATCH 22/82] Rename Amount to Count --- .../UserInterface/TestSceneFriendsOnlineStatusControl.cs | 6 +++--- osu.Game/Overlays/Home/Friends/FriendsBundle.cs | 6 +++--- osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs index 614e99ee0e..45f8a029a8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs @@ -55,9 +55,9 @@ namespace osu.Game.Tests.Visual.UserInterface } })); - AddAssert("3 users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.All)?.Amount == 3); - AddAssert("1 online user", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Online)?.Amount == 1); - AddAssert("2 offline users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Offline)?.Amount == 2); + AddAssert("3 users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.All)?.Count == 3); + AddAssert("1 online user", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Online)?.Count == 1); + AddAssert("2 offline users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Offline)?.Count == 2); } } } diff --git a/osu.Game/Overlays/Home/Friends/FriendsBundle.cs b/osu.Game/Overlays/Home/Friends/FriendsBundle.cs index aa403feffc..75d00dfef8 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsBundle.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsBundle.cs @@ -7,12 +7,12 @@ namespace osu.Game.Overlays.Home.Friends { public FriendsOnlineStatus Status { get; } - public int Amount { get; } + public int Count { get; } - public FriendsBundle(FriendsOnlineStatus status, int amount) + public FriendsBundle(FriendsOnlineStatus status, int count) { Status = status; - Amount = amount; + Count = count; } } diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs index bd480aebe8..4043c72bc4 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Home.Friends protected override string GetMainText() => Value.Status.ToString(); - protected override string GetAdditionalText() => Value.Amount.ToString(); + protected override string GetAdditionalText() => Value.Count.ToString(); protected override Color4 GetBarColour(OsuColour colours) { From 17f2baf600fd703a1f6769bbc08c9298019eb07a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 00:35:32 +0300 Subject: [PATCH 23/82] Remove GetWidth function --- .../Changelog/ChangelogUpdateStreamItem.cs | 10 ++-------- osu.Game/Overlays/OverlayUpdateStreamItem.cs | 14 ++++---------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 189c156b35..5a16fc8ddf 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -13,14 +13,8 @@ namespace osu.Game.Overlays.Changelog public ChangelogUpdateStreamItem(APIUpdateStream stream) : base(stream) { - } - - protected override float GetWidth() - { - if (Value.IsFeatured) - return base.GetWidth() * 2; - - return base.GetWidth(); + if (stream.IsFeatured) + Width *= 2; } protected override string GetMainText() => Value.DisplayName; diff --git a/osu.Game/Overlays/OverlayUpdateStreamItem.cs b/osu.Game/Overlays/OverlayUpdateStreamItem.cs index ce9aca6f1f..0cdf894f73 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamItem.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamItem.cs @@ -11,16 +11,12 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Allocation; using osu.Game.Graphics.Sprites; using osu.Game.Graphics; -using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays { public abstract class OverlayUpdateStreamItem : TabItem { - private const float transition_duration = 100; - private const float tab_width = 100; - public readonly Bindable SelectedItem = new Bindable(); private bool userHoveringArea; @@ -43,14 +39,14 @@ namespace osu.Game.Overlays protected OverlayUpdateStreamItem(T value) : base(value) { + Height = 60; + Width = 100; + Padding = new MarginPadding(5); } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider, OsuColour colours) { - Size = new Vector2(GetWidth(), 60); - Padding = new MarginPadding(5); - AddRange(new Drawable[] { text = new FillFlowContainer @@ -100,8 +96,6 @@ namespace osu.Game.Overlays protected abstract Color4 GetBarColour(OsuColour colours); - protected virtual float GetWidth() => tab_width; - protected override void OnActivated() => updateState(); protected override void OnDeactivated() => updateState(); @@ -140,7 +134,7 @@ namespace osu.Game.Overlays } expandingBar.Expanded = barExpanded; - text.FadeTo(textHighlighted ? 1 : 0.5f, transition_duration, Easing.OutQuint); + text.FadeTo(textHighlighted ? 1 : 0.5f, 100, Easing.OutQuint); } } } From 6fca3e5a468d09d065a975e5d5eaab567ee6e5f7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 00:39:12 +0300 Subject: [PATCH 24/82] Remove functions with get-only properties --- .../Overlays/Changelog/ChangelogUpdateStreamItem.cs | 6 +++--- .../Overlays/Home/Friends/FriendsOnlineStatusItem.cs | 4 ++-- osu.Game/Overlays/OverlayUpdateStreamItem.cs | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 5a16fc8ddf..84b33fcde9 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -17,11 +17,11 @@ namespace osu.Game.Overlays.Changelog Width *= 2; } - protected override string GetMainText() => Value.DisplayName; + protected override string GetMainText => Value.DisplayName; - protected override string GetAdditionalText() => Value.LatestBuild.DisplayVersion; + protected override string GetAdditionalText => Value.LatestBuild.DisplayVersion; - protected override string GetInfoText() => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null; + protected override string GetInfoText => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null; protected override Color4 GetBarColour(OsuColour colours) => Value.Colour; } diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs index 4043c72bc4..1025fc8146 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs @@ -14,9 +14,9 @@ namespace osu.Game.Overlays.Home.Friends { } - protected override string GetMainText() => Value.Status.ToString(); + protected override string GetMainText => Value.Status.ToString(); - protected override string GetAdditionalText() => Value.Count.ToString(); + protected override string GetAdditionalText => Value.Count.ToString(); protected override Color4 GetBarColour(OsuColour colours) { diff --git a/osu.Game/Overlays/OverlayUpdateStreamItem.cs b/osu.Game/Overlays/OverlayUpdateStreamItem.cs index 0cdf894f73..459daeb3a5 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamItem.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamItem.cs @@ -58,17 +58,17 @@ namespace osu.Game.Overlays { new OsuSpriteText { - Text = GetMainText(), + Text = GetMainText, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), }, new OsuSpriteText { - Text = GetAdditionalText(), + Text = GetAdditionalText, Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), }, new OsuSpriteText { - Text = GetInfoText(), + Text = GetInfoText, Font = OsuFont.GetFont(size: 10), Colour = colourProvider.Foreground1 }, @@ -88,11 +88,11 @@ namespace osu.Game.Overlays SelectedItem.BindValueChanged(_ => updateState(), true); } - protected abstract string GetMainText(); + protected abstract string GetMainText { get; } - protected abstract string GetAdditionalText(); + protected abstract string GetAdditionalText { get; } - protected virtual string GetInfoText() => string.Empty; + protected virtual string GetInfoText => string.Empty; protected abstract Color4 GetBarColour(OsuColour colours); From e2ed13b39248d10f52ffae58f4e51ed594a8951e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 00:40:10 +0300 Subject: [PATCH 25/82] Trim whitespace --- osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 84b33fcde9..79824db572 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Changelog : base(stream) { if (stream.IsFeatured) - Width *= 2; + Width *= 2; } protected override string GetMainText => Value.DisplayName; From a62550b3239791678ab70613ad8ac522101e5788 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Mar 2020 20:14:18 +0900 Subject: [PATCH 26/82] Reapply filters on next change after a forced beatmap display --- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 7 +++++++ osu.Game/Screens/Select/Carousel/CarouselItem.cs | 2 +- osu.Game/Screens/Select/FilterCriteria.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 7 +++++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 2ffb73f226..d78d407748 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -25,6 +25,13 @@ namespace osu.Game.Screens.Select.Carousel { base.Filter(criteria); + if (Beatmap.Equals(criteria.SelectedBeatmap)) + { + // bypass filtering for selected beatmap + Filtered.Value = false; + return; + } + bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 1108b72bd2..79c1a4cb6b 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// This item is not in a hidden state. /// - public bool Visible => State.Value == CarouselItemState.Selected || (State.Value != CarouselItemState.Collapsed && !Filtered.Value); + public bool Visible => State.Value != CarouselItemState.Collapsed && !Filtered.Value; public virtual List Drawables { diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index 9fa57af01d..a5c4e2961d 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -15,6 +15,8 @@ namespace osu.Game.Screens.Select public GroupMode Group; public SortMode Sort; + public BeatmapInfo SelectedBeatmap; + public OptionalRange StarDifficulty; public OptionalRange ApproachRate; public OptionalRange DrainRate; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 67626d1e4f..90ad7a7fdd 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -392,8 +392,11 @@ namespace osu.Game.Screens.Select } // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), - // we still want to forcefully show the new beatmap, bypassing filters. - Carousel.SelectBeatmap(e.NewValue.BeatmapInfo); + // we still want to temporarily show the new beatmap, bypassing filters. + // This will be undone the next time the user changes the filter. + var criteria = FilterControl.CreateCriteria(); + criteria.SelectedBeatmap = e.NewValue.BeatmapInfo; + Carousel.Filter(criteria); } } From f8776a0be4924acfc5673b9683d4ef8fab702390 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Mar 2020 22:59:49 +0900 Subject: [PATCH 27/82] Display all difficulties from overriding selection --- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 2 +- osu.Game/Screens/Select/FilterCriteria.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index d78d407748..c110608a0e 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Select.Carousel { base.Filter(criteria); - if (Beatmap.Equals(criteria.SelectedBeatmap)) + if (Beatmap.BeatmapSet.Equals(criteria.SelectedBeatmapSet)) { // bypass filtering for selected beatmap Filtered.Value = false; diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index a5c4e2961d..18be4fcac8 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Select public GroupMode Group; public SortMode Sort; - public BeatmapInfo SelectedBeatmap; + public BeatmapSetInfo SelectedBeatmapSet; public OptionalRange StarDifficulty; public OptionalRange ApproachRate; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 90ad7a7fdd..6577ed8506 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -395,7 +395,7 @@ namespace osu.Game.Screens.Select // we still want to temporarily show the new beatmap, bypassing filters. // This will be undone the next time the user changes the filter. var criteria = FilterControl.CreateCriteria(); - criteria.SelectedBeatmap = e.NewValue.BeatmapInfo; + criteria.SelectedBeatmapSet = e.NewValue.BeatmapInfo.BeatmapSet; Carousel.Filter(criteria); } } From 9aacc3f5ae1b27cf4564f9f1bf53bd8af0485f27 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 4 Mar 2020 19:24:52 +0100 Subject: [PATCH 28/82] Replace Scores property with DisplayScores method Also adds null checks to prevent crashes in tests. --- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 32 ++++++++++--------- .../BeatmapSet/Scores/ScoresContainer.cs | 5 ++- .../Scores/TopScoreStatisticsSection.cs | 2 +- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index af6bf8299f..4755522b9c 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -52,25 +52,27 @@ namespace osu.Game.Overlays.BeatmapSet.Scores highAccuracyColour = colours.GreenLight; } - public IReadOnlyList Scores + private bool showPerformancePoints; + + public void DisplayScores(IReadOnlyList scores, bool showPerformanceColumn) { - set - { - Content = null; - backgroundFlow.Clear(); + if (!scores.Any()) + return; - if (value?.Any() != true) - return; + showPerformancePoints = showPerformanceColumn; - for (int i = 0; i < value.Count; i++) - backgroundFlow.Add(new ScoreTableRowBackground(i, value[i], row_height)); + for (int i = 0; i < scores.Count; i++) + backgroundFlow.Add(new ScoreTableRowBackground(i, scores[i], row_height)); - Columns = createHeaders(value.First()); - Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); - } + Columns = createHeaders(scores.FirstOrDefault()); + Content = scores.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); } - public bool IsBeatmapRanked { get; set; } + public void ClearScores() + { + Content = null; + backgroundFlow.Clear(); + } private TableColumn[] createHeaders(ScoreInfo score) { @@ -90,7 +92,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95))); - if (IsBeatmapRanked) + if (showPerformancePoints) columns.Add(new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30))); columns.Add(new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize))); @@ -151,7 +153,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } - if (IsBeatmapRanked) + if (showPerformancePoints) { content.Add(new OsuSpriteText { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 5a931fffcb..be1f8c2111 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (value?.Scores.Any() != true) { - scoreTable.Scores = null; + scoreTable.ClearScores(); scoreTable.Hide(); return; } @@ -61,8 +61,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores var scoreInfos = value.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToList(); var topScore = scoreInfos.First(); - scoreTable.Scores = scoreInfos; - scoreTable.IsBeatmapRanked = topScore.Beatmap.Status == BeatmapSetOnlineStatus.Ranked; + scoreTable.DisplayScores(scoreInfos, topScore.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked); scoreTable.Show(); var userScore = value.UserScore; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 9ecc40eed2..a92346e0fe 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -97,7 +97,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores totalScoreColumn.Text = $@"{value.TotalScore:N0}"; accuracyColumn.Text = value.DisplayAccuracy; maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; - ppColumn.Alpha = value.Beatmap.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0; + ppColumn.Alpha = value.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0; ppColumn.Text = $@"{value.PP:N0}"; statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); From 5628c5102dc791fa44c96e5c2480dcc40c726eaf Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 4 Mar 2020 20:01:15 +0100 Subject: [PATCH 29/82] Remove old scores before adding new ones --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 4755522b9c..097ca27bf7 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -56,6 +56,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public void DisplayScores(IReadOnlyList scores, bool showPerformanceColumn) { + ClearScores(); + if (!scores.Any()) return; From 55a0586b13903999e5fd3ec04f8622ed077446c6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 23:03:02 +0300 Subject: [PATCH 30/82] Move exception handling below all the cases --- osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs index 1025fc8146..37652a7ecb 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs @@ -22,9 +22,6 @@ namespace osu.Game.Overlays.Home.Friends { switch (Value.Status) { - default: - throw new ArgumentException($@"{Value.Status} status does not provide a colour in {nameof(GetBarColour)}."); - case FriendsOnlineStatus.All: return Color4.White; @@ -33,6 +30,9 @@ namespace osu.Game.Overlays.Home.Friends case FriendsOnlineStatus.Offline: return Color4.Black; + + default: + throw new ArgumentException($@"{Value.Status} status does not provide a colour in {nameof(GetBarColour)}."); } } } From 63219a2357ebe94d9b96c4a74ac17bdc85e57a42 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 23:06:16 +0300 Subject: [PATCH 31/82] Adjust properties naming --- .../Overlays/Changelog/ChangelogUpdateStreamItem.cs | 6 +++--- .../Overlays/Home/Friends/FriendsOnlineStatusItem.cs | 4 ++-- osu.Game/Overlays/OverlayUpdateStreamItem.cs | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 79824db572..9590aefa49 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -17,11 +17,11 @@ namespace osu.Game.Overlays.Changelog Width *= 2; } - protected override string GetMainText => Value.DisplayName; + protected override string MainText => Value.DisplayName; - protected override string GetAdditionalText => Value.LatestBuild.DisplayVersion; + protected override string AdditionalText => Value.LatestBuild.DisplayVersion; - protected override string GetInfoText => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null; + protected override string InfoText => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null; protected override Color4 GetBarColour(OsuColour colours) => Value.Colour; } diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs index 37652a7ecb..5dd7ca2c18 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs @@ -14,9 +14,9 @@ namespace osu.Game.Overlays.Home.Friends { } - protected override string GetMainText => Value.Status.ToString(); + protected override string MainText => Value.Status.ToString(); - protected override string GetAdditionalText => Value.Count.ToString(); + protected override string AdditionalText => Value.Count.ToString(); protected override Color4 GetBarColour(OsuColour colours) { diff --git a/osu.Game/Overlays/OverlayUpdateStreamItem.cs b/osu.Game/Overlays/OverlayUpdateStreamItem.cs index 459daeb3a5..7bccb8da25 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamItem.cs +++ b/osu.Game/Overlays/OverlayUpdateStreamItem.cs @@ -58,17 +58,17 @@ namespace osu.Game.Overlays { new OsuSpriteText { - Text = GetMainText, + Text = MainText, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), }, new OsuSpriteText { - Text = GetAdditionalText, + Text = AdditionalText, Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), }, new OsuSpriteText { - Text = GetInfoText, + Text = InfoText, Font = OsuFont.GetFont(size: 10), Colour = colourProvider.Foreground1 }, @@ -88,11 +88,11 @@ namespace osu.Game.Overlays SelectedItem.BindValueChanged(_ => updateState(), true); } - protected abstract string GetMainText { get; } + protected abstract string MainText { get; } - protected abstract string GetAdditionalText { get; } + protected abstract string AdditionalText { get; } - protected virtual string GetInfoText => string.Empty; + protected virtual string InfoText => string.Empty; protected abstract Color4 GetBarColour(OsuColour colours); From bd03dd9b707bba167a2ae8697626a3f6da50641a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 4 Mar 2020 23:08:58 +0300 Subject: [PATCH 32/82] Adjust class naming --- .../TestSceneFriendsOnlineStatusControl.cs | 4 ++-- .../Overlays/Changelog/ChangelogUpdateStreamControl.cs | 4 ++-- .../Overlays/Changelog/ChangelogUpdateStreamItem.cs | 2 +- .../Home/Friends/FriendsOnlineStatusControl.cs | 4 ++-- .../Overlays/Home/Friends/FriendsOnlineStatusItem.cs | 2 +- ...yUpdateStreamControl.cs => OverlayStreamControl.cs} | 10 +++++----- ...OverlayUpdateStreamItem.cs => OverlayStreamItem.cs} | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) rename osu.Game/Overlays/{OverlayUpdateStreamControl.cs => OverlayStreamControl.cs} (84%) rename osu.Game/Overlays/{OverlayUpdateStreamItem.cs => OverlayStreamItem.cs} (97%) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs index 45f8a029a8..0d841dfef1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.UserInterface { typeof(FriendsOnlineStatusControl), typeof(FriendsOnlineStatusItem), - typeof(OverlayUpdateStreamControl<>), - typeof(OverlayUpdateStreamItem<>), + typeof(OverlayStreamControl<>), + typeof(OverlayStreamItem<>), typeof(FriendsBundle) }; diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs index 555f0904d6..509a6dabae 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs @@ -5,8 +5,8 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Changelog { - public class ChangelogUpdateStreamControl : OverlayUpdateStreamControl + public class ChangelogUpdateStreamControl : OverlayStreamControl { - protected override OverlayUpdateStreamItem CreateStreamItem(APIUpdateStream value) => new ChangelogUpdateStreamItem(value); + protected override OverlayStreamItem CreateStreamItem(APIUpdateStream value) => new ChangelogUpdateStreamItem(value); } } diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 9590aefa49..f8e1ac0c84 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -8,7 +8,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Changelog { - public class ChangelogUpdateStreamItem : OverlayUpdateStreamItem + public class ChangelogUpdateStreamItem : OverlayStreamItem { public ChangelogUpdateStreamItem(APIUpdateStream stream) : base(stream) diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs index a92de9dbeb..196f01ab4a 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusControl.cs @@ -7,9 +7,9 @@ using osu.Game.Users; namespace osu.Game.Overlays.Home.Friends { - public class FriendsOnlineStatusControl : OverlayUpdateStreamControl + public class FriendsOnlineStatusControl : OverlayStreamControl { - protected override OverlayUpdateStreamItem CreateStreamItem(FriendsBundle value) => new FriendsOnlineStatusItem(value); + protected override OverlayStreamItem CreateStreamItem(FriendsBundle value) => new FriendsOnlineStatusItem(value); public void Populate(List users) { diff --git a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs index 5dd7ca2c18..d9b780ce46 100644 --- a/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Home/Friends/FriendsOnlineStatusItem.cs @@ -7,7 +7,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Home.Friends { - public class FriendsOnlineStatusItem : OverlayUpdateStreamItem + public class FriendsOnlineStatusItem : OverlayStreamItem { public FriendsOnlineStatusItem(FriendsBundle value) : base(value) diff --git a/osu.Game/Overlays/OverlayUpdateStreamControl.cs b/osu.Game/Overlays/OverlayStreamControl.cs similarity index 84% rename from osu.Game/Overlays/OverlayUpdateStreamControl.cs rename to osu.Game/Overlays/OverlayStreamControl.cs index 0fdf6c0111..8b6aca6d5d 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamControl.cs +++ b/osu.Game/Overlays/OverlayStreamControl.cs @@ -10,9 +10,9 @@ using JetBrains.Annotations; namespace osu.Game.Overlays { - public abstract class OverlayUpdateStreamControl : TabControl + public abstract class OverlayStreamControl : TabControl { - protected OverlayUpdateStreamControl() + protected OverlayStreamControl() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -28,7 +28,7 @@ namespace osu.Game.Overlays }); [NotNull] - protected abstract OverlayUpdateStreamItem CreateStreamItem(T value); + protected abstract OverlayStreamItem CreateStreamItem(T value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { @@ -39,7 +39,7 @@ namespace osu.Game.Overlays protected override bool OnHover(HoverEvent e) { - foreach (var streamBadge in TabContainer.Children.OfType>()) + foreach (var streamBadge in TabContainer.Children.OfType>()) streamBadge.UserHoveringArea = true; return base.OnHover(e); @@ -47,7 +47,7 @@ namespace osu.Game.Overlays protected override void OnHoverLost(HoverLostEvent e) { - foreach (var streamBadge in TabContainer.Children.OfType>()) + foreach (var streamBadge in TabContainer.Children.OfType>()) streamBadge.UserHoveringArea = false; base.OnHoverLost(e); diff --git a/osu.Game/Overlays/OverlayUpdateStreamItem.cs b/osu.Game/Overlays/OverlayStreamItem.cs similarity index 97% rename from osu.Game/Overlays/OverlayUpdateStreamItem.cs rename to osu.Game/Overlays/OverlayStreamItem.cs index 7bccb8da25..630d3a0a22 100644 --- a/osu.Game/Overlays/OverlayUpdateStreamItem.cs +++ b/osu.Game/Overlays/OverlayStreamItem.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class OverlayUpdateStreamItem : TabItem + public abstract class OverlayStreamItem : TabItem { public readonly Bindable SelectedItem = new Bindable(); @@ -36,7 +36,7 @@ namespace osu.Game.Overlays private FillFlowContainer text; private ExpandingBar expandingBar; - protected OverlayUpdateStreamItem(T value) + protected OverlayStreamItem(T value) : base(value) { Height = 60; From 371a54364508eb84a37f1e098bded8584e2c1d8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 20:25:38 +0900 Subject: [PATCH 33/82] 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 1c4a6ffe75..97f7a7edb1 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4d59b709aa..855bda3679 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 6897d3e625..e2c4c09047 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - + From 332f56a7f8f62fa426e1f153cb184a7030658961 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 20:34:24 +0900 Subject: [PATCH 34/82] Fix nullref in tests --- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index c110608a0e..8c264ce974 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Select.Carousel { base.Filter(criteria); - if (Beatmap.BeatmapSet.Equals(criteria.SelectedBeatmapSet)) + if (Beatmap.BeatmapSet?.Equals(criteria.SelectedBeatmapSet) == true) { // bypass filtering for selected beatmap Filtered.Value = false; From 0477ef6c130052d0dc95d7fc78e0c2cc2e8a9a30 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Mar 2020 21:45:19 +0900 Subject: [PATCH 35/82] Force a selection after filtering to ensure correct difficulty is selected --- osu.Game/Screens/Select/SongSelect.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6577ed8506..528222a89c 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -397,6 +397,8 @@ namespace osu.Game.Screens.Select var criteria = FilterControl.CreateCriteria(); criteria.SelectedBeatmapSet = e.NewValue.BeatmapInfo.BeatmapSet; Carousel.Filter(criteria); + + Carousel.SelectBeatmap(e.NewValue.BeatmapInfo); } } From ece263131b6c4d89a9580c70f34fdf36837b4c4a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 00:36:05 +0900 Subject: [PATCH 36/82] Update to follow new naming/structure --- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 20 +++++++------------- osu.Game/Tests/Visual/ModTestScene.cs | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index 31d2ce9281..4bc00425bf 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -1,29 +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.Extensions.TypeExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; -using osu.Game.Scoring; namespace osu.Game.Tests.Visual { - public abstract class ModPerfectTestScene : ModSandboxTestScene + public abstract class ModPerfectTestScene : ModTestScene { private readonly Ruleset ruleset; - private readonly ModPerfect perfectMod; + private readonly ModPerfect mod; - protected ModPerfectTestScene(Ruleset ruleset, ModPerfect perfectMod) + protected ModPerfectTestScene(Ruleset ruleset, ModPerfect mod) : base(ruleset) { this.ruleset = ruleset; - this.perfectMod = perfectMod; + this.mod = mod; } - protected void CreateHitObjectTest(HitObjectTestCase testCaseData, bool shouldMiss) => CreateModTest(new ModTestCaseData(testCaseData.HitObject.GetType().ReadableName(), perfectMod) + protected void CreateHitObjectTest(HitObjectTestCase testCaseData, bool shouldMiss) => CreateModTest(new ModTestData { + Mod = mod, Beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo }, @@ -33,15 +32,10 @@ namespace osu.Game.Tests.Visual PassCondition = () => ((PerfectModTestPlayer)Player).CheckFailed(shouldMiss && testCaseData.FailOnMiss) }); - protected sealed override TestPlayer CreateReplayPlayer(Score score) => new PerfectModTestPlayer(score); + protected override TestPlayer CreatePlayer(Ruleset ruleset) => new PerfectModTestPlayer(); private class PerfectModTestPlayer : TestPlayer { - public PerfectModTestPlayer(Score score) - : base(score) - { - } - protected override bool AllowFail => true; public bool CheckFailed(bool failed) diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index 9abe543bf6..eb418304d9 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTestData?.Beatmap ?? base.CreateBeatmap(ruleset); - protected sealed override TestPlayer CreatePlayer(Ruleset ruleset) + protected override TestPlayer CreatePlayer(Ruleset ruleset) { var mods = new List(SelectedMods.Value); From 3ac599246dc816247c7790aec8a95e0fc50aa62b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Mar 2020 16:08:24 +0900 Subject: [PATCH 37/82] Initial pass of seeding screen design update --- .../Screens/TeamIntro/SeedingScreen.cs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index 513d84b594..d48e396b89 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -15,7 +15,6 @@ using osu.Game.Tournament.Components; using osu.Game.Tournament.Models; using osu.Game.Tournament.Screens.Ladder.Components; using osuTK; -using osuTK.Graphics; namespace osu.Game.Tournament.Screens.TeamIntro { @@ -140,9 +139,9 @@ namespace osu.Game.Tournament.Screens.TeamIntro Spacing = new Vector2(5), Children = new Drawable[] { - new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Title, Colour = Color4.Black, }, - new TournamentSpriteText { Text = "by", Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) }, - new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Artist, Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) }, + new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Title, Colour = TournamentGame.TEXT_COLOUR, }, + new TournamentSpriteText { Text = "by", Colour = TournamentGame.TEXT_COLOUR, Font = OsuFont.Torus.With(weight: FontWeight.Regular) }, + new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Artist, Colour = TournamentGame.TEXT_COLOUR, Font = OsuFont.Torus.With(weight: FontWeight.Regular) }, } }, new FillFlowContainer @@ -154,8 +153,8 @@ namespace osu.Game.Tournament.Screens.TeamIntro Spacing = new Vector2(40), Children = new Drawable[] { - new TournamentSpriteText { Text = beatmap.Score.ToString("#,0"), Colour = Color4.Black, Width = 80 }, - new TournamentSpriteText { Text = "#" + beatmap.Seed.Value.ToString("#,0"), Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) }, + new TournamentSpriteText { Text = beatmap.Score.ToString("#,0"), Colour = TournamentGame.TEXT_COLOUR, Width = 80 }, + new TournamentSpriteText { Text = "#" + beatmap.Seed.Value.ToString("#,0"), Colour = TournamentGame.TEXT_COLOUR, Font = OsuFont.Torus.With(weight: FontWeight.Regular) }, } }, }; @@ -204,7 +203,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, + Colour = TournamentGame.TEXT_COLOUR, }, new TournamentSpriteText { @@ -260,20 +259,18 @@ namespace osu.Game.Tournament.Screens.TeamIntro AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - var colour = OsuColour.Gray(0.3f); - InternalChildren = new Drawable[] { new TournamentSpriteText { Text = left, - Colour = colour, - Font = OsuFont.Torus.With(size: 22), + Colour = TournamentGame.TEXT_COLOUR, + Font = OsuFont.Torus.With(size: 22, weight: FontWeight.SemiBold), }, new TournamentSpriteText { Text = right, - Colour = colour, + Colour = TournamentGame.TEXT_COLOUR, Anchor = Anchor.TopRight, Origin = Anchor.TopLeft, Font = OsuFont.Torus.With(size: 22, weight: FontWeight.Regular), @@ -305,7 +302,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro { Text = team?.FullName.Value ?? "???", Font = OsuFont.Torus.With(size: 32, weight: FontWeight.SemiBold), - Colour = Color4.Black, + Colour = TournamentGame.TEXT_COLOUR, }, } }; From cc5cae4db995d6b680022e11b1ba1f272983d3bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 8 Mar 2020 14:08:49 +0100 Subject: [PATCH 38/82] Do not transition to result screen --- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index 4bc00425bf..8b8070caf1 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -36,6 +36,11 @@ namespace osu.Game.Tests.Visual private class PerfectModTestPlayer : TestPlayer { + public PerfectModTestPlayer() + : base(showResults: false) + { + } + protected override bool AllowFail => true; public bool CheckFailed(bool failed) From c803de2b499a44a8dde5eba44961ddcea684fb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 8 Mar 2020 14:18:45 +0100 Subject: [PATCH 39/82] Fix player instantiation Since ModTestScene.CreatePlayer would apply mods in addition to instantiating the player, overriding it could lead to mistakenly also overriding the code that was supposed to set up the test via currentTestData. Make ModTestScene.CreatePlayer sealed, which ensures that mod & autoplay changes are applied, and expose ModTestScene.CreateModPlayer instead which has the expected semantics. --- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 2 +- osu.Game/Tests/Visual/ModTestScene.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index 8b8070caf1..d6255d2478 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual PassCondition = () => ((PerfectModTestPlayer)Player).CheckFailed(shouldMiss && testCaseData.FailOnMiss) }); - protected override TestPlayer CreatePlayer(Ruleset ruleset) => new PerfectModTestPlayer(); + protected override TestPlayer CreateModPlayer(Ruleset ruleset) => new PerfectModTestPlayer(); private class PerfectModTestPlayer : TestPlayer { diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index eb418304d9..8b41fb5075 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTestData?.Beatmap ?? base.CreateBeatmap(ruleset); - protected override TestPlayer CreatePlayer(Ruleset ruleset) + protected sealed override TestPlayer CreatePlayer(Ruleset ruleset) { var mods = new List(SelectedMods.Value); @@ -57,9 +57,11 @@ namespace osu.Game.Tests.Visual SelectedMods.Value = mods; - return new ModTestPlayer(AllowFail); + return CreateModPlayer(ruleset); } + protected virtual TestPlayer CreateModPlayer(Ruleset ruleset) => new ModTestPlayer(AllowFail); + protected class ModTestPlayer : TestPlayer { protected override bool AllowFail { get; } From e6858bf1304f0a96e1f3ead46640b0b83fc72d4e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Mar 2020 11:58:33 +0900 Subject: [PATCH 40/82] Fix crashes on some storyboards --- .../Formats/LegacyStoryboardDecoder.cs | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 6569f76b2d..c81f933bca 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using osuTK; using osuTK.Graphics; @@ -93,8 +92,8 @@ namespace osu.Game.Beatmaps.Formats var layer = parseLayer(split[1]); var origin = parseOrigin(split[2]); var path = CleanFilename(split[3]); - var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); - var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); + var x = Parsing.ParseFloat(split[4], Parsing.MAX_COORDINATE_VALUE); + var y = Parsing.ParseFloat(split[5], Parsing.MAX_COORDINATE_VALUE); storyboardSprite = new StoryboardSprite(path, origin, new Vector2(x, y)); storyboard.GetLayer(layer).Add(storyboardSprite); break; @@ -105,10 +104,10 @@ namespace osu.Game.Beatmaps.Formats var layer = parseLayer(split[1]); var origin = parseOrigin(split[2]); var path = CleanFilename(split[3]); - var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); - var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); - var frameCount = int.Parse(split[6]); - var frameDelay = double.Parse(split[7], NumberFormatInfo.InvariantInfo); + var x = Parsing.ParseFloat(split[4], Parsing.MAX_COORDINATE_VALUE); + var y = Parsing.ParseFloat(split[5], Parsing.MAX_COORDINATE_VALUE); + var frameCount = Parsing.ParseInt(split[6]); + var frameDelay = Parsing.ParseDouble(split[7]); var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever; storyboardSprite = new StoryboardAnimation(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType); storyboard.GetLayer(layer).Add(storyboardSprite); @@ -117,10 +116,10 @@ namespace osu.Game.Beatmaps.Formats case LegacyEventType.Sample: { - var time = double.Parse(split[1], CultureInfo.InvariantCulture); + var time = Parsing.ParseDouble(split[1]); var layer = parseLayer(split[2]); var path = CleanFilename(split[3]); - var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100; + var volume = split.Length > 4 ? Parsing.ParseFloat(split[4]) : 100; storyboard.GetLayer(layer).Add(new StoryboardSampleInfo(path, time, (int)volume)); break; } @@ -138,17 +137,17 @@ namespace osu.Game.Beatmaps.Formats case "T": { var triggerName = split[1]; - var startTime = split.Length > 2 ? double.Parse(split[2], CultureInfo.InvariantCulture) : double.MinValue; - var endTime = split.Length > 3 ? double.Parse(split[3], CultureInfo.InvariantCulture) : double.MaxValue; - var groupNumber = split.Length > 4 ? int.Parse(split[4]) : 0; + var startTime = split.Length > 2 ? Parsing.ParseDouble(split[2]) : double.MinValue; + var endTime = split.Length > 3 ? Parsing.ParseDouble(split[3]) : double.MaxValue; + var groupNumber = split.Length > 4 ? Parsing.ParseInt(split[4]) : 0; timelineGroup = storyboardSprite?.AddTrigger(triggerName, startTime, endTime, groupNumber); break; } case "L": { - var startTime = double.Parse(split[1], CultureInfo.InvariantCulture); - var loopCount = int.Parse(split[2]); + var startTime = Parsing.ParseDouble(split[1]); + var loopCount = Parsing.ParseInt(split[2]); timelineGroup = storyboardSprite?.AddLoop(startTime, loopCount); break; } @@ -158,52 +157,52 @@ namespace osu.Game.Beatmaps.Formats if (string.IsNullOrEmpty(split[3])) split[3] = split[2]; - var easing = (Easing)int.Parse(split[1]); - var startTime = double.Parse(split[2], CultureInfo.InvariantCulture); - var endTime = double.Parse(split[3], CultureInfo.InvariantCulture); + var easing = (Easing)Parsing.ParseInt(split[1]); + var startTime = Parsing.ParseDouble(split[2]); + var endTime = Parsing.ParseDouble(split[3]); switch (commandType) { case "F": { - var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); - var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + var startValue = Parsing.ParseFloat(split[4]); + var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue; timelineGroup?.Alpha.Add(easing, startTime, endTime, startValue, endValue); break; } case "S": { - var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); - var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + var startValue = Parsing.ParseFloat(split[4]); + var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue; timelineGroup?.Scale.Add(easing, startTime, endTime, startValue, endValue); break; } case "V": { - var startX = float.Parse(split[4], CultureInfo.InvariantCulture); - var startY = float.Parse(split[5], CultureInfo.InvariantCulture); - var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX; - var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY; + var startX = Parsing.ParseFloat(split[4]); + var startY = Parsing.ParseFloat(split[5]); + var endX = split.Length > 6 ? Parsing.ParseFloat(split[6]) : startX; + var endY = split.Length > 7 ? Parsing.ParseFloat(split[7]) : startY; timelineGroup?.VectorScale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(endX, endY)); break; } case "R": { - var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); - var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + var startValue = Parsing.ParseFloat(split[4]); + var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue; timelineGroup?.Rotation.Add(easing, startTime, endTime, MathUtils.RadiansToDegrees(startValue), MathUtils.RadiansToDegrees(endValue)); break; } case "M": { - var startX = float.Parse(split[4], CultureInfo.InvariantCulture); - var startY = float.Parse(split[5], CultureInfo.InvariantCulture); - var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX; - var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY; + var startX = Parsing.ParseFloat(split[4]); + var startY = Parsing.ParseFloat(split[5]); + var endX = split.Length > 6 ? Parsing.ParseFloat(split[6]) : startX; + var endY = split.Length > 7 ? Parsing.ParseFloat(split[7]) : startY; timelineGroup?.X.Add(easing, startTime, endTime, startX, endX); timelineGroup?.Y.Add(easing, startTime, endTime, startY, endY); break; @@ -211,28 +210,28 @@ namespace osu.Game.Beatmaps.Formats case "MX": { - var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); - var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + var startValue = Parsing.ParseFloat(split[4]); + var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue; timelineGroup?.X.Add(easing, startTime, endTime, startValue, endValue); break; } case "MY": { - var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); - var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + var startValue = Parsing.ParseFloat(split[4]); + var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue; timelineGroup?.Y.Add(easing, startTime, endTime, startValue, endValue); break; } case "C": { - var startRed = float.Parse(split[4], CultureInfo.InvariantCulture); - var startGreen = float.Parse(split[5], CultureInfo.InvariantCulture); - var startBlue = float.Parse(split[6], CultureInfo.InvariantCulture); - var endRed = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startRed; - var endGreen = split.Length > 8 ? float.Parse(split[8], CultureInfo.InvariantCulture) : startGreen; - var endBlue = split.Length > 9 ? float.Parse(split[9], CultureInfo.InvariantCulture) : startBlue; + var startRed = Parsing.ParseFloat(split[4]); + var startGreen = Parsing.ParseFloat(split[5]); + var startBlue = Parsing.ParseFloat(split[6]); + var endRed = split.Length > 7 ? Parsing.ParseFloat(split[7]) : startRed; + var endGreen = split.Length > 8 ? Parsing.ParseFloat(split[8]) : startGreen; + var endBlue = split.Length > 9 ? Parsing.ParseFloat(split[9]) : startBlue; timelineGroup?.Colour.Add(easing, startTime, endTime, new Color4(startRed / 255f, startGreen / 255f, startBlue / 255f, 1), new Color4(endRed / 255f, endGreen / 255f, endBlue / 255f, 1)); From 7a9c85d69da0a826ac03fd78fb615e146a0eef96 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Mar 2020 12:21:40 +0900 Subject: [PATCH 41/82] Fix now failing test due to parsing ranges --- osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs | 2 +- osu.Game.Tests/Resources/variable-with-suffix.osb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 96ff6b81e3..76b76aa357 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -99,7 +99,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var storyboard = decoder.Decode(stream); StoryboardLayer background = storyboard.Layers.Single(l => l.Depth == 3); - Assert.AreEqual(123456, ((StoryboardSprite)background.Elements.Single()).InitialPosition.X); + Assert.AreEqual(3456, ((StoryboardSprite)background.Elements.Single()).InitialPosition.X); } } } diff --git a/osu.Game.Tests/Resources/variable-with-suffix.osb b/osu.Game.Tests/Resources/variable-with-suffix.osb index 5c9b46ca98..fd284eb055 100644 --- a/osu.Game.Tests/Resources/variable-with-suffix.osb +++ b/osu.Game.Tests/Resources/variable-with-suffix.osb @@ -1,5 +1,5 @@ [Variables] -$var=1234 +$var=34 [Events] Sprite,Background,TopCentre,"img.jpg",$var56,240 From 9d5327b1accc07234637f51f7903cacb2b9966ea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Mar 2020 15:00:23 +0900 Subject: [PATCH 42/82] Fix osu! shaking instead of missing for early hits --- .../TestSceneEarlyMissJudgement.cs | 70 +++++++++++++++++++ .../Scoring/OsuHitWindows.cs | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs new file mode 100644 index 0000000000..27a32aa96e --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs @@ -0,0 +1,70 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Replays; +using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Tests.Visual; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Tests +{ + public class TestSceneEarlyMissJudgement : ModTestScene + { + public TestSceneEarlyMissJudgement() + : base(new OsuRuleset()) + { + } + + [Test] + public void TestHitCircleEarly() => CreateModTest(new ModTestData + { + Autoplay = false, + Mod = new TestAutoMod(), + Beatmap = new Beatmap + { + HitObjects = { new HitCircle { Position = new Vector2(256, 192) } } + }, + PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset < 0 && Player.Results[0].Type == HitResult.Miss + }); + + private class TestAutoMod : OsuModAutoplay + { + public override Score CreateReplayScore(IBeatmap beatmap) => new Score + { + ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } }, + Replay = new MissingAutoGenerator(beatmap).Generate() + }; + } + + private class MissingAutoGenerator : OsuAutoGeneratorBase + { + public new OsuBeatmap Beatmap => (OsuBeatmap)base.Beatmap; + + public MissingAutoGenerator(IBeatmap beatmap) + : base(beatmap) + { + } + + public override Replay Generate() + { + AddFrameToReplay(new OsuReplayFrame(-100000, new Vector2(256, 500))); + AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 1500, new Vector2(256, 500))); + AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 1500, new Vector2(256, 500))); + + AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 450, Beatmap.HitObjects[0].StackedPosition)); + AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 350, Beatmap.HitObjects[0].StackedPosition, OsuAction.LeftButton)); + AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 325, Beatmap.HitObjects[0].StackedPosition)); + + return Replay; + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuHitWindows.cs b/osu.Game.Rulesets.Osu/Scoring/OsuHitWindows.cs index a6491bb3f3..6f2998006f 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuHitWindows.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuHitWindows.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Scoring new DifficultyRange(HitResult.Great, 80, 50, 20), new DifficultyRange(HitResult.Good, 140, 100, 60), new DifficultyRange(HitResult.Meh, 200, 150, 100), - new DifficultyRange(HitResult.Miss, 200, 200, 200), + new DifficultyRange(HitResult.Miss, 400, 400, 400), }; public override bool IsHitResultAllowed(HitResult result) From 678f33eea36615c5a2ac2463ff13fc3c6f50a704 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Mar 2020 15:45:21 +0900 Subject: [PATCH 43/82] Add late miss judgements --- ...cs => TestSceneMissHitWindowJudgements.cs} | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) rename osu.Game.Rulesets.Osu.Tests/{TestSceneEarlyMissJudgement.cs => TestSceneMissHitWindowJudgements.cs} (58%) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs similarity index 58% rename from osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs rename to osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs index 27a32aa96e..5f3596976d 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneEarlyMissJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Tests.Visual; @@ -16,24 +17,54 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneEarlyMissJudgement : ModTestScene + public class TestSceneMissHitWindowJudgements : ModTestScene { - public TestSceneEarlyMissJudgement() + public TestSceneMissHitWindowJudgements() : base(new OsuRuleset()) { } [Test] - public void TestHitCircleEarly() => CreateModTest(new ModTestData + public void TestMissViaEarlyHit() { - Autoplay = false, - Mod = new TestAutoMod(), - Beatmap = new Beatmap + var beatmap = new Beatmap { HitObjects = { new HitCircle { Position = new Vector2(256, 192) } } - }, - PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset < 0 && Player.Results[0].Type == HitResult.Miss - }); + }; + + var hitWindows = new OsuHitWindows(); + hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); + + CreateModTest(new ModTestData + { + Autoplay = false, + Mod = new TestAutoMod(), + Beatmap = new Beatmap + { + HitObjects = { new HitCircle { Position = new Vector2(256, 192) } } + }, + PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset < -hitWindows.WindowFor(HitResult.Meh) && Player.Results[0].Type == HitResult.Miss + }); + } + + [Test] + public void TestMissViaNotHitting() + { + var beatmap = new Beatmap + { + HitObjects = { new HitCircle { Position = new Vector2(256, 192) } } + }; + + var hitWindows = new OsuHitWindows(); + hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); + + CreateModTest(new ModTestData + { + Autoplay = false, + Beatmap = beatmap, + PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset >= hitWindows.WindowFor(HitResult.Meh) && Player.Results[0].Type == HitResult.Miss + }); + } private class TestAutoMod : OsuModAutoplay { From 2b33594400dae72c9dc05d428f927353b53fe407 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 15:59:13 +0900 Subject: [PATCH 44/82] Add random rotation and scale factors to osu!catch bananas --- .../TestSceneBananaShower.cs | 2 ++ .../Objects/Drawables/DrawableBanana.cs | 17 +++++++++++++++++ osu.Game/Tests/Visual/ScreenTestScene.cs | 5 ++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs index 20911b8d06..024c4cefb0 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs @@ -18,7 +18,9 @@ namespace osu.Game.Rulesets.Catch.Tests public override IReadOnlyList RequiredTypes => new[] { typeof(BananaShower), + typeof(Banana), typeof(DrawableBananaShower), + typeof(DrawableBanana), typeof(CatchRuleset), typeof(DrawableCatchRuleset), diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index cf7231ebb2..2e7618b8df 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Framework.Utils; using osuTK.Graphics; @@ -22,6 +23,22 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables return colour ??= getBananaColour(); } + protected override void UpdateInitialTransforms() + { + base.UpdateInitialTransforms(); + + const float end_scale = 0.6f; + const float random_scale_range = 1.6f; + + ScaleContainer.ScaleTo(HitObject.Scale * (end_scale + random_scale_range * RNG.NextSingle())) + .Then().ScaleTo(HitObject.Scale * end_scale, HitObject.TimePreempt); + + const float random_angle_range = 180; + + ScaleContainer.RotateTo(random_angle_range * (RNG.NextSingle() * 2 - 1)) + .Then().RotateTo(random_angle_range * (RNG.NextSingle() * 2 - 1), HitObject.TimePreempt); + } + private Color4 getBananaColour() { switch (RNG.Next(0, 3)) diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs index d26aacf2bc..1a6ebed425 100644 --- a/osu.Game/Tests/Visual/ScreenTestScene.cs +++ b/osu.Game/Tests/Visual/ScreenTestScene.cs @@ -38,12 +38,11 @@ namespace osu.Game.Tests.Visual private void addExitAllScreensStep() { - AddUntilStep("exit all screens", () => + AddStep("exit all screens", () => { - if (Stack.CurrentScreen == null) return true; + if (Stack.CurrentScreen == null) return; Stack.Exit(); - return false; }); } } From eab544b49f47d2543ff25d80a281a3531f636f4e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 16:41:08 +0900 Subject: [PATCH 45/82] Add afterimage glow when entering hyperdash --- .../TestSceneCatcherArea.cs | 5 ---- .../TestSceneHyperDash.cs | 6 ++++ osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 30 ++++++++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index df1ac4c725..0eea352603 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -22,11 +22,6 @@ namespace osu.Game.Rulesets.Catch.Tests { private RulesetInfo catchRuleset; - public override IReadOnlyList RequiredTypes => new[] - { - typeof(CatcherArea), - }; - public TestSceneCatcherArea() { AddSliderStep("CircleSize", 0, 8, 5, createCatcher); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 7a7c3f4103..30df2202f5 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Testing; @@ -15,6 +16,11 @@ namespace osu.Game.Rulesets.Catch.Tests [TestFixture] public class TestSceneHyperDash : PlayerTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CatcherArea), + }; + public TestSceneHyperDash() : base(new CatchRuleset()) { diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index dfeaf6e89f..cc0f41a14f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -205,21 +205,28 @@ namespace osu.Game.Rulesets.Catch.UI if (!Trail) return; + var additive = createAdditiveSprite(HyperDashing); + + additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint); + additive.Expire(true); + + Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50); + } + + private Drawable createAdditiveSprite(bool hyperDash) + { var additive = createCatcherSprite(); additive.Anchor = Anchor; additive.Scale = Scale; - additive.Colour = HyperDashing ? Color4.Red : Color4.White; + additive.Colour = hyperDash ? Color4.Red : Color4.White; additive.Blending = BlendingParameters.Additive; additive.RelativePositionAxes = RelativePositionAxes; additive.Position = Position; AdditiveTarget.Add(additive); - additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint); - additive.Expire(true); - - Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50); + return additive; } private Drawable createCatcherSprite() => new CatcherSprite(); @@ -311,14 +318,14 @@ namespace osu.Game.Rulesets.Catch.UI { const float hyper_dash_transition_length = 180; - bool previouslyHyperDashing = HyperDashing; + bool wasHyperDashing = HyperDashing; if (modifier <= 1 || X == targetPosition) { hyperDashModifier = 1; hyperDashDirection = 0; - if (previouslyHyperDashing) + if (wasHyperDashing) { this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint); this.FadeTo(1, hyper_dash_transition_length, Easing.OutQuint); @@ -331,11 +338,18 @@ namespace osu.Game.Rulesets.Catch.UI hyperDashDirection = Math.Sign(targetPosition - X); hyperDashTargetPosition = targetPosition; - if (!previouslyHyperDashing) + if (!wasHyperDashing) { this.FadeColour(Color4.OrangeRed, hyper_dash_transition_length, Easing.OutQuint); this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint); Trail = true; + + var hyperDashEndGlow = createAdditiveSprite(true); + + hyperDashEndGlow.MoveToOffset(new Vector2(0, -20), 1200, Easing.In); + hyperDashEndGlow.ScaleTo(hyperDashEndGlow.Scale * 0.9f).ScaleTo(hyperDashEndGlow.Scale * 1.2f, 1200, Easing.In); + hyperDashEndGlow.FadeOut(1200); + hyperDashEndGlow.Expire(true); } } } From 8ad44952f8da454f5d8d77172b6615099f86ebe0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 16:47:53 +0900 Subject: [PATCH 46/82] Remove unused usings --- osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index 0eea352603..cf4843c200 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.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. -using System; -using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; From 5329b222f6de157989225761aeaf5dd89c60d72f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 17:49:51 +0900 Subject: [PATCH 47/82] Fix hyperdash test having a zero-length juice stream --- .../TestSceneHyperDash.cs | 45 ++++++++++++------- .../Objects/JuiceStream.cs | 4 +- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 7a7c3f4103..5b3a114506 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -8,7 +8,9 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects; using osu.Game.Tests.Visual; +using osuTK; namespace osu.Game.Rulesets.Catch.Tests { @@ -26,9 +28,11 @@ namespace osu.Game.Rulesets.Catch.Tests public void TestHyperDash() { AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); - AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing); + AddUntilStep("wait for right movement", () => getCatcher().Scale.X > 0); // don't check hyperdashing as it happens too fast. - for (int i = 0; i < 2; i++) + AddUntilStep("wait for left movement", () => getCatcher().Scale.X < 0); + + for (int i = 0; i < 3; i++) { AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing); AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing); @@ -49,39 +53,50 @@ namespace osu.Game.Rulesets.Catch.Tests }; // Should produce a hyper-dash (edge case test) - beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 308 / 512f, NewCombo = true }); - beatmap.HitObjects.Add(new JuiceStream { StartTime = 2008, X = 56 / 512f, }); + beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56 / 512f, NewCombo = true }); + beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308 / 512f, NewCombo = true }); double startTime = 3000; const float left_x = 0.02f; const float right_x = 0.98f; - createObjects(() => new Fruit(), left_x); - createObjects(() => new JuiceStream(), right_x); - createObjects(() => new JuiceStream(), left_x); - createObjects(() => new Fruit(), right_x); - createObjects(() => new Fruit(), left_x); - createObjects(() => new Fruit(), right_x); - createObjects(() => new JuiceStream(), left_x); + createObjects(() => new Fruit { X = left_x }); + createObjects(() => new TestJuiceStream(right_x), 1); + createObjects(() => new TestJuiceStream(left_x), 1); + createObjects(() => new Fruit { X = right_x }); + createObjects(() => new Fruit { X = left_x }); + createObjects(() => new Fruit { X = right_x }); + createObjects(() => new TestJuiceStream(left_x), 1); return beatmap; - void createObjects(Func createObject, float x) + void createObjects(Func createObject, int count = 3) { const float spacing = 140; - for (int i = 0; i < 3; i++) + for (int i = 0; i < count; i++) { var hitObject = createObject(); - hitObject.X = x; hitObject.StartTime = startTime + i * spacing; - beatmap.HitObjects.Add(hitObject); } startTime += 700; } } + + private class TestJuiceStream : JuiceStream + { + public TestJuiceStream(float x) + { + X = x; + Path = new SliderPath(new[] + { + new PathControlPoint(new Vector2(x, 0)), + new PathControlPoint(new Vector2(x + 30, 0)), + }); + } + } } } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 642ff0246e..bcc2d9d9bb 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Catch.Objects public int RepeatCount { get; set; } - public double Velocity; - public double TickDistance; + public double Velocity { get; private set; } + public double TickDistance { get; private set; } /// /// The length of one span of this . From 14192c069f8a694dd7fd7b28a6d6785af44ceb6b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 18:05:44 +0900 Subject: [PATCH 48/82] Don't play samples on catching a tiny droplet --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 642ff0246e..1e4d8e15db 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Objects { base.CreateNestedHitObjects(); - var tickSamples = Samples.Select(s => new HitSampleInfo + var dropletSamples = Samples.Select(s => new HitSampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -75,7 +75,6 @@ namespace osu.Game.Rulesets.Catch.Objects { AddNested(new TinyDroplet { - Samples = tickSamples, StartTime = t + lastEvent.Value.Time, X = X + Path.PositionAt( lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X / CatchPlayfield.BASE_WIDTH, @@ -93,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Objects case SliderEventType.Tick: AddNested(new Droplet { - Samples = tickSamples, + Samples = dropletSamples, StartTime = e.Time, X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH, }); From 4daba48a1df153bd543d9251a9060aa163cbcd36 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 19:30:31 +0900 Subject: [PATCH 49/82] Stop rotating DrawableCatchHitObjects at the top level --- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs | 2 +- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index 0a8e830af9..cad8892283 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables float startRotation = RNG.NextSingle() * 20; double duration = HitObject.TimePreempt + 2000; - this.RotateTo(startRotation).RotateTo(startRotation + 720, duration); + ScaleContainer.RotateTo(startRotation).RotateTo(startRotation + 720, duration); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index 197ad41247..fae5a10d04 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -13,7 +13,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public DrawableFruit(Fruit h) : base(h) { - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } [BackgroundDependencyLoader] @@ -21,6 +20,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { ScaleContainer.Child = new SkinnableDrawable( new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece()); + + ScaleContainer.Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } private CatchSkinComponents getComponent(FruitVisualRepresentation hitObjectVisualRepresentation) From 9ad519e5a5dd1207f4f6cca8b3cfbae6bb9906fe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 19:35:08 +0900 Subject: [PATCH 50/82] Remove fade and custom InitialLifetimeOffset --- .../Objects/Drawables/DrawableCatchHitObject.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index 5bfe0515a1..6844be5941 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -91,10 +91,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables ApplyResult(r => r.Type = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss); } - protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt; - - protected override void UpdateInitialTransforms() => this.FadeInFromZero(200); - protected override void UpdateStateTransforms(ArmedState state) { var endTime = HitObject.GetEndTime(); From 8ec2c35c4f6833a745eecc5ee98fb7c1eca7e422 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 19:34:52 +0900 Subject: [PATCH 51/82] Change origin of nested objects inside JuiceStream to fix visibility issues --- .../Objects/Drawables/DrawableJuiceStream.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs index 932464cfd1..7bc016d94f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osuTK; namespace osu.Game.Rulesets.Catch.Objects.Drawables { @@ -14,11 +15,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private readonly Func> createDrawableRepresentation; private readonly Container dropletContainer; + public override Vector2 OriginPosition => base.OriginPosition - new Vector2(0, CatchHitObject.OBJECT_RADIUS); + public DrawableJuiceStream(JuiceStream s, Func> createDrawableRepresentation = null) : base(s) { this.createDrawableRepresentation = createDrawableRepresentation; - RelativeSizeAxes = Axes.Both; + RelativeSizeAxes = Axes.X; Origin = Anchor.BottomLeft; X = 0; @@ -27,6 +30,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables protected override void AddNestedHitObject(DrawableHitObject hitObject) { + hitObject.Origin = Anchor.BottomCentre; + base.AddNestedHitObject(hitObject); dropletContainer.Add(hitObject); } From 8294dd0b717a2f6f0071eee12078d899eca10dc5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 19:59:49 +0900 Subject: [PATCH 52/82] Fix changing ruleset at song selectnot scrolling the current selection back into view --- osu.Game/Screens/Select/BeatmapCarousel.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 1db97af2f0..71744d8b80 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -189,7 +189,7 @@ namespace osu.Game.Screens.Select root.AddChild(newSet); - applyActiveCriteria(false, false); + applyActiveCriteria(false); //check if we can/need to maintain our current selection. if (previouslySelectedID != null) @@ -239,7 +239,7 @@ namespace osu.Game.Screens.Select { Debug.Assert(bypassFilters); - applyActiveCriteria(false, true); + applyActiveCriteria(false); } return true; @@ -396,7 +396,7 @@ namespace osu.Game.Screens.Select { if (PendingFilter?.Completed == false) { - applyActiveCriteria(false, false); + applyActiveCriteria(false); Update(); } } @@ -406,10 +406,10 @@ namespace osu.Game.Screens.Select if (newCriteria != null) activeCriteria = newCriteria; - applyActiveCriteria(debounce, true); + applyActiveCriteria(debounce); } - private void applyActiveCriteria(bool debounce, bool scroll) + private void applyActiveCriteria(bool debounce) { if (root.Children.Any() != true) return; @@ -419,7 +419,7 @@ namespace osu.Game.Screens.Select root.Filter(activeCriteria); itemsCache.Invalidate(); - if (scroll) scrollPositionCache.Invalidate(); + scrollPositionCache.Invalidate(); } PendingFilter?.Cancel(); From ad7cda87357d32be258e39104a5350ee9f6798a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Mar 2020 20:11:06 +0900 Subject: [PATCH 53/82] Fix download failures causing a non-safe drawable change --- osu.Game/Database/IModelDownloader.cs | 2 ++ osu.Game/Online/DownloadTrackingComposite.cs | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs index 17f1ccab06..99aeb4eacf 100644 --- a/osu.Game/Database/IModelDownloader.cs +++ b/osu.Game/Database/IModelDownloader.cs @@ -15,11 +15,13 @@ namespace osu.Game.Database { /// /// Fired when a download begins. + /// This is NOT run on the update thread and should be scheduled. /// event Action> DownloadBegan; /// /// Fired when a download is interrupted, either due to user cancellation or failure. + /// This is NOT run on the update thread and should be scheduled. /// event Action> DownloadFailed; diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 6e7ef99c6d..0769be2998 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -53,17 +53,17 @@ namespace osu.Game.Online manager.ItemRemoved += itemRemoved; } - private void downloadBegan(ArchiveDownloadRequest request) + private void downloadBegan(ArchiveDownloadRequest request) => Schedule(() => { if (request.Model.Equals(Model.Value)) attachDownload(request); - } + }); - private void downloadFailed(ArchiveDownloadRequest request) + private void downloadFailed(ArchiveDownloadRequest request) => Schedule(() => { if (request.Model.Equals(Model.Value)) attachDownload(null); - } + }); private ArchiveDownloadRequest attachedRequest; From 0be423183daad7a77e186e5834bffdb623c4d08d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 00:36:56 +0900 Subject: [PATCH 54/82] Rename data class --- .../Mods/TestSceneCatchModPerfect.cs | 10 +++++----- .../Mods/TestSceneManiaModPerfect.cs | 4 ++-- .../Mods/TestSceneOsuModPerfect.cs | 6 +++--- .../Mods/TestSceneTaikoModPerfect.cs | 6 +++--- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 10 +++++----- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs index 56d2fe1ee0..47e91e50d4 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs @@ -20,11 +20,11 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods [TestCase(false)] [TestCase(true)] - public void TestBananaShower(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new BananaShower { StartTime = 1000, EndTime = 3000 }, false), shouldMiss); + public void TestBananaShower(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new BananaShower { StartTime = 1000, EndTime = 3000 }, false), shouldMiss); [TestCase(false)] [TestCase(true)] - public void TestFruit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Fruit { StartTime = 1000 }), shouldMiss); + public void TestFruit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Fruit { StartTime = 1000 }), shouldMiss); [TestCase(false)] [TestCase(true)] @@ -40,15 +40,15 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods }) }; - CreateHitObjectTest(new HitObjectTestCase(stream), shouldMiss); + CreateHitObjectTest(new HitObjectTestData(stream), shouldMiss); } // We only care about testing misses, hits are tested via JuiceStream [TestCase(true)] - public void TestDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Droplet { StartTime = 1000 }), shouldMiss); + public void TestDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Droplet { StartTime = 1000 }), shouldMiss); // We only care about testing misses, hits are tested via JuiceStream [TestCase(true)] - public void TestTinyDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new TinyDroplet { StartTime = 1000 }), shouldMiss); + public void TestTinyDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new TinyDroplet { StartTime = 1000 }), shouldMiss); } } diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs index 4e11a302c9..607d42a1bb 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs @@ -17,10 +17,10 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods [TestCase(false)] [TestCase(true)] - public void TestNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Note { StartTime = 1000 }), shouldMiss); + public void TestNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Note { StartTime = 1000 }), shouldMiss); [TestCase(false)] [TestCase(true)] - public void TestHoldNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new HoldNote { StartTime = 1000, EndTime = 3000 }), shouldMiss); + public void TestHoldNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new HoldNote { StartTime = 1000, EndTime = 3000 }), shouldMiss); } } diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs index fc2dfa16ec..b03a894085 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods [TestCase(false)] [TestCase(true)] - public void TestHitCircle(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new HitCircle { StartTime = 1000 }), shouldMiss); + public void TestHitCircle(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new HitCircle { StartTime = 1000 }), shouldMiss); [TestCase(false)] [TestCase(true)] @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), }) }; - CreateHitObjectTest(new HitObjectTestCase(slider), shouldMiss); + CreateHitObjectTest(new HitObjectTestData(slider), shouldMiss); } [TestCase(false)] @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods Position = new Vector2(256, 192) }; - CreateHitObjectTest(new HitObjectTestCase(spinner), shouldMiss); + CreateHitObjectTest(new HitObjectTestData(spinner), shouldMiss); } } } diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs index fd9d01a3db..d3be2cdf0d 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs @@ -19,15 +19,15 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods [TestCase(false)] [TestCase(true)] - public void TestHit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new CentreHit { StartTime = 1000 }), shouldMiss); + public void TestHit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new CentreHit { StartTime = 1000 }), shouldMiss); [TestCase(false)] [TestCase(true)] - public void TestDrumRoll(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new DrumRoll { StartTime = 1000, EndTime = 3000 }), shouldMiss); + public void TestDrumRoll(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new DrumRoll { StartTime = 1000, EndTime = 3000 }), shouldMiss); [TestCase(false)] [TestCase(true)] - public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestCase(new Swell { StartTime = 1000, EndTime = 3000 }), shouldMiss); + public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Swell { StartTime = 1000, EndTime = 3000 }), shouldMiss); private class TestTaikoRuleset : TaikoRuleset { diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index d6255d2478..798947eb40 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -20,16 +20,16 @@ namespace osu.Game.Tests.Visual this.mod = mod; } - protected void CreateHitObjectTest(HitObjectTestCase testCaseData, bool shouldMiss) => CreateModTest(new ModTestData + protected void CreateHitObjectTest(HitObjectTestData testData, bool shouldMiss) => CreateModTest(new ModTestData { Mod = mod, Beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo }, - HitObjects = { testCaseData.HitObject } + HitObjects = { testData.HitObject } }, Autoplay = !shouldMiss, - PassCondition = () => ((PerfectModTestPlayer)Player).CheckFailed(shouldMiss && testCaseData.FailOnMiss) + PassCondition = () => ((PerfectModTestPlayer)Player).CheckFailed(shouldMiss && testData.FailOnMiss) }); protected override TestPlayer CreateModPlayer(Ruleset ruleset) => new PerfectModTestPlayer(); @@ -52,12 +52,12 @@ namespace osu.Game.Tests.Visual } } - protected class HitObjectTestCase + protected class HitObjectTestData { public readonly HitObject HitObject; public readonly bool FailOnMiss; - public HitObjectTestCase(HitObject hitObject, bool failOnMiss = true) + public HitObjectTestData(HitObject hitObject, bool failOnMiss = true) { HitObject = hitObject; FailOnMiss = failOnMiss; From 998ca05a0cf144bb30a8b7f7605369e35cac45e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 02:35:36 +0900 Subject: [PATCH 55/82] Fix disclaimer test scene supporter toggle --- osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs b/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs index 681bf1b40b..49fab08ded 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Menus API.LocalUser.Value = new User { Username = API.LocalUser.Value.Username, - Id = API.LocalUser.Value.Id, + Id = API.LocalUser.Value.Id + 1, IsSupporter = !API.LocalUser.Value.IsSupporter, }; }); From 7b368dca359f9ec9a766877cc77d7edbfe821fdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 02:59:24 +0900 Subject: [PATCH 56/82] Add test coverage --- .../SongSelect/TestScenePlaySongSelect.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 51d302123b..105d96cdfe 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -465,6 +465,43 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("carousel still correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); } + [Test] + public void TestExternalBeatmapChangeWhileFilteredThenRefilter() + { + createSongSelect(); + addManyTestMaps(); + + changeRuleset(0); + + AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); + + AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType().First().Text = "nonono"); + + AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap); + + AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmap == null); + + BeatmapInfo target = null; + + AddStep("select beatmap externally", () => + { + target = manager.GetAllUsableBeatmapSets().Where(b => b.Beatmaps.Any(bi => bi.RulesetID == 1)) + .ElementAt(5).Beatmaps.First(); + + Beatmap.Value = manager.GetWorkingBeatmap(target); + }); + + AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); + + AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID); + AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); + + AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType().First().Text = "nononoo"); + + AddUntilStep("game lost selection", () => Beatmap.Value is DummyWorkingBeatmap); + AddAssert("carousel lost selection", () => songSelect.Carousel.SelectedBeatmap == null); + } + [Test] public void TestAutoplayViaCtrlEnter() { From ed837d311529bfe180871ac4600824daff890a21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 10:18:41 +0900 Subject: [PATCH 57/82] Use framework extension method for FromHex --- .../Objects/Drawables/DrawableSpinner.cs | 4 +- .../Visual/Online/TestSceneChatLink.cs | 3 +- .../Components/TournamentMatchChatDisplay.cs | 2 +- .../Screens/Gameplay/Components/TeamScore.cs | 4 +- .../Ladder/Components/DrawableMatchTeam.cs | 9 +- .../Screens/Ladder/LadderScreen.cs | 4 +- osu.Game.Tournament/TournamentGame.cs | 12 +- osu.Game/Graphics/OsuColour.cs | 214 +++++++----------- .../UserInterface/DrawableOsuMenuItem.cs | 5 +- .../UserInterfaceV2/LabelledDrawable.cs | 3 +- osu.Game/Online/Leaderboards/DrawableRank.cs | 24 +- .../Online/Leaderboards/LeaderboardScore.cs | 8 +- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 5 +- .../BeatmapSet/Buttons/HeaderButton.cs | 8 +- osu.Game/Overlays/Chat/ChatLine.cs | 68 +++--- .../Chat/Selection/ChannelSelectionOverlay.cs | 10 +- .../Chat/Tabs/PrivateChannelTabItem.cs | 2 +- osu.Game/Overlays/Dialog/PopupDialog.cs | 7 +- osu.Game/Overlays/Dialog/PopupDialogButton.cs | 4 +- osu.Game/Overlays/Direct/FilterControl.cs | 3 +- osu.Game/Overlays/Direct/Header.cs | 3 +- osu.Game/Overlays/DirectOverlay.cs | 7 +- osu.Game/Overlays/MedalOverlay.cs | 6 +- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 8 +- .../Profile/Header/TopHeaderContainer.cs | 3 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 3 +- osu.Game/Overlays/Social/FilterControl.cs | 4 +- osu.Game/Overlays/Social/Header.cs | 3 +- osu.Game/Overlays/SocialOverlay.cs | 8 +- .../Edit/Components/Menus/EditorMenuBar.cs | 3 +- .../Components/Timeline/TimelineArea.cs | 8 +- osu.Game/Screens/Menu/IntroSequence.cs | 12 +- osu.Game/Screens/Menu/OsuLogo.cs | 8 +- .../Multi/Components/DrawableGameType.cs | 3 +- .../Multi/Components/ParticipantsList.cs | 4 +- osu.Game/Screens/Multi/Header.cs | 3 +- .../Multi/Lounge/Components/DrawableRoom.cs | 2 +- .../Screens/Multi/Match/Components/Footer.cs | 3 +- .../Match/Components/MatchSettingsOverlay.cs | 4 +- .../Match/Components/PurpleTriangleButton.cs | 8 +- .../Components/RoomAvailabilityPicker.cs | 3 +- osu.Game/Screens/Multi/Multiplayer.cs | 11 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 +- .../Carousel/DrawableCarouselBeatmap.cs | 5 +- 44 files changed, 249 insertions(+), 276 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index de11ab6419..0ec7f2ebfe 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly SpriteIcon symbol; - private readonly Color4 baseColour = OsuColour.FromHex(@"002c3c"); - private readonly Color4 fillColour = OsuColour.FromHex(@"005b7c"); + private readonly Color4 baseColour = Color4Extensions.FromHex(@"002c3c"); + private readonly Color4 fillColour = Color4Extensions.FromHex(@"005b7c"); private readonly IBindable positionBindable = new Bindable(); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index a1c77e2db0..c76d4fd5b8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -7,6 +7,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -102,7 +103,7 @@ namespace osu.Game.Tests.Visual.Online { bool hasBackground = !string.IsNullOrEmpty(newLine.Message.Sender.Colour); - Color4 textColour = isAction && hasBackground ? OsuColour.FromHex(newLine.Message.Sender.Colour) : Color4.White; + Color4 textColour = isAction && hasBackground ? Color4Extensions.FromHex(newLine.Message.Sender.Colour) : Color4.White; var linkCompilers = newLine.ContentFlow.Where(d => d is DrawableLinkCompiler).ToList(); var linkSprites = linkCompilers.SelectMany(comp => ((DrawableLinkCompiler)comp).Parts); diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 8eb1c98ba0..2a183d0d45 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -84,7 +84,7 @@ namespace osu.Game.Tournament.Components // else if (info.CurrentMatch.Value.Team2.Value.Players.Any(u => u.Id == Message.Sender.Id)) // SenderText.Colour = TournamentGame.COLOUR_BLUE; // else if (Message.Sender.Colour != null) - // SenderText.Colour = ColourBox.Colour = OsuColour.FromHex(Message.Sender.Colour); + // SenderText.Colour = ColourBox.Colour = Color4Extensions.FromHex(Message.Sender.Colour); } } } diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs index c7071484ca..36c78c5ac1 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components }, box = new Box { - Colour = OsuColour.FromHex("#FFE8AD"), + Colour = Color4Extensions.FromHex("#FFE8AD"), RelativeSizeAxes = Axes.Both, }, }; @@ -85,7 +85,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, - Colour = OsuColour.FromHex("#FFE8AD").Opacity(0.1f), + Colour = Color4Extensions.FromHex("#FFE8AD").Opacity(0.1f), Hollow = true, Radius = 20, Roundness = 10, diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs index fe7e80873c..15cb7e44cb 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -85,8 +86,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components this.ladderEditor = ladderEditor; colourWinner = losers - ? OsuColour.FromHex("#8E7F48") - : OsuColour.FromHex("#1462AA"); + ? Color4Extensions.FromHex("#8E7F48") + : Color4Extensions.FromHex("#1462AA"); InternalChildren = new Drawable[] { @@ -180,8 +181,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { bool winner = completed.Value && isWinner?.Invoke() == true; - background.FadeColour(winner ? Color4.White : OsuColour.FromHex("#444"), winner ? 500 : 0, Easing.OutQuint); - backgroundRight.FadeColour(winner ? colourWinner : OsuColour.FromHex("#333"), winner ? 500 : 0, Easing.OutQuint); + background.FadeColour(winner ? Color4.White : Color4Extensions.FromHex("#444"), winner ? 500 : 0, Easing.OutQuint); + backgroundRight.FadeColour(winner ? colourWinner : Color4Extensions.FromHex("#333"), winner ? 500 : 0, Easing.OutQuint); AcronymText.Colour = winner ? Color4.Black : Color4.White; diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index c7e59cfa7b..6f62b3ddba 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -32,8 +32,8 @@ namespace osu.Game.Tournament.Screens.Ladder [BackgroundDependencyLoader] private void load(OsuColour colours, Storage storage) { - normalPathColour = OsuColour.FromHex("#66D1FF"); - losersPathColour = OsuColour.FromHex("#FFC700"); + normalPathColour = Color4Extensions.FromHex("#66D1FF"); + losersPathColour = Color4Extensions.FromHex("#FFC700"); RelativeSizeAxes = Axes.Both; diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index 6d597d5e7d..78bb66d553 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -1,9 +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 osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; -using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Tournament.Models; using osuTK.Graphics; @@ -14,13 +14,13 @@ namespace osu.Game.Tournament { public static ColourInfo GetTeamColour(TeamColour teamColour) => teamColour == TeamColour.Red ? COLOUR_RED : COLOUR_BLUE; - public static readonly Color4 COLOUR_RED = OsuColour.FromHex("#AA1414"); - public static readonly Color4 COLOUR_BLUE = OsuColour.FromHex("#1462AA"); + public static readonly Color4 COLOUR_RED = Color4Extensions.FromHex("#AA1414"); + public static readonly Color4 COLOUR_BLUE = Color4Extensions.FromHex("#1462AA"); - public static readonly Color4 ELEMENT_BACKGROUND_COLOUR = OsuColour.FromHex("#fff"); - public static readonly Color4 ELEMENT_FOREGROUND_COLOUR = OsuColour.FromHex("#000"); + public static readonly Color4 ELEMENT_BACKGROUND_COLOUR = Color4Extensions.FromHex("#fff"); + public static readonly Color4 ELEMENT_FOREGROUND_COLOUR = Color4Extensions.FromHex("#000"); - public static readonly Color4 TEXT_COLOUR = OsuColour.FromHex("#fff"); + public static readonly Color4 TEXT_COLOUR = Color4Extensions.FromHex("#fff"); protected override void LoadComplete() { diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 59dd823266..984f5e52d1 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -1,8 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Globalization; +using osu.Framework.Extensions.Color4Extensions; using osu.Game.Beatmaps; using osuTK.Graphics; @@ -13,45 +12,6 @@ namespace osu.Game.Graphics public static Color4 Gray(float amt) => new Color4(amt, amt, amt, 1f); public static Color4 Gray(byte amt) => new Color4(amt, amt, amt, 255); - public static Color4 FromHex(string hex) - { - var hexSpan = hex[0] == '#' ? hex.AsSpan().Slice(1) : hex.AsSpan(); - - switch (hexSpan.Length) - { - default: - throw new ArgumentException(@"Invalid hex string length!"); - - case 3: - return new Color4( - (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17), - (byte)(byte.Parse(hexSpan.Slice(1, 1), NumberStyles.HexNumber) * 17), - (byte)(byte.Parse(hexSpan.Slice(2, 1), NumberStyles.HexNumber) * 17), - 255); - - case 6: - return new Color4( - byte.Parse(hexSpan.Slice(0, 2), NumberStyles.HexNumber), - byte.Parse(hexSpan.Slice(2, 2), NumberStyles.HexNumber), - byte.Parse(hexSpan.Slice(4, 2), NumberStyles.HexNumber), - 255); - - case 4: - return new Color4( - (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17), - (byte)(byte.Parse(hexSpan.Slice(1, 1), NumberStyles.HexNumber) * 17), - (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17), - (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17)); - - case 8: - return new Color4( - byte.Parse(hexSpan.Slice(0, 2), NumberStyles.HexNumber), - byte.Parse(hexSpan.Slice(2, 2), NumberStyles.HexNumber), - byte.Parse(hexSpan.Slice(4, 2), NumberStyles.HexNumber), - byte.Parse(hexSpan.Slice(6, 2), NumberStyles.HexNumber)); - } - } - public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterColour = false) { switch (difficulty) @@ -78,105 +38,105 @@ namespace osu.Game.Graphics } // See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less - public readonly Color4 PurpleLighter = FromHex(@"eeeeff"); - public readonly Color4 PurpleLight = FromHex(@"aa88ff"); - public readonly Color4 PurpleLightAlternative = FromHex(@"cba4da"); - public readonly Color4 Purple = FromHex(@"8866ee"); - public readonly Color4 PurpleDark = FromHex(@"6644cc"); - public readonly Color4 PurpleDarkAlternative = FromHex(@"312436"); - public readonly Color4 PurpleDarker = FromHex(@"441188"); + public readonly Color4 PurpleLighter = Color4Extensions.FromHex(@"eeeeff"); + public readonly Color4 PurpleLight = Color4Extensions.FromHex(@"aa88ff"); + public readonly Color4 PurpleLightAlternative = Color4Extensions.FromHex(@"cba4da"); + public readonly Color4 Purple = Color4Extensions.FromHex(@"8866ee"); + public readonly Color4 PurpleDark = Color4Extensions.FromHex(@"6644cc"); + public readonly Color4 PurpleDarkAlternative = Color4Extensions.FromHex(@"312436"); + public readonly Color4 PurpleDarker = Color4Extensions.FromHex(@"441188"); - public readonly Color4 PinkLighter = FromHex(@"ffddee"); - public readonly Color4 PinkLight = FromHex(@"ff99cc"); - public readonly Color4 Pink = FromHex(@"ff66aa"); - public readonly Color4 PinkDark = FromHex(@"cc5288"); - public readonly Color4 PinkDarker = FromHex(@"bb1177"); + public readonly Color4 PinkLighter = Color4Extensions.FromHex(@"ffddee"); + public readonly Color4 PinkLight = Color4Extensions.FromHex(@"ff99cc"); + public readonly Color4 Pink = Color4Extensions.FromHex(@"ff66aa"); + public readonly Color4 PinkDark = Color4Extensions.FromHex(@"cc5288"); + public readonly Color4 PinkDarker = Color4Extensions.FromHex(@"bb1177"); - public readonly Color4 BlueLighter = FromHex(@"ddffff"); - public readonly Color4 BlueLight = FromHex(@"99eeff"); - public readonly Color4 Blue = FromHex(@"66ccff"); - public readonly Color4 BlueDark = FromHex(@"44aadd"); - public readonly Color4 BlueDarker = FromHex(@"2299bb"); + public readonly Color4 BlueLighter = Color4Extensions.FromHex(@"ddffff"); + public readonly Color4 BlueLight = Color4Extensions.FromHex(@"99eeff"); + public readonly Color4 Blue = Color4Extensions.FromHex(@"66ccff"); + public readonly Color4 BlueDark = Color4Extensions.FromHex(@"44aadd"); + public readonly Color4 BlueDarker = Color4Extensions.FromHex(@"2299bb"); - public readonly Color4 YellowLighter = FromHex(@"ffffdd"); - public readonly Color4 YellowLight = FromHex(@"ffdd55"); - public readonly Color4 Yellow = FromHex(@"ffcc22"); - public readonly Color4 YellowDark = FromHex(@"eeaa00"); - public readonly Color4 YellowDarker = FromHex(@"cc6600"); + public readonly Color4 YellowLighter = Color4Extensions.FromHex(@"ffffdd"); + public readonly Color4 YellowLight = Color4Extensions.FromHex(@"ffdd55"); + public readonly Color4 Yellow = Color4Extensions.FromHex(@"ffcc22"); + public readonly Color4 YellowDark = Color4Extensions.FromHex(@"eeaa00"); + public readonly Color4 YellowDarker = Color4Extensions.FromHex(@"cc6600"); - public readonly Color4 GreenLighter = FromHex(@"eeffcc"); - public readonly Color4 GreenLight = FromHex(@"b3d944"); - public readonly Color4 Green = FromHex(@"88b300"); - public readonly Color4 GreenDark = FromHex(@"668800"); - public readonly Color4 GreenDarker = FromHex(@"445500"); + public readonly Color4 GreenLighter = Color4Extensions.FromHex(@"eeffcc"); + public readonly Color4 GreenLight = Color4Extensions.FromHex(@"b3d944"); + public readonly Color4 Green = Color4Extensions.FromHex(@"88b300"); + public readonly Color4 GreenDark = Color4Extensions.FromHex(@"668800"); + public readonly Color4 GreenDarker = Color4Extensions.FromHex(@"445500"); - public readonly Color4 Sky = FromHex(@"6bb5ff"); - public readonly Color4 GreySkyLighter = FromHex(@"c6e3f4"); - public readonly Color4 GreySkyLight = FromHex(@"8ab3cc"); - public readonly Color4 GreySky = FromHex(@"405461"); - public readonly Color4 GreySkyDark = FromHex(@"303d47"); - public readonly Color4 GreySkyDarker = FromHex(@"21272c"); + public readonly Color4 Sky = Color4Extensions.FromHex(@"6bb5ff"); + public readonly Color4 GreySkyLighter = Color4Extensions.FromHex(@"c6e3f4"); + public readonly Color4 GreySkyLight = Color4Extensions.FromHex(@"8ab3cc"); + public readonly Color4 GreySky = Color4Extensions.FromHex(@"405461"); + public readonly Color4 GreySkyDark = Color4Extensions.FromHex(@"303d47"); + public readonly Color4 GreySkyDarker = Color4Extensions.FromHex(@"21272c"); - public readonly Color4 Seafoam = FromHex(@"05ffa2"); - public readonly Color4 GreySeafoamLighter = FromHex(@"9ebab1"); - public readonly Color4 GreySeafoamLight = FromHex(@"4d7365"); - public readonly Color4 GreySeafoam = FromHex(@"33413c"); - public readonly Color4 GreySeafoamDark = FromHex(@"2c3532"); - public readonly Color4 GreySeafoamDarker = FromHex(@"1e2422"); + public readonly Color4 Seafoam = Color4Extensions.FromHex(@"05ffa2"); + public readonly Color4 GreySeafoamLighter = Color4Extensions.FromHex(@"9ebab1"); + public readonly Color4 GreySeafoamLight = Color4Extensions.FromHex(@"4d7365"); + public readonly Color4 GreySeafoam = Color4Extensions.FromHex(@"33413c"); + public readonly Color4 GreySeafoamDark = Color4Extensions.FromHex(@"2c3532"); + public readonly Color4 GreySeafoamDarker = Color4Extensions.FromHex(@"1e2422"); - public readonly Color4 Cyan = FromHex(@"05f4fd"); - public readonly Color4 GreyCyanLighter = FromHex(@"77b1b3"); - public readonly Color4 GreyCyanLight = FromHex(@"436d6f"); - public readonly Color4 GreyCyan = FromHex(@"293d3e"); - public readonly Color4 GreyCyanDark = FromHex(@"243536"); - public readonly Color4 GreyCyanDarker = FromHex(@"1e2929"); + public readonly Color4 Cyan = Color4Extensions.FromHex(@"05f4fd"); + public readonly Color4 GreyCyanLighter = Color4Extensions.FromHex(@"77b1b3"); + public readonly Color4 GreyCyanLight = Color4Extensions.FromHex(@"436d6f"); + public readonly Color4 GreyCyan = Color4Extensions.FromHex(@"293d3e"); + public readonly Color4 GreyCyanDark = Color4Extensions.FromHex(@"243536"); + public readonly Color4 GreyCyanDarker = Color4Extensions.FromHex(@"1e2929"); - public readonly Color4 Lime = FromHex(@"82ff05"); - public readonly Color4 GreyLimeLighter = FromHex(@"deff87"); - public readonly Color4 GreyLimeLight = FromHex(@"657259"); - public readonly Color4 GreyLime = FromHex(@"3f443a"); - public readonly Color4 GreyLimeDark = FromHex(@"32352e"); - public readonly Color4 GreyLimeDarker = FromHex(@"2e302b"); + public readonly Color4 Lime = Color4Extensions.FromHex(@"82ff05"); + public readonly Color4 GreyLimeLighter = Color4Extensions.FromHex(@"deff87"); + public readonly Color4 GreyLimeLight = Color4Extensions.FromHex(@"657259"); + public readonly Color4 GreyLime = Color4Extensions.FromHex(@"3f443a"); + public readonly Color4 GreyLimeDark = Color4Extensions.FromHex(@"32352e"); + public readonly Color4 GreyLimeDarker = Color4Extensions.FromHex(@"2e302b"); - public readonly Color4 Violet = FromHex(@"bf04ff"); - public readonly Color4 GreyVioletLighter = FromHex(@"ebb8fe"); - public readonly Color4 GreyVioletLight = FromHex(@"685370"); - public readonly Color4 GreyViolet = FromHex(@"46334d"); - public readonly Color4 GreyVioletDark = FromHex(@"2c2230"); - public readonly Color4 GreyVioletDarker = FromHex(@"201823"); + public readonly Color4 Violet = Color4Extensions.FromHex(@"bf04ff"); + public readonly Color4 GreyVioletLighter = Color4Extensions.FromHex(@"ebb8fe"); + public readonly Color4 GreyVioletLight = Color4Extensions.FromHex(@"685370"); + public readonly Color4 GreyViolet = Color4Extensions.FromHex(@"46334d"); + public readonly Color4 GreyVioletDark = Color4Extensions.FromHex(@"2c2230"); + public readonly Color4 GreyVioletDarker = Color4Extensions.FromHex(@"201823"); - public readonly Color4 Carmine = FromHex(@"ff0542"); - public readonly Color4 GreyCarmineLighter = FromHex(@"deaab4"); - public readonly Color4 GreyCarmineLight = FromHex(@"644f53"); - public readonly Color4 GreyCarmine = FromHex(@"342b2d"); - public readonly Color4 GreyCarmineDark = FromHex(@"302a2b"); - public readonly Color4 GreyCarmineDarker = FromHex(@"241d1e"); + public readonly Color4 Carmine = Color4Extensions.FromHex(@"ff0542"); + public readonly Color4 GreyCarmineLighter = Color4Extensions.FromHex(@"deaab4"); + public readonly Color4 GreyCarmineLight = Color4Extensions.FromHex(@"644f53"); + public readonly Color4 GreyCarmine = Color4Extensions.FromHex(@"342b2d"); + public readonly Color4 GreyCarmineDark = Color4Extensions.FromHex(@"302a2b"); + public readonly Color4 GreyCarmineDarker = Color4Extensions.FromHex(@"241d1e"); - public readonly Color4 Gray0 = FromHex(@"000"); - public readonly Color4 Gray1 = FromHex(@"111"); - public readonly Color4 Gray2 = FromHex(@"222"); - public readonly Color4 Gray3 = FromHex(@"333"); - public readonly Color4 Gray4 = FromHex(@"444"); - public readonly Color4 Gray5 = FromHex(@"555"); - public readonly Color4 Gray6 = FromHex(@"666"); - public readonly Color4 Gray7 = FromHex(@"777"); - public readonly Color4 Gray8 = FromHex(@"888"); - public readonly Color4 Gray9 = FromHex(@"999"); - public readonly Color4 GrayA = FromHex(@"aaa"); - public readonly Color4 GrayB = FromHex(@"bbb"); - public readonly Color4 GrayC = FromHex(@"ccc"); - public readonly Color4 GrayD = FromHex(@"ddd"); - public readonly Color4 GrayE = FromHex(@"eee"); - public readonly Color4 GrayF = FromHex(@"fff"); + public readonly Color4 Gray0 = Color4Extensions.FromHex(@"000"); + public readonly Color4 Gray1 = Color4Extensions.FromHex(@"111"); + public readonly Color4 Gray2 = Color4Extensions.FromHex(@"222"); + public readonly Color4 Gray3 = Color4Extensions.FromHex(@"333"); + public readonly Color4 Gray4 = Color4Extensions.FromHex(@"444"); + public readonly Color4 Gray5 = Color4Extensions.FromHex(@"555"); + public readonly Color4 Gray6 = Color4Extensions.FromHex(@"666"); + public readonly Color4 Gray7 = Color4Extensions.FromHex(@"777"); + public readonly Color4 Gray8 = Color4Extensions.FromHex(@"888"); + public readonly Color4 Gray9 = Color4Extensions.FromHex(@"999"); + public readonly Color4 GrayA = Color4Extensions.FromHex(@"aaa"); + public readonly Color4 GrayB = Color4Extensions.FromHex(@"bbb"); + public readonly Color4 GrayC = Color4Extensions.FromHex(@"ccc"); + public readonly Color4 GrayD = Color4Extensions.FromHex(@"ddd"); + public readonly Color4 GrayE = Color4Extensions.FromHex(@"eee"); + public readonly Color4 GrayF = Color4Extensions.FromHex(@"fff"); - public readonly Color4 RedLighter = FromHex(@"ffeded"); - public readonly Color4 RedLight = FromHex(@"ed7787"); - public readonly Color4 Red = FromHex(@"ed1121"); - public readonly Color4 RedDark = FromHex(@"ba0011"); - public readonly Color4 RedDarker = FromHex(@"870000"); + public readonly Color4 RedLighter = Color4Extensions.FromHex(@"ffeded"); + public readonly Color4 RedLight = Color4Extensions.FromHex(@"ed7787"); + public readonly Color4 Red = Color4Extensions.FromHex(@"ed1121"); + public readonly Color4 RedDark = Color4Extensions.FromHex(@"ba0011"); + public readonly Color4 RedDarker = Color4Extensions.FromHex(@"870000"); - public readonly Color4 ChatBlue = FromHex(@"17292e"); + public readonly Color4 ChatBlue = Color4Extensions.FromHex(@"17292e"); - public readonly Color4 ContextMenuGray = FromHex(@"223034"); + public readonly Color4 ContextMenuGray = Color4Extensions.FromHex(@"223034"); } } diff --git a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs index 591ed3df83..a3ca851341 100644 --- a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -38,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface sampleClick = audio.Samples.Get(@"UI/generic-select"); BackgroundColour = Color4.Transparent; - BackgroundColourHover = OsuColour.FromHex(@"172023"); + BackgroundColourHover = Color4Extensions.FromHex(@"172023"); updateTextColour(); } @@ -57,7 +58,7 @@ namespace osu.Game.Graphics.UserInterface break; case MenuItemType.Highlighted: - text.Colour = OsuColour.FromHex(@"ffcc22"); + text.Colour = Color4Extensions.FromHex(@"ffcc22"); break; } } diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs index f44bd72aee..0e995ca73d 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs @@ -2,6 +2,7 @@ // 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; @@ -42,7 +43,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("1c2125"), + Colour = Color4Extensions.FromHex("1c2125"), }, new FillFlowContainer { diff --git a/osu.Game/Online/Leaderboards/DrawableRank.cs b/osu.Game/Online/Leaderboards/DrawableRank.cs index 20bda4601f..45b91bbf81 100644 --- a/osu.Game/Online/Leaderboards/DrawableRank.cs +++ b/osu.Game/Online/Leaderboards/DrawableRank.cs @@ -80,23 +80,23 @@ namespace osu.Game.Online.Leaderboards { case ScoreRank.XH: case ScoreRank.X: - return OsuColour.FromHex(@"ce1c9d"); + return Color4Extensions.FromHex(@"ce1c9d"); case ScoreRank.SH: case ScoreRank.S: - return OsuColour.FromHex(@"00a8b5"); + return Color4Extensions.FromHex(@"00a8b5"); case ScoreRank.A: - return OsuColour.FromHex(@"7cce14"); + return Color4Extensions.FromHex(@"7cce14"); case ScoreRank.B: - return OsuColour.FromHex(@"e3b130"); + return Color4Extensions.FromHex(@"e3b130"); case ScoreRank.C: - return OsuColour.FromHex(@"f18252"); + return Color4Extensions.FromHex(@"f18252"); default: - return OsuColour.FromHex(@"e95353"); + return Color4Extensions.FromHex(@"e95353"); } } @@ -109,23 +109,23 @@ namespace osu.Game.Online.Leaderboards { case ScoreRank.XH: case ScoreRank.SH: - return ColourInfo.GradientVertical(Color4.White, OsuColour.FromHex("afdff0")); + return ColourInfo.GradientVertical(Color4.White, Color4Extensions.FromHex("afdff0")); case ScoreRank.X: case ScoreRank.S: - return ColourInfo.GradientVertical(OsuColour.FromHex(@"ffe7a8"), OsuColour.FromHex(@"ffb800")); + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"ffe7a8"), Color4Extensions.FromHex(@"ffb800")); case ScoreRank.A: - return OsuColour.FromHex(@"275227"); + return Color4Extensions.FromHex(@"275227"); case ScoreRank.B: - return OsuColour.FromHex(@"553a2b"); + return Color4Extensions.FromHex(@"553a2b"); case ScoreRank.C: - return OsuColour.FromHex(@"473625"); + return Color4Extensions.FromHex(@"473625"); default: - return OsuColour.FromHex(@"512525"); + return Color4Extensions.FromHex(@"512525"); } } } diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index ba92b993a2..1469f29874 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -200,7 +200,7 @@ namespace osu.Game.Online.Leaderboards scoreLabel = new GlowingSpriteText { TextColour = Color4.White, - GlowColour = OsuColour.FromHex(@"83ccfa"), + GlowColour = Color4Extensions.FromHex(@"83ccfa"), Text = score.TotalScore.ToString(@"N0"), Font = OsuFont.Numeric.With(size: 23), }, @@ -325,7 +325,7 @@ namespace osu.Game.Online.Leaderboards Origin = Anchor.Centre, Size = new Vector2(icon_size), Rotation = 45, - Colour = OsuColour.FromHex(@"3087ac"), + Colour = Color4Extensions.FromHex(@"3087ac"), Icon = FontAwesome.Solid.Square, Shadow = true, }, @@ -334,7 +334,7 @@ namespace osu.Game.Online.Leaderboards Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(icon_size - 6), - Colour = OsuColour.FromHex(@"a4edff"), + Colour = Color4Extensions.FromHex(@"a4edff"), Icon = statistic.Icon, }, }, @@ -344,7 +344,7 @@ namespace osu.Game.Online.Leaderboards Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, TextColour = Color4.White, - GlowColour = OsuColour.FromHex(@"83ccfa"), + GlowColour = Color4Extensions.FromHex(@"83ccfa"), Text = statistic.Value, Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold), }, diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index ba0a62ec2f..a2464bef09 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -124,7 +125,7 @@ namespace osu.Game.Overlays.BeatmapSet Icon = FontAwesome.Solid.Square, Size = new Vector2(12), Rotation = 45, - Colour = OsuColour.FromHex(@"441288"), + Colour = Color4Extensions.FromHex(@"441288"), }, new SpriteIcon { @@ -132,7 +133,7 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.Centre, Icon = icon, Size = new Vector2(12), - Colour = OsuColour.FromHex(@"f7dd55"), + Colour = Color4Extensions.FromHex(@"f7dd55"), Scale = new Vector2(0.8f), }, value = new OsuSpriteText diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs index 6de1d3fca7..99b0b2ed3b 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs @@ -2,8 +2,8 @@ // 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.Game.Graphics; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.BeatmapSet.Buttons @@ -19,9 +19,9 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons [BackgroundDependencyLoader] private void load() { - BackgroundColour = OsuColour.FromHex(@"094c5f"); - Triangles.ColourLight = OsuColour.FromHex(@"0f7c9b"); - Triangles.ColourDark = OsuColour.FromHex(@"094c5f"); + BackgroundColour = Color4Extensions.FromHex(@"094c5f"); + Triangles.ColourLight = Color4Extensions.FromHex(@"0f7c9b"); + Triangles.ColourDark = Color4Extensions.FromHex(@"094c5f"); Triangles.TriangleScale = 1.5f; } } diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 8abde8a24f..496986dc56 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -123,7 +123,7 @@ namespace osu.Game.Overlays.Chat EdgeEffect = new EdgeEffectParameters { Radius = 1, - Colour = OsuColour.FromHex(message.Sender.Colour), + Colour = Color4Extensions.FromHex(message.Sender.Colour), Type = EdgeEffectType.Shadow, }, Padding = new MarginPadding { Left = 3, Right = 3, Bottom = 1, Top = -3 }, @@ -172,7 +172,7 @@ namespace osu.Game.Overlays.Chat t.Font = OsuFont.GetFont(italics: true); if (senderHasBackground) - t.Colour = OsuColour.FromHex(message.Sender.Colour); + t.Colour = Color4Extensions.FromHex(message.Sender.Colour); } t.Font = t.Font.With(size: TextSize); @@ -249,41 +249,41 @@ namespace osu.Game.Overlays.Chat private static readonly Color4[] username_colours = { - OsuColour.FromHex("588c7e"), - OsuColour.FromHex("b2a367"), - OsuColour.FromHex("c98f65"), - OsuColour.FromHex("bc5151"), - OsuColour.FromHex("5c8bd6"), - OsuColour.FromHex("7f6ab7"), - OsuColour.FromHex("a368ad"), - OsuColour.FromHex("aa6880"), + Color4Extensions.FromHex("588c7e"), + Color4Extensions.FromHex("b2a367"), + Color4Extensions.FromHex("c98f65"), + Color4Extensions.FromHex("bc5151"), + Color4Extensions.FromHex("5c8bd6"), + Color4Extensions.FromHex("7f6ab7"), + Color4Extensions.FromHex("a368ad"), + Color4Extensions.FromHex("aa6880"), - OsuColour.FromHex("6fad9b"), - OsuColour.FromHex("f2e394"), - OsuColour.FromHex("f2ae72"), - OsuColour.FromHex("f98f8a"), - OsuColour.FromHex("7daef4"), - OsuColour.FromHex("a691f2"), - OsuColour.FromHex("c894d3"), - OsuColour.FromHex("d895b0"), + Color4Extensions.FromHex("6fad9b"), + Color4Extensions.FromHex("f2e394"), + Color4Extensions.FromHex("f2ae72"), + Color4Extensions.FromHex("f98f8a"), + Color4Extensions.FromHex("7daef4"), + Color4Extensions.FromHex("a691f2"), + Color4Extensions.FromHex("c894d3"), + Color4Extensions.FromHex("d895b0"), - OsuColour.FromHex("53c4a1"), - OsuColour.FromHex("eace5c"), - OsuColour.FromHex("ea8c47"), - OsuColour.FromHex("fc4f4f"), - OsuColour.FromHex("3d94ea"), - OsuColour.FromHex("7760ea"), - OsuColour.FromHex("af52c6"), - OsuColour.FromHex("e25696"), + Color4Extensions.FromHex("53c4a1"), + Color4Extensions.FromHex("eace5c"), + Color4Extensions.FromHex("ea8c47"), + Color4Extensions.FromHex("fc4f4f"), + Color4Extensions.FromHex("3d94ea"), + Color4Extensions.FromHex("7760ea"), + Color4Extensions.FromHex("af52c6"), + Color4Extensions.FromHex("e25696"), - OsuColour.FromHex("677c66"), - OsuColour.FromHex("9b8732"), - OsuColour.FromHex("8c5129"), - OsuColour.FromHex("8c3030"), - OsuColour.FromHex("1f5d91"), - OsuColour.FromHex("4335a5"), - OsuColour.FromHex("812a96"), - OsuColour.FromHex("992861"), + Color4Extensions.FromHex("677c66"), + Color4Extensions.FromHex("9b8732"), + Color4Extensions.FromHex("8c5129"), + Color4Extensions.FromHex("8c3030"), + Color4Extensions.FromHex("1f5d91"), + Color4Extensions.FromHex("4335a5"), + Color4Extensions.FromHex("812a96"), + Color4Extensions.FromHex("992861"), }; } } diff --git a/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs b/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs index 25a9a51638..b46ca6b040 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelSelectionOverlay.cs @@ -41,10 +41,10 @@ namespace osu.Game.Overlays.Chat.Selection { RelativeSizeAxes = Axes.X; - Waves.FirstWaveColour = OsuColour.FromHex("353535"); - Waves.SecondWaveColour = OsuColour.FromHex("434343"); - Waves.ThirdWaveColour = OsuColour.FromHex("515151"); - Waves.FourthWaveColour = OsuColour.FromHex("595959"); + Waves.FirstWaveColour = Color4Extensions.FromHex("353535"); + Waves.SecondWaveColour = Color4Extensions.FromHex("434343"); + Waves.ThirdWaveColour = Color4Extensions.FromHex("515151"); + Waves.FourthWaveColour = Color4Extensions.FromHex("595959"); Children = new Drawable[] { @@ -154,7 +154,7 @@ namespace osu.Game.Overlays.Chat.Selection { bg.Colour = colours.Gray3; triangles.ColourDark = colours.Gray3; - triangles.ColourLight = OsuColour.FromHex(@"353535"); + triangles.ColourLight = Color4Extensions.FromHex(@"353535"); headerBg.Colour = colours.Gray2.Opacity(0.75f); } diff --git a/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs b/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs index 1413b8fe78..5b428a3825 100644 --- a/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Chat.Tabs { var user = Value.Users.First(); - BackgroundActive = user.Colour != null ? OsuColour.FromHex(user.Colour) : colours.BlueDark; + BackgroundActive = user.Colour != null ? Color4Extensions.FromHex(user.Colour) : colours.BlueDark; BackgroundInactive = BackgroundActive.Darken(0.5f); } } diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 37db78faa1..02ef900dc5 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osuTK; @@ -114,13 +113,13 @@ namespace osu.Game.Overlays.Dialog new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"221a21"), + Colour = Color4Extensions.FromHex(@"221a21"), }, new Triangles { RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"271e26"), - ColourDark = OsuColour.FromHex(@"1e171e"), + ColourLight = Color4Extensions.FromHex(@"271e26"), + ColourDark = Color4Extensions.FromHex(@"1e171e"), TriangleScale = 4, }, }, diff --git a/osu.Game/Overlays/Dialog/PopupDialogButton.cs b/osu.Game/Overlays/Dialog/PopupDialogButton.cs index 75bae25b73..76ee438d6d 100644 --- a/osu.Game/Overlays/Dialog/PopupDialogButton.cs +++ b/osu.Game/Overlays/Dialog/PopupDialogButton.cs @@ -1,7 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Graphics; +using osu.Framework.Extensions.Color4Extensions; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Dialog @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Dialog public PopupDialogButton() { Height = 50; - BackgroundColour = OsuColour.FromHex(@"150e14"); + BackgroundColour = Color4Extensions.FromHex(@"150e14"); TextSize = 18; } } diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 70a3ab54fb..e5b2b5cc34 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Online.API.Requests; @@ -16,7 +17,7 @@ namespace osu.Game.Overlays.Direct { private DirectRulesetSelector rulesetSelector; - protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); + protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"384552"); protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked; protected override BeatmapSearchCategory DefaultCategory => BeatmapSearchCategory.Leaderboard; diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index 80870dcb68..5b3e394a18 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.ComponentModel; +using osu.Framework.Extensions.Color4Extensions; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; @@ -13,7 +14,7 @@ namespace osu.Game.Overlays.Direct { public class Header : SearchableListHeader { - protected override Color4 BackgroundColour => OsuColour.FromHex(@"252f3a"); + protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"252f3a"); protected override DirectTab DefaultTab => DirectTab.Search; protected override Drawable CreateHeaderText() => new OsuSpriteText { Text = @"osu!direct", Font = OsuFont.GetFont(size: 25) }; diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index a6f8b65a0d..61986d1cf0 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Threading; @@ -34,9 +35,9 @@ namespace osu.Game.Overlays private readonly OsuSpriteText resultCountsText; private FillFlowContainer panels; - protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74"); - protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71"); - protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); + protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"485e74"); + protected override Color4 TrianglesColourLight => Color4Extensions.FromHex(@"465b71"); + protected override Color4 TrianglesColourDark => Color4Extensions.FromHex(@"3f5265"); protected override SearchableListHeader CreateHeader() => new Header(); protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index aa28b0659d..4425c2f168 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.cs @@ -126,14 +126,14 @@ namespace osu.Game.Overlays new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"05262f"), + Colour = Color4Extensions.FromHex(@"05262f"), }, new Triangles { RelativeSizeAxes = Axes.Both, TriangleScale = 2, - ColourDark = OsuColour.FromHex(@"04222b"), - ColourLight = OsuColour.FromHex(@"052933"), + ColourDark = Color4Extensions.FromHex(@"04222b"), + ColourLight = Color4Extensions.FromHex(@"052933"), }, innerSpin = new Sprite { diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 466c953151..e9b3598625 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -63,10 +63,10 @@ namespace osu.Game.Overlays.Mods public ModSelectOverlay() { - Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2"); - Waves.SecondWaveColour = OsuColour.FromHex(@"2280a2"); - Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); - Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); + Waves.FirstWaveColour = Color4Extensions.FromHex(@"19b0e2"); + Waves.SecondWaveColour = Color4Extensions.FromHex(@"2280a2"); + Waves.ThirdWaveColour = Color4Extensions.FromHex(@"005774"); + Waves.FourthWaveColour = Color4Extensions.FromHex(@"003a4e"); RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 6ed4fc3187..2cc1f6533f 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -170,7 +171,7 @@ namespace osu.Game.Overlays.Profile.Header userCountryText.Text = user?.Country?.FullName ?? "Alien"; supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; - titleText.Colour = OsuColour.FromHex(user?.Colour ?? "fff"); + titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); userStats.Clear(); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 3e78423a5a..f7c09e33c1 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; @@ -48,7 +47,7 @@ namespace osu.Game.Overlays.Profile new Box { RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(OsuColour.FromHex("222").Opacity(0.8f), OsuColour.FromHex("222").Opacity(0.2f)) + Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("222").Opacity(0.8f), Color4Extensions.FromHex("222").Opacity(0.2f)) }, } }; diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 1c2cb95dfe..93fcc3c401 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -1,16 +1,16 @@ // 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 osuTK.Graphics; using osu.Framework.Graphics; -using osu.Game.Graphics; using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Social { public class FilterControl : SearchableListFilterControl { - protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); + protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"47253a"); protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Rank; protected override SortDirection DefaultCategory => SortDirection.Ascending; diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 22bca9b421..22e0fdcd56 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Framework.Allocation; using System.ComponentModel; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Social @@ -17,7 +18,7 @@ namespace osu.Game.Overlays.Social { private OsuSpriteText browser; - protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e"); + protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"38202e"); protected override SocialTab DefaultTab => SocialTab.AllPlayers; protected override IconUsage Icon => FontAwesome.Solid.Users; diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 54c978738d..50c05e1b54 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -9,7 +9,6 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -18,6 +17,7 @@ using osu.Game.Overlays.Social; using osu.Game.Users; using System.Threading; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Threading; namespace osu.Game.Overlays @@ -27,9 +27,9 @@ namespace osu.Game.Overlays private readonly LoadingSpinner loading; private FillFlowContainer panels; - protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); - protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); - protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); + protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"60284b"); + protected override Color4 TrianglesColourLight => Color4Extensions.FromHex(@"672b51"); + protected override Color4 TrianglesColourDark => Color4Extensions.FromHex(@"5c2648"); protected override SearchableListHeader CreateHeader() => new Header(); protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs index 752615245e..afd9e3d760 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -26,7 +27,7 @@ namespace osu.Game.Screens.Edit.Components.Menus MaskingContainer.CornerRadius = 0; ItemsContainer.Padding = new MarginPadding { Left = 100 }; - BackgroundColour = OsuColour.FromHex("111"); + BackgroundColour = Color4Extensions.FromHex("111"); ScreenSelectionTabControl tabControl; AddRangeInternal(new Drawable[] diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index 02e5db306d..b99a053859 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -2,11 +2,11 @@ // 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.UserInterface; using osuTK; @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("111") + Colour = Color4Extensions.FromHex("111") }, new GridContainer { @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222") + Colour = Color4Extensions.FromHex("222") }, new FillFlowContainer { @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("333") + Colour = Color4Extensions.FromHex("333") }, new Container { diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index e2dd14b18c..6731fef6f7 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Menu }, } }, - bigRing = new Ring(OsuColour.FromHex(@"B6C5E9"), 0.85f), + bigRing = new Ring(Color4Extensions.FromHex(@"B6C5E9"), 0.85f), mediumRing = new Ring(Color4.White.Opacity(130), 0.7f), smallRing = new Ring(Color4.White, 0.6f), welcomeText = new OsuSpriteText @@ -121,7 +121,7 @@ namespace osu.Game.Screens.Menu Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Height = 0, - Colour = OsuColour.FromHex(@"C6D8FF").Opacity(160), + Colour = Color4Extensions.FromHex(@"C6D8FF").Opacity(160), }, foregroundFill = new Box { @@ -139,28 +139,28 @@ namespace osu.Game.Screens.Menu Anchor = Anchor.Centre, Origin = Anchor.TopCentre, Position = new Vector2(0, circle_offset), - Colour = OsuColour.FromHex(@"AA92FF"), + Colour = Color4Extensions.FromHex(@"AA92FF"), }, blueCircle = new Circle { Anchor = Anchor.Centre, Origin = Anchor.CentreRight, Position = new Vector2(-circle_offset, 0), - Colour = OsuColour.FromHex(@"8FE5FE"), + Colour = Color4Extensions.FromHex(@"8FE5FE"), }, yellowCircle = new Circle { Anchor = Anchor.Centre, Origin = Anchor.BottomCentre, Position = new Vector2(0, -circle_offset), - Colour = OsuColour.FromHex(@"FFD64C"), + Colour = Color4Extensions.FromHex(@"FFD64C"), }, pinkCircle = new Circle { Anchor = Anchor.Centre, Origin = Anchor.CentreLeft, Position = new Vector2(circle_offset, 0), - Colour = OsuColour.FromHex(@"e967a1"), + Colour = Color4Extensions.FromHex(@"e967a1"), }, }; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index be2f29cbe9..800520100e 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,7 +15,6 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Input.Events; using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osuTK; @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Menu /// public class OsuLogo : BeatSyncedContainer { - public readonly Color4 OsuPink = OsuColour.FromHex(@"e967a1"); + public readonly Color4 OsuPink = Color4Extensions.FromHex(@"e967a1"); private const double transition_length = 300; @@ -176,8 +176,8 @@ namespace osu.Game.Screens.Menu triangles = new Triangles { TriangleScale = 4, - ColourLight = OsuColour.FromHex(@"ff7db7"), - ColourDark = OsuColour.FromHex(@"de5b95"), + ColourLight = Color4Extensions.FromHex(@"ff7db7"), + ColourDark = Color4Extensions.FromHex(@"de5b95"), RelativeSizeAxes = Axes.Both, }, } diff --git a/osu.Game/Screens/Multi/Components/DrawableGameType.cs b/osu.Game/Screens/Multi/Components/DrawableGameType.cs index f4941dd73a..28240f0796 100644 --- a/osu.Game/Screens/Multi/Components/DrawableGameType.cs +++ b/osu.Game/Screens/Multi/Components/DrawableGameType.cs @@ -2,6 +2,7 @@ // 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.Cursor; @@ -27,7 +28,7 @@ namespace osu.Game.Screens.Multi.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"545454"), + Colour = Color4Extensions.FromHex(@"545454"), }, }; } diff --git a/osu.Game/Screens/Multi/Components/ParticipantsList.cs b/osu.Game/Screens/Multi/Components/ParticipantsList.cs index 5a2dc19b66..79d130adf5 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantsList.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantsList.cs @@ -2,12 +2,12 @@ // 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.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Threading; -using osu.Game.Graphics; using osu.Game.Users; using osu.Game.Users.Drawables; using osuTK; @@ -114,7 +114,7 @@ namespace osu.Game.Screens.Multi.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"27252d"), + Colour = Color4Extensions.FromHex(@"27252d"), }, avatar = new UpdateableAvatar { RelativeSizeAxes = Axes.Both }, }; diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 1cbf2a45e7..0a05472ba3 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -2,6 +2,7 @@ // 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; @@ -30,7 +31,7 @@ namespace osu.Game.Screens.Multi new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"2f2043"), + Colour = Color4Extensions.FromHex(@"2f2043"), }, new Container { diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index d45dac1ae6..de02d779e1 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -134,7 +134,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"212121"), + Colour = Color4Extensions.FromHex(@"212121"), }, new StatusColouredContainer(transition_duration) { diff --git a/osu.Game/Screens/Multi/Match/Components/Footer.cs b/osu.Game/Screens/Multi/Match/Components/Footer.cs index c0c866d815..94d7df6194 100644 --- a/osu.Game/Screens/Multi/Match/Components/Footer.cs +++ b/osu.Game/Screens/Multi/Match/Components/Footer.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -44,7 +45,7 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = OsuColour.FromHex(@"28242d"); + background.Colour = Color4Extensions.FromHex(@"28242d"); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 115ac5037a..5d68de9ce6 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Multi.Match.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d"), + Colour = Color4Extensions.FromHex(@"28242d"), }, new GridContainer { @@ -270,7 +270,7 @@ namespace osu.Game.Screens.Multi.Match.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), + Colour = Color4Extensions.FromHex(@"28242d").Darken(0.5f).Opacity(1f), }, new FillFlowContainer { diff --git a/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs b/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs index 8a0369ceba..1d93116d07 100644 --- a/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs @@ -2,7 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Game.Graphics; +using osu.Framework.Extensions.Color4Extensions; using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Multi.Match.Components @@ -12,9 +12,9 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - BackgroundColour = OsuColour.FromHex(@"593790"); - Triangles.ColourLight = OsuColour.FromHex(@"7247b6"); - Triangles.ColourDark = OsuColour.FromHex(@"593790"); + BackgroundColour = Color4Extensions.FromHex(@"593790"); + Triangles.ColourLight = Color4Extensions.FromHex(@"7247b6"); + Triangles.ColourDark = Color4Extensions.FromHex(@"593790"); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs b/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs index 9de4a61cde..7ef39c2a74 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; @@ -52,7 +53,7 @@ namespace osu.Game.Screens.Multi.Match.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"3d3943"), + Colour = Color4Extensions.FromHex(@"3d3943"), }, selection = new Box { diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index b0d773869a..863a28609b 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -13,7 +13,6 @@ using osu.Framework.Logging; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Input; @@ -75,7 +74,7 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both; Padding = new MarginPadding { Horizontal = -HORIZONTAL_OVERFLOW_PADDING }; - var backgroundColour = OsuColour.FromHex(@"3e3a44"); + var backgroundColour = Color4Extensions.FromHex(@"3e3a44"); InternalChild = waves = new MultiplayerWaveContainer { @@ -386,10 +385,10 @@ namespace osu.Game.Screens.Multi public MultiplayerWaveContainer() { - FirstWaveColour = OsuColour.FromHex(@"654d8c"); - SecondWaveColour = OsuColour.FromHex(@"554075"); - ThirdWaveColour = OsuColour.FromHex(@"44325e"); - FourthWaveColour = OsuColour.FromHex(@"392850"); + FirstWaveColour = Color4Extensions.FromHex(@"654d8c"); + SecondWaveColour = Color4Extensions.FromHex(@"554075"); + ThirdWaveColour = Color4Extensions.FromHex(@"44325e"); + FourthWaveColour = Color4Extensions.FromHex(@"392850"); } } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index cf49cf0228..f84aac3081 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -384,7 +384,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"441288"), + Colour = Color4Extensions.FromHex(@"441288"), Icon = FontAwesome.Solid.Square, Rotation = 45, }, @@ -394,7 +394,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Scale = new Vector2(0.8f), - Colour = OsuColour.FromHex(@"f7dd55"), + Colour = Color4Extensions.FromHex(@"f7dd55"), Icon = statistic.Icon, }, } diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 50419a5fb9..841bbf415c 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -69,8 +70,8 @@ namespace osu.Game.Screens.Select.Carousel { TriangleScale = 2, RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"3a7285"), - ColourDark = OsuColour.FromHex(@"123744") + ColourLight = Color4Extensions.FromHex(@"3a7285"), + ColourDark = Color4Extensions.FromHex(@"123744") }, new FillFlowContainer { From 9683c0756d391930d6514e4d3a93ba9021ad623a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Mar 2020 12:56:12 +0900 Subject: [PATCH 58/82] Start path at (0,0) --- osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 5b3a114506..f39395ba44 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -91,10 +91,11 @@ namespace osu.Game.Rulesets.Catch.Tests public TestJuiceStream(float x) { X = x; + Path = new SliderPath(new[] { - new PathControlPoint(new Vector2(x, 0)), - new PathControlPoint(new Vector2(x + 30, 0)), + new PathControlPoint(Vector2.Zero), + new PathControlPoint(new Vector2(30, 0)), }); } } From 638a9a24aa20d9c028dd750ae59b6075f781e93c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 02:35:49 +0900 Subject: [PATCH 59/82] Initial disclaimer updates --- osu.Game/Screens/Menu/Disclaimer.cs | 89 ++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index bcab73715b..2c1b0c3166 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Screens; +using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; @@ -33,6 +34,7 @@ namespace osu.Game.Screens.Menu private readonly OsuScreen nextScreen; private readonly Bindable currentUser = new Bindable(); + private FillFlowContainer fill; public Disclaimer(OsuScreen nextScreen = null) { @@ -49,16 +51,16 @@ namespace osu.Game.Screens.Menu { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.Solid.ExclamationTriangle, + Icon = FontAwesome.Solid.Poo, Size = new Vector2(icon_size), Y = icon_y, }, - new FillFlowContainer + fill = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Y = icon_y + icon_size, + Y = icon_y, Anchor = Anchor.Centre, Origin = Anchor.TopCentre, Children = new Drawable[] @@ -71,6 +73,8 @@ namespace osu.Game.Screens.Menu Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Spacing = new Vector2(0, 2), + LayoutDuration = 2000, + LayoutEasing = Easing.OutQuint }, supportFlow = new LinkFlowContainer { @@ -86,23 +90,16 @@ namespace osu.Game.Screens.Menu } }; - textFlow.AddText("This is an ", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.Light)); - textFlow.AddText("early development build", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.SemiBold)); + textFlow.AddText("This project is an ongoing ", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.Light)); + textFlow.AddText("work in progress", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.SemiBold)); - textFlow.AddParagraph("Things may not work as expected", t => t.Font = t.Font.With(size: 20)); textFlow.NewParagraph(); static void format(SpriteText t) => t.Font = OsuFont.GetFont(size: 15, weight: FontWeight.SemiBold); - textFlow.AddParagraph("Detailed bug reports are welcomed via github issues.", format); + textFlow.AddParagraph(getRandomTip(), t => t.Font = t.Font.With(Typeface.Exo, 20, FontWeight.SemiBold)); textFlow.NewParagraph(); - textFlow.AddText("Visit ", format); - textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy", creationParameters: format); - textFlow.AddText(" to help out or follow progress!", format); - - textFlow.NewParagraph(); - textFlow.NewParagraph(); textFlow.NewParagraph(); iconColour = colours.Yellow; @@ -114,7 +111,7 @@ namespace osu.Game.Screens.Menu if (e.NewValue.IsSupporter) { - supportFlow.AddText("Thank you for supporting osu!", format); + supportFlow.AddText("Eternal thanks to you for supporting osu!", format); } else { @@ -125,7 +122,7 @@ namespace osu.Game.Screens.Menu heart = supportFlow.AddIcon(FontAwesome.Solid.Heart, t => { - t.Padding = new MarginPadding { Left = 5 }; + t.Padding = new MarginPadding { Left = 5, Top = 3 }; t.Font = t.Font.With(size: 12); t.Origin = Anchor.Centre; t.Colour = colours.Pink; @@ -139,11 +136,6 @@ namespace osu.Game.Screens.Menu }, true); } - private void animateHeart() - { - heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop(); - } - protected override void LoadComplete() { base.LoadComplete(); @@ -155,15 +147,28 @@ namespace osu.Game.Screens.Menu { base.OnEntering(last); - icon.Delay(1000).FadeColour(iconColour, 200, Easing.OutQuint); - icon.Delay(1000) - .MoveToY(icon_y * 1.1f, 160, Easing.OutCirc) - .RotateTo(-10, 160, Easing.OutCirc) - .Then() - .MoveToY(icon_y, 160, Easing.InCirc) - .RotateTo(0, 160, Easing.InCirc); + icon.RotateTo(10); + icon.FadeOut(); + icon.ScaleTo(0.5f); + + icon.Delay(500).FadeIn(500).ScaleTo(1, 500, Easing.OutQuint); + + using (BeginDelayedSequence(3000, true)) + { + icon.FadeColour(iconColour, 200, Easing.OutQuint); + icon.MoveToY(icon_y * 1.3f, 500, Easing.OutCirc) + .RotateTo(-360, 520, Easing.OutQuint) + .Then() + .MoveToY(icon_y, 160, Easing.InQuart) + .FadeColour(Color4.White, 160); + + fill.Delay(520 + 160).MoveToOffset(new Vector2(0, 15), 160, Easing.OutQuart); + } supportFlow.FadeOut().Delay(2000).FadeIn(500); + double delay = 500; + foreach (var c in textFlow.Children) + c.FadeTo(0.001f).Delay(delay += 20).FadeIn(500); animateHeart(); @@ -178,5 +183,35 @@ namespace osu.Game.Screens.Menu this.Push(nextScreen); }); } + + private string getRandomTip() + { + string[] tips = + { + "You can press Ctrl-T anywhere in the game to toggle the toolbar!", + "You can press Ctrl-O anywhere in the game to access options!", + "All settings are dynamic and take effect in real-time. Try changing the skin while playing!", + "New features are coming online every update. Make sure to stay up-to-date!", + "If you find the UI too large or small, try adjusting UI scale in settings!", + "Try adjusting the \"Screen Scaling\" mode to change your gameplay or UI area, even in fullscreen!", + "For now, osu!direct is available to all users on lazer. You can access it anywhere using Ctrl-D!", + "Seeking in replays is available by dragging on the difficulty bar at the bottom of the screen!", + "Multithreading support means that even with low \"FPS\" your input and judgements will be accurate!", + "Try scrolling down in the mod select panel to find a bunch of new fun mods!", + "Most of the web content (profiles, rankings, etc.) are available natively in-game from the icons on the toolbar!", + "Get more details, hide or delete a beatmap by right-clicking on its panel at song select!", + "All delete operations are temoprary until quit. Restore accidentally deleted content from the maintenance settings!", + "Check out the \"timeshift\" multiplayer system, which has local permanent leaderboards and playlist support!", + "Toggle advanced frame / thread statistics with Ctrl-F11!", + "Take a look under the hood at performance counters and enable verbose performance logging with Ctrl-F2!", + }; + + return tips[RNG.Next(0, tips.Length)]; + } + + private void animateHeart() + { + heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop(); + } } } From 93aec4e6920759e76c00f10ad322b3fd6ff8cf27 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 13:23:26 +0900 Subject: [PATCH 60/82] Improve english Co-Authored-By: Dan Balasescu --- osu.Game/Screens/Menu/Disclaimer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 2c1b0c3166..ee8200321b 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -200,7 +200,7 @@ namespace osu.Game.Screens.Menu "Try scrolling down in the mod select panel to find a bunch of new fun mods!", "Most of the web content (profiles, rankings, etc.) are available natively in-game from the icons on the toolbar!", "Get more details, hide or delete a beatmap by right-clicking on its panel at song select!", - "All delete operations are temoprary until quit. Restore accidentally deleted content from the maintenance settings!", + "All delete operations are temporary until exiting. Restore accidentally deleted content from the maintenance settings!", "Check out the \"timeshift\" multiplayer system, which has local permanent leaderboards and playlist support!", "Toggle advanced frame / thread statistics with Ctrl-F11!", "Take a look under the hood at performance counters and enable verbose performance logging with Ctrl-F2!", From 401429feeccbcb92818cfd31f5020ffdf3070abe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 15:52:18 +0900 Subject: [PATCH 61/82] Revert changes to ScrenTestScene --- osu.Game/Tests/Visual/ScreenTestScene.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs index 1a6ebed425..d26aacf2bc 100644 --- a/osu.Game/Tests/Visual/ScreenTestScene.cs +++ b/osu.Game/Tests/Visual/ScreenTestScene.cs @@ -38,11 +38,12 @@ namespace osu.Game.Tests.Visual private void addExitAllScreensStep() { - AddStep("exit all screens", () => + AddUntilStep("exit all screens", () => { - if (Stack.CurrentScreen == null) return; + if (Stack.CurrentScreen == null) return true; Stack.Exit(); + return false; }); } } From 966e5bbc8aa441cecde5fa54fce6f659015b6392 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Mar 2020 15:54:03 +0900 Subject: [PATCH 62/82] User helper function to reduce copy paste --- .../Objects/Drawables/DrawableBanana.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index 2e7618b8df..01b76ceed9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -33,10 +33,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables ScaleContainer.ScaleTo(HitObject.Scale * (end_scale + random_scale_range * RNG.NextSingle())) .Then().ScaleTo(HitObject.Scale * end_scale, HitObject.TimePreempt); - const float random_angle_range = 180; + ScaleContainer.RotateTo(getRandomAngle()) + .Then() + .RotateTo(getRandomAngle(), HitObject.TimePreempt); - ScaleContainer.RotateTo(random_angle_range * (RNG.NextSingle() * 2 - 1)) - .Then().RotateTo(random_angle_range * (RNG.NextSingle() * 2 - 1), HitObject.TimePreempt); + float getRandomAngle() => 180 * (RNG.NextSingle() * 2 - 1); } private Color4 getBananaColour() From 8eb8572c738b549be8915ea809a7ad20d600e307 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Mar 2020 18:00:39 +0900 Subject: [PATCH 63/82] Apply osu!-side video sprite changes --- osu.Game.Tournament/Components/TourneyVideo.cs | 2 +- osu.Game/Screens/Menu/IntroTriangles.cs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs index 43088d6b92..81620b017c 100644 --- a/osu.Game.Tournament/Components/TourneyVideo.cs +++ b/osu.Game.Tournament/Components/TourneyVideo.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tournament.Components if (stream != null) { - InternalChild = video = new VideoSprite(stream) + InternalChild = video = new VideoSprite(stream, false) { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 4e51ff939a..be5762e68d 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -259,11 +259,18 @@ namespace osu.Game.Screens.Menu private class LazerLogo : CompositeDrawable { + private readonly Stream videoStream; + public LazerLogo(Stream videoStream) { + this.videoStream = videoStream; Size = new Vector2(960); + } - InternalChild = new VideoSprite(videoStream) + [BackgroundDependencyLoader] + private void load() + { + InternalChild = new VideoSprite(videoStream, false) { RelativeSizeAxes = Axes.Both, Clock = new FramedOffsetClock(Clock) { Offset = -logo_1 } From 5b03b3e36304b1546c671aa875ce3d97bec79ced Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Mar 2020 18:36:37 +0900 Subject: [PATCH 64/82] Fix hyperdashes not recalculated with HR application --- .../Beatmaps/CatchBeatmapProcessor.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 1a5d0f983b..e0c65a8317 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -28,8 +28,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps ApplyPositionOffsets(Beatmap); - initialiseHyperDash((List)Beatmap.HitObjects); - int index = 0; foreach (var obj in Beatmap.HitObjects.OfType()) @@ -90,6 +88,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps break; } } + + initialiseHyperDash(beatmap); } private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng) @@ -191,14 +191,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } - private void initialiseHyperDash(List objects) + private static void initialiseHyperDash(IBeatmap beatmap) { List objectWithDroplets = new List(); - foreach (var currentObject in objects) + foreach (var currentObject in beatmap.HitObjects) { - if (currentObject is Fruit) - objectWithDroplets.Add(currentObject); + if (currentObject is Fruit fruitObject) + objectWithDroplets.Add(fruitObject); if (currentObject is JuiceStream) { @@ -212,7 +212,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps objectWithDroplets.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); - double halfCatcherWidth = CatcherArea.GetCatcherSize(Beatmap.BeatmapInfo.BaseDifficulty) / 2; + double halfCatcherWidth = CatcherArea.GetCatcherSize(beatmap.BeatmapInfo.BaseDifficulty) / 2; int lastDirection = 0; double lastExcess = halfCatcherWidth; @@ -221,6 +221,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps CatchHitObject currentObject = objectWithDroplets[i]; CatchHitObject nextObject = objectWithDroplets[i + 1]; + // Reset variables in-case values have changed (e.g. after applying HR) + currentObject.HyperDashTarget = null; + currentObject.DistanceToHyperDash = 0; + int thisDirection = nextObject.X > currentObject.X ? 1 : -1; double timeToNext = nextObject.StartTime - currentObject.StartTime - 1000f / 60f / 4; // 1/4th of a frame of grace time, taken from osu-stable double distanceToNext = Math.Abs(nextObject.X - currentObject.X) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth); From f8e7579f4574aee46ae278fe853e43864d047710 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Mar 2020 18:37:58 +0900 Subject: [PATCH 65/82] Fix juice stream position reset not ever being applied --- .../Beatmaps/CatchBeatmapProcessor.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index e0c65a8317..e76e95e9aa 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -74,6 +74,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps break; case JuiceStream juiceStream: + // Todo: BUG!! Stable used the last control point as the final position of the path, but it should use the computed path instead. + lastPosition = juiceStream.X + juiceStream.Path.ControlPoints[^1].Position.Value.X / CatchPlayfield.BASE_WIDTH; + + // Todo: BUG!! Stable attempted to use the end time of the stream, but referenced it too early in execution and used the start time instead. + lastStartTime = juiceStream.StartTime; + foreach (var nested in juiceStream.NestedHitObjects) { var catchObject = (CatchHitObject)nested; @@ -94,13 +100,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng) { - if (hitObject is JuiceStream stream) - { - lastPosition = stream.EndX; - lastStartTime = stream.EndTime; - return; - } - if (!(hitObject is Fruit)) return; From 919410c6277644329b96a6724a5045b6a94072ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Mar 2020 18:39:47 +0900 Subject: [PATCH 66/82] Remove always-false condition --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index e76e95e9aa..5f23bf1428 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -100,9 +100,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng) { - if (!(hitObject is Fruit)) - return; - float offsetPosition = hitObject.X; double startTime = hitObject.StartTime; From 5c051027e707db7fea7bf6a11b121249d44afd70 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Mar 2020 18:43:08 +0900 Subject: [PATCH 67/82] Fix different offset being applied from stable --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 5f23bf1428..986dc9dbb9 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -112,7 +112,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } float positionDiff = offsetPosition - lastPosition.Value; - double timeDiff = startTime - lastStartTime; + + // Todo: BUG!! Stable calculated time deltas as ints, which affects randomisation. This should be changed to a double. + int timeDiff = (int)(startTime - lastStartTime); if (timeDiff > 1000) { @@ -128,7 +130,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps return; } - if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d) + // ReSharper disable once PossibleLossOfFraction + if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3) applyOffset(ref offsetPosition, positionDiff); hitObject.XOffset = offsetPosition - hitObject.X; From 2866d626531f678e07c81b44ab27d7fecae95d87 Mon Sep 17 00:00:00 2001 From: Olle Kelderman Date: Wed, 11 Mar 2020 16:17:28 +0100 Subject: [PATCH 68/82] Use environment variable for initializing osuInstallPath --- osu.Game.Tournament/IPC/FileBasedIPC.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index b19f2bedf0..eefa9fcfe6 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -163,12 +163,7 @@ namespace osu.Game.Tournament.IPC { try { - stableInstallPath = "G:\\My Drive\\Main\\osu!tourney"; - - if (checkExists(stableInstallPath)) - return stableInstallPath; - - stableInstallPath = "G:\\My Drive\\Main\\osu!mappool"; + stableInstallPath = Environment.GetEnvironmentVariable("OSU_STABLE_PATH"); if (checkExists(stableInstallPath)) return stableInstallPath; From efceeba0769999db723bb74d0f0a2b5c143270c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 02:22:02 +0900 Subject: [PATCH 69/82] Use fixed width for tournament score displays --- .../Screens/Gameplay/Components/MatchScoreDisplay.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs index ed14956793..2e7484542a 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchScoreDisplay.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Tournament.IPC; using osu.Game.Tournament.Models; +using osuTK; namespace osu.Game.Tournament.Screens.Gameplay.Components { @@ -131,13 +132,15 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components Margin = new MarginPadding { Top = bar_height, Horizontal = 10 }; Winning = false; + + DisplayedCountSpriteText.Spacing = new Vector2(-6); } public bool Winning { set => DisplayedCountSpriteText.Font = value - ? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50) - : OsuFont.Torus.With(weight: FontWeight.Regular, size: 40); + ? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50, fixedWidth: true) + : OsuFont.Torus.With(weight: FontWeight.Regular, size: 40, fixedWidth: true); } } } From 09b9983286d5a1a7f960ed968f33a2b3bc139c67 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 11 Mar 2020 21:14:07 +0300 Subject: [PATCH 70/82] Fix CatcherAnimationState is Fail if missing banana shower --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 9ee94636f1..d18f5e165f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -345,7 +345,10 @@ namespace osu.Game.Rulesets.Catch.UI if (validCatch) updateState(fruit.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle); else - updateState(CatcherAnimationState.Fail); + { + if (!(fruit is Banana)) + updateState(CatcherAnimationState.Fail); + } return validCatch; } From e46c070d951341370f16733da1d63c33c0f116c6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 11 Mar 2020 23:09:29 +0300 Subject: [PATCH 71/82] Add test scene --- .../TestSceneDrawableHitObjects.cs | 53 +++++++++++++++---- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 10 ++-- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 070847c0c1..304c7e3854 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; +using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -34,8 +34,8 @@ namespace osu.Game.Rulesets.Catch.Tests private DrawableCatchRuleset drawableRuleset; private double playfieldTime => drawableRuleset.Playfield.Time.Current; - [BackgroundDependencyLoader] - private void load() + [SetUp] + public void Setup() => Schedule(() => { var controlPointInfo = new ControlPointInfo(); controlPointInfo.Add(0, new TimingControlPoint()); @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Catch.Tests ControlPointInfo = controlPointInfo }); - Add(new Container + Child = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -66,16 +66,49 @@ namespace osu.Game.Rulesets.Catch.Tests { drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap.GetPlayableBeatmap(new CatchRuleset().RulesetInfo)) } - }); + }; + }); + + [Test] + public void TestFruits() + { + AddStep("hit fruits", () => spawnFruits(true)); + AddUntilStep("wait for completion", () => playfieldIsEmpty); + AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle); AddStep("miss fruits", () => spawnFruits()); - AddStep("hit fruits", () => spawnFruits(true)); - AddStep("miss juicestream", () => spawnJuiceStream()); - AddStep("hit juicestream", () => spawnJuiceStream(true)); - AddStep("miss bananas", () => spawnBananas()); - AddStep("hit bananas", () => spawnBananas(true)); + AddUntilStep("wait for completion", () => playfieldIsEmpty); + AddAssert("catcher state is failed", () => catcherState == CatcherAnimationState.Fail); } + [Test] + public void TestJuicestream() + { + AddStep("hit juicestream", () => spawnJuiceStream(true)); + AddUntilStep("wait for completion", () => playfieldIsEmpty); + AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle); + + AddStep("miss juicestream", () => spawnJuiceStream()); + AddUntilStep("wait for completion", () => playfieldIsEmpty); + AddAssert("catcher state is failed", () => catcherState == CatcherAnimationState.Fail); + } + + [Test] + public void TestBananas() + { + AddStep("hit bananas", () => spawnBananas(true)); + AddUntilStep("wait for completion", () => playfieldIsEmpty); + AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle); + + AddStep("miss bananas", () => spawnBananas()); + AddUntilStep("wait for completion", () => playfieldIsEmpty); + AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle); + } + + private bool playfieldIsEmpty => !((CatchPlayfield)drawableRuleset.Playfield).AllHitObjects.Any(h => h.IsAlive); + + private CatcherAnimationState catcherState => ((CatchPlayfield)drawableRuleset.Playfield).CatcherArea.MovableCatcher.CurrentState; + private void spawnFruits(bool hit = false) { for (int i = 1; i <= 4; i++) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index d18f5e165f..441f9126f6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Catch.UI CatcherSprite current; - switch (currentState) + switch (CurrentState) { default: current = catcherIdle; @@ -274,7 +274,7 @@ namespace osu.Game.Rulesets.Catch.UI return additive; } - private Drawable createCatcherSprite() => new CatcherSprite(currentState); + private Drawable createCatcherSprite() => new CatcherSprite(CurrentState); /// /// Add a caught fruit to the catcher's stack. @@ -355,14 +355,14 @@ namespace osu.Game.Rulesets.Catch.UI private void updateState(CatcherAnimationState state) { - if (currentState == state) + if (CurrentState == state) return; - currentState = state; + CurrentState = state; updateCatcher(); } - private CatcherAnimationState currentState; + public CatcherAnimationState CurrentState; private double hyperDashModifier = 1; private int hyperDashDirection; From fd21e87670ebde3018e43a550aff6ef9b30383f9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 11:28:45 +0900 Subject: [PATCH 72/82] Disable adjusting volume via "select next" and "select previous" as fallbacks --- .../Overlays/Volume/VolumeControlReceptor.cs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 4bff8146b4..3478f18a40 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -14,22 +14,8 @@ namespace osu.Game.Overlays.Volume public Func ActionRequested; public Func ScrollActionRequested; - public bool OnPressed(GlobalAction action) - { - // if nothing else handles selection actions in the game, it's safe to let volume be adjusted. - switch (action) - { - case GlobalAction.SelectPrevious: - action = GlobalAction.IncreaseVolume; - break; - - case GlobalAction.SelectNext: - action = GlobalAction.DecreaseVolume; - break; - } - - return ActionRequested?.Invoke(action) ?? false; - } + public bool OnPressed(GlobalAction action) => + ActionRequested?.Invoke(action) ?? false; public bool OnScroll(GlobalAction action, float amount, bool isPrecise) => ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false; From 39bb98bfb219a2c174c1193850ce500eb0b5aeba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 13:26:58 +0900 Subject: [PATCH 73/82] Allow videos to be loaded with any extension Also moves all tournament user resources to a "tournament" subfolder. --- .../Components/TourneyVideo.cs | 5 ++--- osu.Game.Tournament/TournamentGameBase.cs | 6 +++++- osu.Game.Tournament/TournamentStorage.cs | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Tournament/TournamentStorage.cs diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs index 43088d6b92..d8488ce4f6 100644 --- a/osu.Game.Tournament/Components/TourneyVideo.cs +++ b/osu.Game.Tournament/Components/TourneyVideo.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Video; -using osu.Framework.Platform; using osu.Framework.Timing; using osu.Game.Graphics; @@ -28,9 +27,9 @@ namespace osu.Game.Tournament.Components } [BackgroundDependencyLoader] - private void load(Storage storage) + private void load(TournamentStorage storage) { - var stream = storage.GetStream($@"videos/{filename}.m4v"); + var stream = storage.GetStream($@"videos/{filename}"); if (stream != null) { diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 41165ca141..41822ae2c3 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -37,6 +37,8 @@ namespace osu.Game.Tournament private Storage storage; + private TournamentStorage tournamentStorage; + private DependencyContainer dependencies; private Bindable windowSize; @@ -54,7 +56,9 @@ namespace osu.Game.Tournament { Resources.AddStore(new DllResourceStore(typeof(TournamentGameBase).Assembly)); - Textures.AddStore(new TextureLoaderStore(new ResourceStore(new StorageBackedResourceStore(storage)))); + dependencies.CacheAs(tournamentStorage = new TournamentStorage(storage)); + + Textures.AddStore(new TextureLoaderStore(tournamentStorage)); this.storage = storage; diff --git a/osu.Game.Tournament/TournamentStorage.cs b/osu.Game.Tournament/TournamentStorage.cs new file mode 100644 index 0000000000..139ad3857b --- /dev/null +++ b/osu.Game.Tournament/TournamentStorage.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.Framework.IO.Stores; +using osu.Framework.Platform; + +namespace osu.Game.Tournament +{ + internal class TournamentStorage : NamespacedResourceStore + { + public TournamentStorage(Storage storage) + : base(new StorageBackedResourceStore(storage), "tournament") + { + AddExtension("m4v"); + AddExtension("avi"); + AddExtension("mp4"); + } + } +} From 190ff974862e9e379917eeccd40034c546448980 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 13:29:09 +0900 Subject: [PATCH 74/82] Rename classes to better suit purpose --- .../Components/DrawableTournamentHeaderLogo.cs | 18 ++++++++++++++++++ .../Components/DrawableTournamentHeaderText.cs | 18 ++++++++++++++++++ .../Components/DrawableTournamentTitleText.cs | 16 ---------------- osu.Game.Tournament/Components/RoundDisplay.cs | 2 +- .../Screens/Gameplay/Components/MatchHeader.cs | 4 ++-- .../{RoundDisplay.cs => MatchRoundDisplay.cs} | 2 +- .../Screens/Ladder/LadderScreen.cs | 2 +- .../Screens/Schedule/ScheduleScreen.cs | 2 +- 8 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs create mode 100644 osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs delete mode 100644 osu.Game.Tournament/Components/DrawableTournamentTitleText.cs rename osu.Game.Tournament/Screens/Gameplay/Components/{RoundDisplay.cs => MatchRoundDisplay.cs} (92%) diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs new file mode 100644 index 0000000000..b6f74a75e7 --- /dev/null +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs @@ -0,0 +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 osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Tournament.Components +{ + public class DrawableTournamentHeaderLogo : Sprite + { + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Texture = textures.Get("header-text"); + } + } +} diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs new file mode 100644 index 0000000000..38500fa857 --- /dev/null +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs @@ -0,0 +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 osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Tournament.Components +{ + public class DrawableTournamentHeaderText : Sprite + { + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Texture = textures.Get("header-text"); + } + } +} diff --git a/osu.Game.Tournament/Components/DrawableTournamentTitleText.cs b/osu.Game.Tournament/Components/DrawableTournamentTitleText.cs deleted file mode 100644 index 4fbc6cd060..0000000000 --- a/osu.Game.Tournament/Components/DrawableTournamentTitleText.cs +++ /dev/null @@ -1,16 +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.Game.Graphics; - -namespace osu.Game.Tournament.Components -{ - public class DrawableTournamentTitleText : TournamentSpriteText - { - public DrawableTournamentTitleText() - { - Text = "osu!taiko world cup 2020"; - Font = OsuFont.Torus.With(size: 26, weight: FontWeight.SemiBold); - } - } -} diff --git a/osu.Game.Tournament/Components/RoundDisplay.cs b/osu.Game.Tournament/Components/RoundDisplay.cs index dd56c83c57..bebede6782 100644 --- a/osu.Game.Tournament/Components/RoundDisplay.cs +++ b/osu.Game.Tournament/Components/RoundDisplay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Tournament.Components Direction = FillDirection.Vertical, Children = new Drawable[] { - new DrawableTournamentTitleText(), + new DrawableTournamentHeaderText(), new TournamentSpriteText { Text = match.Round.Value?.Name.Value ?? "Unknown Round", diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs index 69a68c946b..aa4bd4a701 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs @@ -41,13 +41,13 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components Spacing = new Vector2(5), Children = new Drawable[] { - new DrawableTournamentTitleText + new DrawableTournamentHeaderText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Scale = new Vector2(1.2f) }, - new RoundDisplay + new MatchRoundDisplay { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/RoundDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs similarity index 92% rename from osu.Game.Tournament/Screens/Gameplay/Components/RoundDisplay.cs rename to osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs index c8b0d3bdda..87793f7e1b 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/RoundDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Gameplay.Components { - public class RoundDisplay : TournamentSpriteTextWithBackground + public class MatchRoundDisplay : TournamentSpriteTextWithBackground { private readonly Bindable currentMatch = new Bindable(); diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 6f62b3ddba..534c402f6c 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -47,7 +47,7 @@ namespace osu.Game.Tournament.Screens.Ladder RelativeSizeAxes = Axes.Both, Loop = true, }, - new DrawableTournamentTitleText + new DrawableTournamentHeaderText { Y = 100, Anchor = Anchor.TopCentre, diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs index 0fcec645e3..88289ad6bd 100644 --- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs +++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs @@ -62,7 +62,7 @@ namespace osu.Game.Tournament.Screens.Schedule Direction = FillDirection.Vertical, Children = new Drawable[] { - new DrawableTournamentTitleText(), + new DrawableTournamentHeaderText(), new Container { Margin = new MarginPadding { Top = 40 }, From b6b802e8212f44a669675f6705fd16db667fd758 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 14:06:40 +0900 Subject: [PATCH 75/82] Add back customisable header logo/text Also adds test scene for MatchHeader component. --- .../Components/TestSceneMatchHeader.cs | 33 +++++ .../DrawableTournamentHeaderLogo.cs | 27 +++- .../DrawableTournamentHeaderText.cs | 27 +++- .../Gameplay/Components/MatchHeader.cs | 119 +++++++----------- .../Gameplay/Components/TeamScoreDisplay.cs | 83 ++++++++++++ 5 files changed, 206 insertions(+), 83 deletions(-) create mode 100644 osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs create mode 100644 osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs diff --git a/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs b/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs new file mode 100644 index 0000000000..b29e4964b6 --- /dev/null +++ b/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Tournament.Screens.Gameplay.Components; +using osuTK; + +namespace osu.Game.Tournament.Tests.Components +{ + public class TestSceneMatchHeader : TournamentTestScene + { + public TestSceneMatchHeader() + { + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(50), + Children = new Drawable[] + { + new TournamentSpriteText { Text = "with logo", Font = OsuFont.Torus.With(size: 30) }, + new MatchHeader(), + new TournamentSpriteText { Text = "without logo", Font = OsuFont.Torus.With(size: 30) }, + new MatchHeader { ShowLogo = false }, + new TournamentSpriteText { Text = "without scores", Font = OsuFont.Torus.With(size: 30) }, + new MatchHeader { ShowScores = false }, + } + }; + } + } +} diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs index b6f74a75e7..a61cb59fed 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs @@ -2,17 +2,36 @@ // 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.Sprites; using osu.Framework.Graphics.Textures; namespace osu.Game.Tournament.Components { - public class DrawableTournamentHeaderLogo : Sprite + public class DrawableTournamentHeaderLogo : CompositeDrawable { - [BackgroundDependencyLoader] - private void load(TextureStore textures) + public DrawableTournamentHeaderLogo() { - Texture = textures.Get("header-text"); + InternalChild = new LogoSprite(); + + Height = 50; + RelativeSizeAxes = Axes.X; + } + + private class LogoSprite : Sprite + { + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fit; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Texture = textures.Get("header-logo"); + } } } } diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs index 38500fa857..2539075c0f 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs @@ -2,17 +2,36 @@ // 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.Sprites; using osu.Framework.Graphics.Textures; namespace osu.Game.Tournament.Components { - public class DrawableTournamentHeaderText : Sprite + public class DrawableTournamentHeaderText : CompositeDrawable { - [BackgroundDependencyLoader] - private void load(TextureStore textures) + public DrawableTournamentHeaderText() { - Texture = textures.Get("header-text"); + InternalChild = new TextSprite(); + + Height = 25; + RelativeSizeAxes = Axes.X; + } + + private class TextSprite : Sprite + { + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fit; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Texture = textures.Get("header-text"); + } } } } diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs index aa4bd4a701..751a763333 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs @@ -2,14 +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.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Events; using osu.Game.Tournament.Components; using osu.Game.Tournament.Models; using osuTK; -using osuTK.Input; namespace osu.Game.Tournament.Screens.Gameplay.Components { @@ -17,13 +14,39 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components { private TeamScoreDisplay teamDisplay1; private TeamScoreDisplay teamDisplay2; + private DrawableTournamentHeaderLogo logo; + + private bool showScores = true; public bool ShowScores { + get => showScores; set { - teamDisplay1.ShowScore = value; - teamDisplay2.ShowScore = value; + if (value == showScores) + return; + + showScores = value; + + if (IsLoaded) + updateDisplay(); + } + } + + private bool showLogo = true; + + public bool ShowLogo + { + get => showLogo; + set + { + if (value == showLogo) + return; + + showLogo = value; + + if (IsLoaded) + updateDisplay(); } } @@ -38,19 +61,25 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components { RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, + Padding = new MarginPadding(5), Spacing = new Vector2(5), Children = new Drawable[] { + logo = new DrawableTournamentHeaderLogo + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Alpha = showLogo ? 1 : 0 + }, new DrawableTournamentHeaderText { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(1.2f) + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, }, new MatchRoundDisplay { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, Scale = new Vector2(0.4f) }, } @@ -66,76 +95,16 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components Origin = Anchor.TopRight, }, }; - } - } - public class TeamScoreDisplay : CompositeDrawable - { - private readonly TeamColour teamColour; - - private readonly Bindable currentMatch = new Bindable(); - private readonly Bindable currentTeam = new Bindable(); - private readonly Bindable currentTeamScore = new Bindable(); - - private TeamDisplay teamDisplay; - - public bool ShowScore { set => teamDisplay.ShowScore = value; } - - public TeamScoreDisplay(TeamColour teamColour) - { - this.teamColour = teamColour; - - RelativeSizeAxes = Axes.Y; - AutoSizeAxes = Axes.X; + updateDisplay(); } - [BackgroundDependencyLoader] - private void load(LadderInfo ladder) + private void updateDisplay() { - currentMatch.BindTo(ladder.CurrentMatch); - currentMatch.BindValueChanged(matchChanged, true); - } + teamDisplay1.ShowScore = showScores; + teamDisplay2.ShowScore = showScores; - private void matchChanged(ValueChangedEvent match) - { - currentTeamScore.UnbindBindings(); - currentTeam.UnbindBindings(); - - if (match.NewValue != null) - { - currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score); - currentTeam.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1 : match.NewValue.Team2); - } - - // team may change to same team, which means score is not in a good state. - // thus we handle this manually. - teamChanged(currentTeam.Value); - } - - protected override bool OnMouseDown(MouseDownEvent e) - { - switch (e.Button) - { - case MouseButton.Left: - if (currentTeamScore.Value < currentMatch.Value.PointsToWin) - currentTeamScore.Value++; - return true; - - case MouseButton.Right: - if (currentTeamScore.Value > 0) - currentTeamScore.Value--; - return true; - } - - return base.OnMouseDown(e); - } - - private void teamChanged(TournamentTeam team) - { - InternalChildren = new Drawable[] - { - teamDisplay = new TeamDisplay(team, teamColour, currentTeamScore, currentMatch.Value?.PointsToWin ?? 0), - }; + logo.Alpha = showLogo ? 1 : 0; } } } diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs new file mode 100644 index 0000000000..462015f004 --- /dev/null +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.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.Input.Events; +using osu.Game.Tournament.Models; +using osuTK.Input; + +namespace osu.Game.Tournament.Screens.Gameplay.Components +{ + public class TeamScoreDisplay : CompositeDrawable + { + private readonly TeamColour teamColour; + + private readonly Bindable currentMatch = new Bindable(); + private readonly Bindable currentTeam = new Bindable(); + private readonly Bindable currentTeamScore = new Bindable(); + + private TeamDisplay teamDisplay; + + public bool ShowScore { set => teamDisplay.ShowScore = value; } + + public TeamScoreDisplay(TeamColour teamColour) + { + this.teamColour = teamColour; + + RelativeSizeAxes = Axes.Y; + AutoSizeAxes = Axes.X; + } + + [BackgroundDependencyLoader] + private void load(LadderInfo ladder) + { + currentMatch.BindTo(ladder.CurrentMatch); + currentMatch.BindValueChanged(matchChanged, true); + } + + private void matchChanged(ValueChangedEvent match) + { + currentTeamScore.UnbindBindings(); + currentTeam.UnbindBindings(); + + if (match.NewValue != null) + { + currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score); + currentTeam.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1 : match.NewValue.Team2); + } + + // team may change to same team, which means score is not in a good state. + // thus we handle this manually. + teamChanged(currentTeam.Value); + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + switch (e.Button) + { + case MouseButton.Left: + if (currentTeamScore.Value < currentMatch.Value.PointsToWin) + currentTeamScore.Value++; + return true; + + case MouseButton.Right: + if (currentTeamScore.Value > 0) + currentTeamScore.Value--; + return true; + } + + return base.OnMouseDown(e); + } + + private void teamChanged(TournamentTeam team) + { + InternalChildren = new Drawable[] + { + teamDisplay = new TeamDisplay(team, teamColour, currentTeamScore, currentMatch.Value?.PointsToWin ?? 0), + }; + } + } +} From 7b1ac03b18dae6767ee4c13be887b33913570f31 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 14:26:22 +0900 Subject: [PATCH 76/82] Hide logo on gameplay screen --- osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index 4d770855cd..8920990d1b 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -47,7 +47,10 @@ namespace osu.Game.Tournament.Screens.Gameplay Loop = true, RelativeSizeAxes = Axes.Both, }, - header = new MatchHeader(), + header = new MatchHeader + { + ShowLogo = false + }, new Container { RelativeSizeAxes = Axes.X, From ec1c6f88ee3889cbe9657e5745a4753255b7cbf2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 14:26:39 +0900 Subject: [PATCH 77/82] Adjust metrics to align logo pieces correctly on gameplay / map pool --- .../Components/TestSceneMatchHeader.cs | 9 +++++++++ .../Components/DrawableTournamentHeaderLogo.cs | 2 +- .../Components/DrawableTournamentHeaderText.cs | 2 +- .../Screens/Gameplay/Components/MatchHeader.cs | 2 +- osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs | 3 ++- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs b/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs index b29e4964b6..9f885ed827 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs @@ -1,9 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Tournament.Components; using osu.Game.Tournament.Screens.Gameplay.Components; using osuTK; @@ -11,6 +14,12 @@ namespace osu.Game.Tournament.Tests.Components { public class TestSceneMatchHeader : TournamentTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DrawableTournamentHeaderText), + typeof(DrawableTournamentHeaderLogo), + }; + public TestSceneMatchHeader() { Child = new FillFlowContainer diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs index a61cb59fed..3f5ab42fd7 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tournament.Components { InternalChild = new LogoSprite(); - Height = 50; + Height = 82; RelativeSizeAxes = Axes.X; } diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs index 2539075c0f..bda696ba00 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tournament.Components { InternalChild = new TextSprite(); - Height = 25; + Height = 22; RelativeSizeAxes = Axes.X; } diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs index 751a763333..d790f4b754 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components { RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Padding = new MarginPadding(5), + Padding = new MarginPadding(20), Spacing = new Vector2(5), Children = new Drawable[] { diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index 4f3f7cfdbf..2b0bfe0b74 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -50,7 +50,7 @@ namespace osu.Game.Tournament.Screens.MapPool new MatchHeader(), mapFlows = new FillFlowContainer> { - Y = 100, + Y = 140, Spacing = new Vector2(10, 10), Padding = new MarginPadding(25), Direction = FillDirection.Vertical, @@ -235,6 +235,7 @@ namespace osu.Game.Tournament.Screens.MapPool { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + Height = 42, }); } } From 28ac5af91c9bc751f66eb634c0fb3b98e76ba5ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 15:26:22 +0900 Subject: [PATCH 78/82] Fix beatmap carousel tests loading beatmap manager beatmaps in test browser --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 71ae47dc66..80e03d82e2 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -497,7 +497,7 @@ namespace osu.Game.Tests.Visual.SongSelect } bool changed = false; - AddStep($"Load {beatmapSets.Count} Beatmaps", () => + AddStep($"Load {(beatmapSets.Count > 0 ? beatmapSets.Count.ToString() : "some")} beatmaps", () => { carousel.Filter(new FilterCriteria()); carousel.BeatmapSetsChanged = () => changed = true; @@ -697,6 +697,8 @@ namespace osu.Game.Tests.Visual.SongSelect public new List Items => base.Items; public bool PendingFilterTask => PendingFilter != null; + + protected override IEnumerable GetLoadableBeatmaps() => Enumerable.Empty(); } } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 71744d8b80..04c08cdbd2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -153,9 +153,11 @@ namespace osu.Game.Screens.Select beatmaps.BeatmapHidden += beatmapHidden; beatmaps.BeatmapRestored += beatmapRestored; - loadBeatmapSets(beatmaps.GetAllUsableBeatmapSetsEnumerable()); + loadBeatmapSets(GetLoadableBeatmaps()); } + protected virtual IEnumerable GetLoadableBeatmaps() => beatmaps.GetAllUsableBeatmapSetsEnumerable(); + public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() => { var existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.ID == beatmapSet.ID); From bc2a1cdb623547e9a05740685eba26f75bd00c76 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Mar 2020 12:04:36 +0300 Subject: [PATCH 79/82] Apply suggestions --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 441f9126f6..2394110165 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -344,11 +344,8 @@ namespace osu.Game.Rulesets.Catch.UI if (validCatch) updateState(fruit.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle); - else - { - if (!(fruit is Banana)) - updateState(CatcherAnimationState.Fail); - } + else if (!(fruit is Banana)) + updateState(CatcherAnimationState.Fail); return validCatch; } @@ -362,7 +359,7 @@ namespace osu.Game.Rulesets.Catch.UI updateCatcher(); } - public CatcherAnimationState CurrentState; + public CatcherAnimationState CurrentState { get; private set; } private double hyperDashModifier = 1; private int hyperDashDirection; From a69fabbd1ff4255c7cad25881b31daa5a48f365e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Mar 2020 18:56:48 +0900 Subject: [PATCH 80/82] 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 6a8e66ee6a..f623a92ade 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index cc1ab654ab..ba6f0e2251 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 04b688cfa3..54cd400d51 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - + From 317bb5d0a436e3f6af94c141beeeec314b8f10cc Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Thu, 12 Mar 2020 03:55:45 -0700 Subject: [PATCH 81/82] Fallback on invalid AnimationFramerate for legacy skins --- osu.Game/Skinning/LegacySkinExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index fa4de21eec..9cc58f4490 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -61,7 +61,7 @@ namespace osu.Game.Skinning { var iniRate = source.GetConfig(GlobalSkinConfiguration.AnimationFramerate); - if (iniRate != null) + if (iniRate != null && iniRate.Value > 0) return 1000f / iniRate.Value; return 1000f / textures.Length; From c8ea92257765d05bba2ae3d7a0f0966625d2aacf Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@users.noreply.github.com> Date: Thu, 12 Mar 2020 04:18:57 -0700 Subject: [PATCH 82/82] Update osu.Game/Skinning/LegacySkinExtensions.cs Co-Authored-By: Dean Herbert --- osu.Game/Skinning/LegacySkinExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 9cc58f4490..52328d43b2 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -61,7 +61,7 @@ namespace osu.Game.Skinning { var iniRate = source.GetConfig(GlobalSkinConfiguration.AnimationFramerate); - if (iniRate != null && iniRate.Value > 0) + if (iniRate?.Value > 0) return 1000f / iniRate.Value; return 1000f / textures.Length;