From 023a5c6e4faef1cd82bde231af6ed481f89d43c8 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Fri, 10 May 2019 19:12:32 +0300 Subject: [PATCH 001/645] Add the ability to ignore the user's mouse movement. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index b9e083d35b..b4cc556ff2 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Osu set => ((OsuKeyBindingContainer)KeyBindingContainer).AllowUserPresses = value; } + public bool AllowUserCursorMovement { get; set; } = true; + protected override RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) => new OsuKeyBindingContainer(ruleset, variant, unique); @@ -26,6 +28,16 @@ namespace osu.Game.Rulesets.Osu { } + protected override bool Handle(UIEvent e) + { + if (!AllowUserCursorMovement && e is MouseMoveEvent) + { + return false; + } + + return base.Handle(e); + } + private class OsuKeyBindingContainer : RulesetKeyBindingContainer { public bool AllowUserPresses = true; From bda0b35d849d15e01cf6ba4cd4ddd97d225e06c2 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Fri, 10 May 2019 19:46:13 +0300 Subject: [PATCH 002/645] Slight formating change. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index b4cc556ff2..58e275ba26 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -30,10 +30,7 @@ namespace osu.Game.Rulesets.Osu protected override bool Handle(UIEvent e) { - if (!AllowUserCursorMovement && e is MouseMoveEvent) - { - return false; - } + if (e is MouseMoveEvent && !AllowUserCursorMovement) return false; return base.Handle(e); } From d229fed1287c3d48878ab7e91981cf123fbd429d Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 14:00:43 +0300 Subject: [PATCH 003/645] Implemented Autopilot --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 401bd28d7c..7c423235fa 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -2,13 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.StateChanges; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModAutopilot : Mod + public class OsuModAutopilot : Mod, IApplicableFailOverride, IUpdatableByPlayfield, IApplicableToDrawableRuleset { public override string Name => "Autopilot"; public override string Acronym => "AP"; @@ -17,5 +23,41 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"Automatic cursor movement - just follow the rhythm."; public override double ScoreMultiplier => 1; public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) }; + + public bool AllowFail => false; + + private OsuInputManager inputManager; + + private List replayFrames; + private int frameIndex = 0; + + public void Update(Playfield playfield) + { + // If we are on the last replay frame, no need to do anything + if (frameIndex == replayFrames.Count - 1) + { + return; + } + + // Check if we are closer to the next replay frame then the current one + if (Math.Abs(replayFrames[frameIndex].Time - playfield.Time.Current) >= Math.Abs(replayFrames[frameIndex + 1].Time - playfield.Time.Current)) + { + // If we are, move to the next frame, and update the mouse position + frameIndex++; + new MousePositionAbsoluteInput() { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); + } + + // TODO: Implement the functionality to automatically spin spinners + } + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + // Grab the input manager to disable the user's cursor, and for future use + inputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager; + inputManager.AllowUserCursorMovement = false; + + // Generate the replay frames the cursor should follow + replayFrames = new OsuAutoGenerator(drawableRuleset.Beatmap).Generate().Frames.Cast().ToList(); + } } } From 2051be7453ad5c201f0d6e11ecb737a68df1866e Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 15:00:59 +0300 Subject: [PATCH 004/645] Minor changes to pass the AppVeyor test --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 7c423235fa..a9b99f3afe 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Mods private OsuInputManager inputManager; private List replayFrames; - private int frameIndex = 0; + private int frameIndex; public void Update(Playfield playfield) { @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Mods { // If we are, move to the next frame, and update the mouse position frameIndex++; - new MousePositionAbsoluteInput() { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); + new MousePositionAbsoluteInput { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); } // TODO: Implement the functionality to automatically spin spinners From dfd7b1111492735a7ecd7aead43163edbee439f6 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 16:04:37 +0300 Subject: [PATCH 005/645] Changed the unimplemented mod test to use OsuModSpunOut instead of OsuModAutopilot since Autopilot is implemented now. --- osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs index fd003c7ea2..7d1242083e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual.UserInterface var doubleTimeMod = harderMods.OfType().FirstOrDefault(m => m.Mods.Any(a => a is OsuModDoubleTime)); - var autoPilotMod = assistMods.FirstOrDefault(m => m is OsuModAutopilot); + var spunOutMod = easierMods.FirstOrDefault(m => m is OsuModSpunOut); var easy = easierMods.FirstOrDefault(m => m is OsuModEasy); var hardRock = harderMods.FirstOrDefault(m => m is OsuModHardRock); @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual.UserInterface testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour); testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour); - testUnimplementedMod(autoPilotMod); + testUnimplementedMod(spunOutMod); } [Test] From fca1b9325d4800edb79f4a24d4c4a82b500046bb Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 16:18:27 +0300 Subject: [PATCH 006/645] Deleted the assistMods variable since it is never used --- osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs index 7d1242083e..4fbb12d6df 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs @@ -83,7 +83,6 @@ namespace osu.Game.Tests.Visual.UserInterface var easierMods = instance.GetModsFor(ModType.DifficultyReduction); var harderMods = instance.GetModsFor(ModType.DifficultyIncrease); - var assistMods = instance.GetModsFor(ModType.Automation); var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden); From 7c50bdd173ce5c7fbd3cd3d1eaa52725eff372e9 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Wed, 15 May 2019 23:48:37 +0300 Subject: [PATCH 007/645] Removed redundant parentheses. --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index a9b99f3afe..1853b0228f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -34,10 +34,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void Update(Playfield playfield) { // If we are on the last replay frame, no need to do anything - if (frameIndex == replayFrames.Count - 1) - { - return; - } + if (frameIndex == replayFrames.Count - 1) return; // Check if we are closer to the next replay frame then the current one if (Math.Abs(replayFrames[frameIndex].Time - playfield.Time.Current) >= Math.Abs(replayFrames[frameIndex + 1].Time - playfield.Time.Current)) From 515534cb34c4433d09224988e54848105e343f99 Mon Sep 17 00:00:00 2001 From: Ganendra Afrasya Date: Sun, 16 Jun 2019 00:02:26 +0700 Subject: [PATCH 008/645] Adding custom tooltip to DifficultyIcon --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 94 ++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 0a0ad28fdf..22a3fd0c8a 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -6,17 +6,20 @@ 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.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class DifficultyIcon : DifficultyColouredContainer + public class DifficultyIcon : DifficultyColouredContainer, IHasCustomTooltip { private readonly RulesetInfo ruleset; @@ -27,10 +30,97 @@ namespace osu.Game.Beatmaps.Drawables throw new ArgumentNullException(nameof(beatmap)); this.ruleset = ruleset ?? beatmap.Ruleset; + TooltipText = $"{beatmap.Version}${beatmap.StarDifficulty.ToString("0.##")}"; Size = new Vector2(20); } + public string TooltipText { get; set; } + + public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(); + + public class DifficultyIconTooltip : VisibilityContainer, ITooltip + { + private readonly OsuSpriteText difficultyName, starRating; + private readonly Box background; + + public string TooltipText { get; set; } + + public DifficultyIconTooltip() + { + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 5; + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Padding = new MarginPadding(10), + Children = new Drawable[] + { + difficultyName = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + starRating = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Left = 4 }, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + Colour = Color4.White, + }, + } + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreyCarmineDark; + } + + public void Refresh() + { + var info = TooltipText.Split('$'); + difficultyName.Text = info[0]; + starRating.Text = info[1]; + } + + public void Move(Vector2 pos) => this.Position = pos; + + protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); + } + [BackgroundDependencyLoader] private void load() { From 1f2f26a5038be22a0b92fecb728ce2d862d191b8 Mon Sep 17 00:00:00 2001 From: Ganendra Afrasya Date: Sun, 16 Jun 2019 00:40:44 +0700 Subject: [PATCH 009/645] Add color to star rating and star sprite icon --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 22a3fd0c8a..350e450877 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -37,7 +37,7 @@ namespace osu.Game.Beatmaps.Drawables public string TooltipText { get; set; } - public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(); + public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(AccentColour); public class DifficultyIconTooltip : VisibilityContainer, ITooltip { @@ -46,7 +46,7 @@ namespace osu.Game.Beatmaps.Drawables public string TooltipText { get; set; } - public DifficultyIconTooltip() + public DifficultyIconTooltip(Color4 accentColour) { AutoSizeAxes = Axes.Both; Masking = true; @@ -84,6 +84,7 @@ namespace osu.Game.Beatmaps.Drawables Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), + Colour = accentColour }, new SpriteIcon { @@ -92,7 +93,7 @@ namespace osu.Game.Beatmaps.Drawables Margin = new MarginPadding { Left = 4 }, Icon = FontAwesome.Solid.Star, Size = new Vector2(12), - Colour = Color4.White, + Colour = accentColour, }, } } From aa53f1432998eda35c61f5a81c00802e42c66371 Mon Sep 17 00:00:00 2001 From: Ganendra Afrasya Date: Mon, 17 Jun 2019 22:44:28 +0700 Subject: [PATCH 010/645] Make sure tooltip appear in specific cases --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 6 +++--- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- osu.Game/Screens/Multi/Components/ModeTypeInfo.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 350e450877..5f3c712c14 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -23,14 +23,14 @@ namespace osu.Game.Beatmaps.Drawables { private readonly RulesetInfo ruleset; - public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null) + public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, Boolean shouldShowTooltip = false) : base(beatmap) { if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); this.ruleset = ruleset ?? beatmap.Ruleset; - TooltipText = $"{beatmap.Version}${beatmap.StarDifficulty.ToString("0.##")}"; + TooltipText = shouldShowTooltip ? $"{beatmap.Version}${beatmap.StarDifficulty.ToString("0.##")}" : String.Empty; Size = new Vector2(20); } @@ -115,7 +115,7 @@ namespace osu.Game.Beatmaps.Drawables starRating.Text = info[1]; } - public void Move(Vector2 pos) => this.Position = pos; + public void Move(Vector2 pos) => Position = pos; protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index f413dc3771..b2c9df6442 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -140,7 +140,7 @@ namespace osu.Game.Overlays.Direct var icons = new List(); foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty)) - icons.Add(new DifficultyIcon(b)); + icons.Add(new DifficultyIcon(b, null, true)); return icons; } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 6080458aec..434c5c443b 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Components if (item?.Beatmap != null) { drawableRuleset.FadeIn(transition_duration); - drawableRuleset.Child = new DifficultyIcon(item.Beatmap, item.Ruleset) { Size = new Vector2(height) }; + drawableRuleset.Child = new DifficultyIcon(item.Beatmap, item.Ruleset, true) { Size = new Vector2(height) }; } else drawableRuleset.FadeOut(transition_duration); From d0a452cdf9f7ff6e92073259e136110e822b67aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Jun 2019 01:10:03 +0900 Subject: [PATCH 011/645] Show tooltips for beatmap set panels --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 51ca9902d2..68a0a8b5ee 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -190,7 +190,7 @@ namespace osu.Game.Screens.Select.Carousel private readonly BindableBool filtered = new BindableBool(); public FilterableDifficultyIcon(CarouselBeatmap item) - : base(item.Beatmap) + : base(item.Beatmap, shouldShowTooltip: true) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); From 63d0324f96282d048f273552b7c1b5c95d019b52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Jun 2019 01:10:14 +0900 Subject: [PATCH 012/645] Fix inspection --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 5f3c712c14..f5c8d0d029 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps.Drawables throw new ArgumentNullException(nameof(beatmap)); this.ruleset = ruleset ?? beatmap.Ruleset; - TooltipText = shouldShowTooltip ? $"{beatmap.Version}${beatmap.StarDifficulty.ToString("0.##")}" : String.Empty; + TooltipText = shouldShowTooltip ? $"{beatmap.Version}${beatmap.StarDifficulty:0.##}" : String.Empty; Size = new Vector2(20); } From 6288cc6e5c32fcc8790a9a31bf1b22f64292b11a Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:03:22 +0200 Subject: [PATCH 013/645] Refactor OnScreenDisplay to allow displaying of custom messages on OSD --- osu.Game/Overlays/OSD/OsdToast.cs | 40 ++++++ osu.Game/Overlays/OnScreenDisplay.cs | 203 ++------------------------- osu.Game/osu.Game.csproj | 3 + 3 files changed, 55 insertions(+), 191 deletions(-) create mode 100644 osu.Game/Overlays/OSD/OsdToast.cs diff --git a/osu.Game/Overlays/OSD/OsdToast.cs b/osu.Game/Overlays/OSD/OsdToast.cs new file mode 100644 index 0000000000..f700577ba1 --- /dev/null +++ b/osu.Game/Overlays/OSD/OsdToast.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Overlays.OSD +{ + public class OsdToast : Container + { + private readonly Container content; + protected override Container Content => content; + + public OsdToast() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + Width = 240; + RelativeSizeAxes = Axes.Y; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.7f + }, + content = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + } + }; + } + } +} diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 88a1edddc5..0577257080 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -8,17 +8,11 @@ using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; using osuTK; -using osuTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Transforms; using osu.Framework.Threading; using osu.Game.Configuration; -using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.OSD; namespace osu.Game.Overlays { @@ -26,16 +20,9 @@ namespace osu.Game.Overlays { private readonly Container box; - private readonly SpriteText textLine1; - private readonly SpriteText textLine2; - private readonly SpriteText textLine3; - private const float height = 110; - private const float height_notext = 98; private const float height_contracted = height * 0.9f; - private readonly FillFlowContainer optionLights; - public OnScreenDisplay() { RelativeSizeAxes = Axes.Both; @@ -52,64 +39,6 @@ namespace osu.Game.Overlays Height = height_contracted, Alpha = 0, CornerRadius = 20, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.7f, - }, - new Container // purely to add a minimum width - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Width = 240, - RelativeSizeAxes = Axes.Y, - }, - textLine1 = new OsuSpriteText - { - Padding = new MarginPadding(10), - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black), - Spacing = new Vector2(1, 0), - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, - textLine2 = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), - Padding = new MarginPadding { Left = 10, Right = 10 }, - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - }, - new FillFlowContainer - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - optionLights = new FillFlowContainer - { - Padding = new MarginPadding { Top = 20, Bottom = 5 }, - Spacing = new Vector2(5, 0), - Direction = FillDirection.Horizontal, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - AutoSizeAxes = Axes.Both - }, - textLine3 = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Margin = new MarginPadding { Bottom = 15 }, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Alpha = 0.3f, - }, - } - } - } }, }; } @@ -142,7 +71,7 @@ namespace osu.Game.Overlays return; configManager.LoadInto(trackedSettings); - trackedSettings.SettingChanged += display; + trackedSettings.SettingChanged += displayTrackedSettingChange; trackedConfigManagers.Add((source, configManager), trackedSettings); } @@ -162,56 +91,23 @@ namespace osu.Game.Overlays return; existing.Unload(); - existing.SettingChanged -= display; + existing.SettingChanged -= displayTrackedSettingChange; trackedConfigManagers.Remove((source, configManager)); } - private void display(SettingDescription description) + /// + /// Displays the given as parameter on the OSD + /// + /// + public void Display(OsdToast toast) { - Schedule(() => - { - textLine1.Text = description.Name.ToUpperInvariant(); - textLine2.Text = description.Value; - textLine3.Text = description.Shortcut.ToUpperInvariant(); - - if (string.IsNullOrEmpty(textLine3.Text)) - textLine3.Text = "NO KEY BOUND"; - - DisplayTemporarily(box); - - int optionCount = 0; - int selectedOption = -1; - - switch (description.RawValue) - { - case bool val: - optionCount = 1; - if (val) selectedOption = 0; - break; - - case Enum _: - var values = Enum.GetValues(description.RawValue.GetType()); - optionCount = values.Length; - selectedOption = Convert.ToInt32(description.RawValue); - break; - } - - textLine2.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; - textLine2.Y = optionCount > 0 ? 0 : 5; - - if (optionLights.Children.Count != optionCount) - { - optionLights.Clear(); - for (int i = 0; i < optionCount; i++) - optionLights.Add(new OptionLight()); - } - - for (int i = 0; i < optionCount; i++) - optionLights.Children[i].Glowing = i == selectedOption; - }); + box.Child = toast; + DisplayTemporarily(box); } + private void displayTrackedSettingChange(SettingDescription description) => Schedule(() => Display(new OsdTrackedSettingToast(description))); + private TransformSequence fadeIn; private ScheduledDelegate fadeOut; @@ -236,80 +132,5 @@ namespace osu.Game.Overlays b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint)); }, 500); } - - private class OptionLight : Container - { - private Color4 glowingColour, idleColour; - - private const float transition_speed = 300; - - private const float glow_strength = 0.4f; - - private readonly Box fill; - - public OptionLight() - { - Children = new[] - { - fill = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 1, - }, - }; - } - - private bool glowing; - - public bool Glowing - { - set - { - glowing = value; - if (!IsLoaded) return; - - updateGlow(); - } - } - - private void updateGlow() - { - if (glowing) - { - fill.FadeColour(glowingColour, transition_speed, Easing.OutQuint); - FadeEdgeEffectTo(glow_strength, transition_speed, Easing.OutQuint); - } - else - { - FadeEdgeEffectTo(0, transition_speed, Easing.OutQuint); - fill.FadeColour(idleColour, transition_speed, Easing.OutQuint); - } - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - fill.Colour = idleColour = Color4.White.Opacity(0.4f); - glowingColour = Color4.White; - - Size = new Vector2(25, 5); - - Masking = true; - CornerRadius = 3; - - EdgeEffect = new EdgeEffectParameters - { - Colour = colours.BlueDark.Opacity(glow_strength), - Type = EdgeEffectType.Glow, - Radius = 8, - }; - } - - protected override void LoadComplete() - { - updateGlow(); - FinishTransforms(true); - } - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e872cd1387..950a940fec 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -21,4 +21,7 @@ + + + From 4f0429d046da8d5ca21d43d26c40a1773febdd4b Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:03:46 +0200 Subject: [PATCH 014/645] Add OsdTrackedSettingToast --- .../Overlays/OSD/OsdTrackedSettingToast.cs | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs diff --git a/osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs b/osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs new file mode 100644 index 0000000000..411a33b000 --- /dev/null +++ b/osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs @@ -0,0 +1,180 @@ +// 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.Configuration.Tracking; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; +using System; + +namespace osu.Game.Overlays.OSD +{ + public class OsdTrackedSettingToast : OsdToast + { + public OsdTrackedSettingToast(SettingDescription description) + { + SpriteText textLine2; + FillFlowContainer optionLights; + + Children = new Drawable[] + { + new OsuSpriteText + { + Padding = new MarginPadding(10), + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black), + Spacing = new Vector2(1, 0), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = description.Name.ToUpperInvariant() + }, + textLine2 = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), + Padding = new MarginPadding { Left = 10, Right = 10 }, + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Text = description.Value + }, + new FillFlowContainer + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + optionLights = new FillFlowContainer + { + Padding = new MarginPadding { Top = 20, Bottom = 5 }, + Spacing = new Vector2(5, 0), + Direction = FillDirection.Horizontal, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AutoSizeAxes = Axes.Both + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding { Bottom = 15 }, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Alpha = 0.3f, + Text = string.IsNullOrEmpty(description.Shortcut) ? "NO KEY BOUND" : description.Shortcut.ToUpperInvariant() + }, + } + } + }; + + int optionCount = 0; + int selectedOption = -1; + + switch (description.RawValue) + { + case bool val: + optionCount = 1; + if (val) selectedOption = 0; + break; + + case Enum _: + var values = Enum.GetValues(description.RawValue.GetType()); + optionCount = values.Length; + selectedOption = Convert.ToInt32(description.RawValue); + break; + } + + textLine2.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; + textLine2.Y = optionCount > 0 ? 0 : 5; + + for (int i = 0; i < optionCount; i++) + { + optionLights.Add(new OptionLight + { + Glowing = i == selectedOption + }); + } + } + + private class OptionLight : Container + { + private Color4 glowingColour, idleColour; + + private const float transition_speed = 300; + + private const float glow_strength = 0.4f; + + private readonly Box fill; + + public OptionLight() + { + Children = new[] + { + fill = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 1, + }, + }; + } + + private bool glowing; + + public bool Glowing + { + set + { + glowing = value; + if (!IsLoaded) return; + + updateGlow(); + } + } + + private void updateGlow() + { + if (glowing) + { + fill.FadeColour(glowingColour, transition_speed, Easing.OutQuint); + FadeEdgeEffectTo(glow_strength, transition_speed, Easing.OutQuint); + } + else + { + FadeEdgeEffectTo(0, transition_speed, Easing.OutQuint); + fill.FadeColour(idleColour, transition_speed, Easing.OutQuint); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + fill.Colour = idleColour = Color4.White.Opacity(0.4f); + glowingColour = Color4.White; + + Size = new Vector2(25, 5); + + Masking = true; + CornerRadius = 3; + + EdgeEffect = new EdgeEffectParameters + { + Colour = colours.BlueDark.Opacity(glow_strength), + Type = EdgeEffectType.Glow, + Radius = 8, + }; + } + + protected override void LoadComplete() + { + updateGlow(); + FinishTransforms(true); + } + } + } +} From bc60b1dc13d2b069518d3b4b4d1698c43aa48ab9 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:04:47 +0200 Subject: [PATCH 015/645] Add test for empty OsdToast --- osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index d900526c07..b28f794a58 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -22,6 +22,7 @@ namespace osu.Game.Tests.Visual.UserInterface osd.BeginTracking(this, config); Add(osd); + AddStep("Display empty osd toast", () => osd.Display(new Overlays.OSD.OsdToast())); AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); From df75f9d3124f169e2d7950fd317af11c5b481b1a Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:08:02 +0200 Subject: [PATCH 016/645] Revert changes made by VS to csproj --- osu.Game/osu.Game.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 950a940fec..e872cd1387 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -21,7 +21,4 @@ - - - From 70372dd03d1e1735de241d431b629bdb684ae9c1 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:14:04 +0200 Subject: [PATCH 017/645] Add global actions for game-wide music jukebox manipulation --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 14d356f889..6d85a69804 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -38,6 +38,10 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), + new KeyBinding(InputKey.F5, GlobalAction.MusicPrev), + new KeyBinding(InputKey.F6, GlobalAction.MusicNext), + new KeyBinding(InputKey.X, GlobalAction.MusicPlay), + new KeyBinding(InputKey.Escape, GlobalAction.Back), new KeyBinding(InputKey.MouseButton1, GlobalAction.Back), @@ -88,6 +92,16 @@ namespace osu.Game.Input.Bindings [Description("Toggle mute")] ToggleMute, + // Game-wide beatmap jukebox keybindings + [Description("Jukebox next track")] + MusicNext, + + [Description("Jukebox previous track")] + MusicPrev, + + [Description("Jukebox play / pause current track")] + MusicPlay, + // In-Game Keybindings [Description("Skip cutscene")] SkipCutscene, From b5bd863dd080d25f0c01f9cdd30c0d6cde4a9c5d Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:21:50 +0200 Subject: [PATCH 018/645] Add methods to MusicController to play or pause, select next or previous track --- osu.Game/Overlays/MusicController.cs | 31 +++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 29ae5983be..91fa2f5a95 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -529,6 +529,35 @@ namespace osu.Game.Overlays /// /// Play the next random or playlist track. /// - public void NextTrack() => next(); + /// Returns whether the track could be changed or not + public bool NextTrack() + { + if (beatmap.Disabled) return false; + + next(); + return true; + } + + /// + /// Play the previous random or playlist track. + /// + public bool PreviousTrack() + { + if (beatmap.Disabled) return false; + + prev(); + return true; + } + + /// + /// Play or pause the current beatmap track. + /// Returns whether the current track could be played / paused or not + public bool PlayTrack() + { + if (beatmap.Disabled) return false; + + play(); + return true; + } } } From c9e44e5e34aa481ce0210898616829c1770a67c0 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:25:09 +0200 Subject: [PATCH 019/645] Add OsdIconToast + test --- .../UserInterface/TestSceneOnScreenDisplay.cs | 2 + osu.Game/Overlays/OSD/OsdIconToast.cs | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 osu.Game/Overlays/OSD/OsdIconToast.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index b28f794a58..047c89ae54 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface @@ -23,6 +24,7 @@ namespace osu.Game.Tests.Visual.UserInterface Add(osd); AddStep("Display empty osd toast", () => osd.Display(new Overlays.OSD.OsdToast())); + AddStep("Display osd toast with icon and message", () => osd.Display(new Overlays.OSD.OsdIconToast("Hey there !", FontAwesome.Solid.HandSpock))); AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); diff --git a/osu.Game/Overlays/OSD/OsdIconToast.cs b/osu.Game/Overlays/OSD/OsdIconToast.cs new file mode 100644 index 0000000000..c00949d48b --- /dev/null +++ b/osu.Game/Overlays/OSD/OsdIconToast.cs @@ -0,0 +1,42 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.OSD +{ + public class OsdIconToast : OsdToast + { + public OsdIconToast(string message, IconUsage icon) + { + Children = new Drawable[] + { + new FillFlowContainer() + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Direction = FillDirection.Vertical, + Spacing = new osuTK.Vector2(10), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), + Text = message + }, + new SpriteIcon + { + Icon = icon, + Size = new osuTK.Vector2(45), + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + } + } + } + }; + } + } +} From 5cad2b21927199dd4baf026c5d27baf85c29c43b Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:28:37 +0200 Subject: [PATCH 020/645] Add missing function to MusicController --- osu.Game/Overlays/MusicController.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 91fa2f5a95..f6d67e9981 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -559,5 +559,10 @@ namespace osu.Game.Overlays play(); return true; } + + /// + /// Returns whether the current beatmap track is playing. + /// + public bool IsPlaying => beatmap.Value.Track.IsRunning; } } From 89acd9da3e0c9e5aa55d1bdc2647c5349ec1a556 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:33:13 +0200 Subject: [PATCH 021/645] Add game-wide jukebox keybindings handling to OsuGame --- osu.Game/OsuGame.cs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0a472d4dc1..32539055a7 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -67,6 +67,8 @@ namespace osu.Game private BeatmapSetOverlay beatmapSetOverlay; + private OnScreenDisplay osd; + [Cached] private readonly ScreenshotManager screenshotManager = new ScreenshotManager(); @@ -456,7 +458,7 @@ namespace osu.Game }); loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add); - loadComponentSingleFile(new OnScreenDisplay(), Add, true); + loadComponentSingleFile(osd = new OnScreenDisplay(), Add, true); loadComponentSingleFile(notifications = new NotificationOverlay { @@ -719,6 +721,24 @@ namespace osu.Game case GlobalAction.ToggleGameplayMouseButtons: LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get(OsuSetting.MouseDisableButtons)); return true; + + case GlobalAction.MusicPlay: + if (!musicController.IsLoaded) return true; + if (musicController.PlayTrack()) + osd.Display(new Overlays.OSD.OsdIconToast(musicController.IsPlaying ? "Play track" : "Pause track", musicController.IsPlaying ? FontAwesome.Solid.PlayCircle : FontAwesome.Solid.PauseCircle)); + return true; + + case GlobalAction.MusicNext: + if (!musicController.IsLoaded) return true; + if (musicController.NextTrack()) + osd.Display(new Overlays.OSD.OsdIconToast("Next track", FontAwesome.Solid.FastForward)); + return true; + + case GlobalAction.MusicPrev: + if (!musicController.IsLoaded) return true; + if (musicController.PreviousTrack()) + osd.Display(new Overlays.OSD.OsdIconToast("Previous track", FontAwesome.Solid.FastForward)); + return true; } return false; From 5f8bd6eca7a7e0f43b890ef1726da86d41cb0c82 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 5 Jul 2019 16:37:37 +0200 Subject: [PATCH 022/645] Fix CI issues + minor issues --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 8 ++++---- osu.Game/OsuGame.cs | 5 ++++- osu.Game/Overlays/MusicController.cs | 1 + osu.Game/Overlays/OSD/OsdIconToast.cs | 7 +++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 6d85a69804..e756694285 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -38,16 +38,16 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), - new KeyBinding(InputKey.F5, GlobalAction.MusicPrev), - new KeyBinding(InputKey.F6, GlobalAction.MusicNext), - new KeyBinding(InputKey.X, GlobalAction.MusicPlay), - new KeyBinding(InputKey.Escape, GlobalAction.Back), new KeyBinding(InputKey.MouseButton1, GlobalAction.Back), new KeyBinding(InputKey.Space, GlobalAction.Select), new KeyBinding(InputKey.Enter, GlobalAction.Select), new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select), + + new KeyBinding(InputKey.F5, GlobalAction.MusicPrev), + new KeyBinding(InputKey.F6, GlobalAction.MusicNext), + new KeyBinding(InputKey.X, GlobalAction.MusicPlay), }; public IEnumerable InGameKeyBindings => new[] diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 32539055a7..bae301a8a6 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -724,20 +724,23 @@ namespace osu.Game case GlobalAction.MusicPlay: if (!musicController.IsLoaded) return true; + if (musicController.PlayTrack()) osd.Display(new Overlays.OSD.OsdIconToast(musicController.IsPlaying ? "Play track" : "Pause track", musicController.IsPlaying ? FontAwesome.Solid.PlayCircle : FontAwesome.Solid.PauseCircle)); return true; case GlobalAction.MusicNext: if (!musicController.IsLoaded) return true; + if (musicController.NextTrack()) osd.Display(new Overlays.OSD.OsdIconToast("Next track", FontAwesome.Solid.FastForward)); return true; case GlobalAction.MusicPrev: if (!musicController.IsLoaded) return true; + if (musicController.PreviousTrack()) - osd.Display(new Overlays.OSD.OsdIconToast("Previous track", FontAwesome.Solid.FastForward)); + osd.Display(new Overlays.OSD.OsdIconToast("Previous track", FontAwesome.Solid.FastBackward)); return true; } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f6d67e9981..618187069d 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -551,6 +551,7 @@ namespace osu.Game.Overlays /// /// Play or pause the current beatmap track. + /// /// Returns whether the current track could be played / paused or not public bool PlayTrack() { diff --git a/osu.Game/Overlays/OSD/OsdIconToast.cs b/osu.Game/Overlays/OSD/OsdIconToast.cs index c00949d48b..0e2bcd377f 100644 --- a/osu.Game/Overlays/OSD/OsdIconToast.cs +++ b/osu.Game/Overlays/OSD/OsdIconToast.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; @@ -12,7 +15,7 @@ namespace osu.Game.Overlays.OSD { Children = new Drawable[] { - new FillFlowContainer() + new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, From b32b078e48d38a88cfd222c085cb5e9d648e98e8 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 10 Jul 2019 21:55:43 +0200 Subject: [PATCH 023/645] Set default keybindings for jukebox to stable's ones. --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index e756694285..cdd821c173 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -45,9 +45,9 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Enter, GlobalAction.Select), new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select), - new KeyBinding(InputKey.F5, GlobalAction.MusicPrev), - new KeyBinding(InputKey.F6, GlobalAction.MusicNext), - new KeyBinding(InputKey.X, GlobalAction.MusicPlay), + new KeyBinding(InputKey.F1, GlobalAction.MusicPrev), + new KeyBinding(InputKey.F5, GlobalAction.MusicNext), + new KeyBinding(InputKey.F3, GlobalAction.MusicPlay), }; public IEnumerable InGameKeyBindings => new[] From 3bc789fca892d8120e9916c6b285d56f64490086 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jul 2019 15:09:06 +0900 Subject: [PATCH 024/645] Remove osd prefix and prefer upper-case OSD --- .../Visual/UserInterface/TestSceneOnScreenDisplay.cs | 3 ++- osu.Game/Overlays/OSD/{OsdToast.cs => Toast.cs} | 6 +++--- .../{OsdTrackedSettingToast.cs => TrackedSettingToast.cs} | 6 +++--- osu.Game/Overlays/OnScreenDisplay.cs | 6 +++--- 4 files changed, 11 insertions(+), 10 deletions(-) rename osu.Game/Overlays/OSD/{OsdToast.cs => Toast.cs} (94%) rename osu.Game/Overlays/OSD/{OsdTrackedSettingToast.cs => TrackedSettingToast.cs} (98%) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index b28f794a58..59a35591bd 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -7,6 +7,7 @@ using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Graphics; using osu.Game.Overlays; +using osu.Game.Overlays.OSD; namespace osu.Game.Tests.Visual.UserInterface { @@ -22,7 +23,7 @@ namespace osu.Game.Tests.Visual.UserInterface osd.BeginTracking(this, config); Add(osd); - AddStep("Display empty osd toast", () => osd.Display(new Overlays.OSD.OsdToast())); + AddStep("Display empty osd toast", () => osd.Display(new Toast())); AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); diff --git a/osu.Game/Overlays/OSD/OsdToast.cs b/osu.Game/Overlays/OSD/Toast.cs similarity index 94% rename from osu.Game/Overlays/OSD/OsdToast.cs rename to osu.Game/Overlays/OSD/Toast.cs index f700577ba1..6634959bca 100644 --- a/osu.Game/Overlays/OSD/OsdToast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -1,19 +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.Graphics.Containers; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; namespace osu.Game.Overlays.OSD { - public class OsdToast : Container + public class Toast : Container { private readonly Container content; protected override Container Content => content; - public OsdToast() + public Toast() { Anchor = Anchor.Centre; Origin = Anchor.Centre; diff --git a/osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs similarity index 98% rename from osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs rename to osu.Game/Overlays/OSD/TrackedSettingToast.cs index 411a33b000..8def8476f0 100644 --- a/osu.Game/Overlays/OSD/OsdTrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions.Color4Extensions; @@ -13,13 +14,12 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK; using osuTK.Graphics; -using System; namespace osu.Game.Overlays.OSD { - public class OsdTrackedSettingToast : OsdToast + public class TrackedSettingToast : Toast { - public OsdTrackedSettingToast(SettingDescription description) + public TrackedSettingToast(SettingDescription description) { SpriteText textLine2; FillFlowContainer optionLights; diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 0577257080..a30ce5c56f 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -97,16 +97,16 @@ namespace osu.Game.Overlays } /// - /// Displays the given as parameter on the OSD + /// Displays the given as parameter on the OSD /// /// - public void Display(OsdToast toast) + public void Display(Toast toast) { box.Child = toast; DisplayTemporarily(box); } - private void displayTrackedSettingChange(SettingDescription description) => Schedule(() => Display(new OsdTrackedSettingToast(description))); + private void displayTrackedSettingChange(SettingDescription description) => Schedule(() => Display(new TrackedSettingToast(description))); private TransformSequence fadeIn; private ScheduledDelegate fadeOut; From dd13e2508ae854c483b60afcfa8aadd994393bc5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jul 2019 15:14:57 +0900 Subject: [PATCH 025/645] Add note about toast height --- osu.Game/Overlays/OSD/Toast.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index 6634959bca..3ca010c5f4 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -18,6 +18,8 @@ namespace osu.Game.Overlays.OSD Anchor = Anchor.Centre; Origin = Anchor.Centre; Width = 240; + + // A toast's height is decided (and transformed) by the containing OnScreenDisplay. RelativeSizeAxes = Axes.Y; InternalChildren = new Drawable[] From 2c62891c4836ceb5b24957331dd6aa615ca8f85e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jul 2019 15:15:34 +0900 Subject: [PATCH 026/645] Make Toast base class abstract --- .../Visual/UserInterface/TestSceneOnScreenDisplay.cs | 6 +++++- osu.Game/Overlays/OSD/Toast.cs | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index 59a35591bd..ca14822205 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.UserInterface osd.BeginTracking(this, config); Add(osd); - AddStep("Display empty osd toast", () => osd.Display(new Toast())); + AddStep("Display empty osd toast", () => osd.Display(new EmptyToast())); AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); @@ -88,6 +88,10 @@ namespace osu.Game.Tests.Visual.UserInterface Setting4 } + private class EmptyToast : Toast + { + } + private class TestOnScreenDisplay : OnScreenDisplay { protected override void DisplayTemporarily(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110); diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index 3ca010c5f4..c6e3227cd1 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -8,12 +8,12 @@ using osuTK.Graphics; namespace osu.Game.Overlays.OSD { - public class Toast : Container + public abstract class Toast : Container { private readonly Container content; protected override Container Content => content; - public Toast() + protected Toast() { Anchor = Anchor.Centre; Origin = Anchor.Centre; From cd7c03c13a0519c069b531b4c7c127539b85871f Mon Sep 17 00:00:00 2001 From: StanR Date: Thu, 11 Jul 2019 16:44:48 +0300 Subject: [PATCH 027/645] Add genre and language sections to beatmapset overlay --- .../Online/TestSceneBeatmapSetOverlay.cs | 2 ++ osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs | 20 ++++++++++++++++++ osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 10 +++++++++ osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs | 21 +++++++++++++++++++ .../API/Requests/Responses/APIBeatmapSet.cs | 8 +++++++ osu.Game/Overlays/BeatmapSet/Info.cs | 21 ++++++++++++++++++- 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs create mode 100644 osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index daee419b52..d87d9910c3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -173,6 +173,8 @@ namespace osu.Game.Tests.Visual.Online HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), + Language = BeatmapSetOnlineLanguage.English, + Genre = BeatmapSetOnlineGenre.Rock, }, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs b/osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs new file mode 100644 index 0000000000..cea9d94987 --- /dev/null +++ b/osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs @@ -0,0 +1,20 @@ +// 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.Beatmaps +{ + public enum BeatmapSetOnlineGenre + { + Any = 0, + Unspecified = 1, + VideoGame = 2, + Anime = 3, + Rock = 4, + Pop = 5, + Other = 6, + Novelty = 7, + // genre_id 8 doesnt exist + HipHop = 9, + Electronic = 10 + } +} diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index ea3f0b61b9..2d2f06a57c 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -70,6 +70,16 @@ namespace osu.Game.Beatmaps /// The availability of this beatmap set. /// public BeatmapSetOnlineAvailability Availability { get; set; } + + /// + /// Beatmap set's song genre. + /// + public BeatmapSetOnlineGenre Genre { get; set; } + + /// + /// Beatmap set's song language. + /// + public BeatmapSetOnlineLanguage Language { get; set; } } public class BeatmapSetOnlineCovers diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs b/osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs new file mode 100644 index 0000000000..0fb0dec904 --- /dev/null +++ b/osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Beatmaps +{ + public enum BeatmapSetOnlineLanguage + { + Any = 0, + Other = 1, + English = 2, + Japanese = 3, + Chinese = 4, + Instrumental = 5, + Korean = 6, + French = 7, + German = 8, + Swedish = 9, + Spanish = 10, + Italian = 11 + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 200a705500..9ca2cb0b81 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -66,6 +66,12 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"availability")] private BeatmapSetOnlineAvailability availability { get; set; } + [JsonProperty(@"genre_id")] + private BeatmapSetOnlineGenre genre { get; set; } + + [JsonProperty(@"language_id")] + private BeatmapSetOnlineLanguage language { get; set; } + [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } @@ -91,6 +97,8 @@ namespace osu.Game.Online.API.Requests.Responses Ranked = ranked, LastUpdated = lastUpdated, Availability = availability, + Genre = genre, + Language = language }, Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(), }; diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 44827f0a0c..27ca58fbd3 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.BeatmapSet public Info() { - MetadataSection source, tags; + MetadataSection source, tags, genre, language; RelativeSizeAxes = Axes.X; Height = 220; Masking = true; @@ -88,6 +88,19 @@ namespace osu.Game.Overlays.BeatmapSet Children = new[] { source = new MetadataSection("Source"), + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Width = 0.5f, + FillMode = FillMode.Fit, + Children = new Drawable[] + { + genre = new MetadataSection("Genre"), + language = new MetadataSection("Language"), + } + }, tags = new MetadataSection("Tags"), }, }, @@ -119,6 +132,12 @@ namespace osu.Game.Overlays.BeatmapSet { source.Text = b.NewValue?.Metadata.Source ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; + + var genreId = b.NewValue?.OnlineInfo.Genre ?? BeatmapSetOnlineGenre.Unspecified; + genre.Text = genreId.ToString(); + + var languageId = b.NewValue?.OnlineInfo.Language ?? BeatmapSetOnlineLanguage.Other; + language.Text = languageId.ToString(); }; } From 1e04fcc6b54d8dab5d24478794ad27478cf38b80 Mon Sep 17 00:00:00 2001 From: StanR Date: Thu, 11 Jul 2019 17:47:09 +0300 Subject: [PATCH 028/645] Apply fixes --- osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs | 20 ------- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 56 ++++++++++++++++++- osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs | 21 ------- osu.Game/Overlays/BeatmapSet/Info.cs | 9 +-- 4 files changed, 57 insertions(+), 49 deletions(-) delete mode 100644 osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs delete mode 100644 osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs b/osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs deleted file mode 100644 index cea9d94987..0000000000 --- a/osu.Game/Beatmaps/BeatmapSetOnlineGenre.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Beatmaps -{ - public enum BeatmapSetOnlineGenre - { - Any = 0, - Unspecified = 1, - VideoGame = 2, - Anime = 3, - Rock = 4, - Pop = 5, - Other = 6, - Novelty = 7, - // genre_id 8 doesnt exist - HipHop = 9, - Electronic = 10 - } -} diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 2d2f06a57c..4cb50b59fb 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.ComponentModel; using Newtonsoft.Json; namespace osu.Game.Beatmaps @@ -72,16 +73,67 @@ namespace osu.Game.Beatmaps public BeatmapSetOnlineAvailability Availability { get; set; } /// - /// Beatmap set's song genre. + /// The song genre of this beatmap set. /// public BeatmapSetOnlineGenre Genre { get; set; } /// - /// Beatmap set's song language. + /// The song language of this beatmap set. /// public BeatmapSetOnlineLanguage Language { get; set; } } + public enum BeatmapSetOnlineGenre + { + [Description("Any")] + Any = 0, + + [Description("Unspecified")] + Unspecified = 1, + + [Description("Video Game")] + VideoGame = 2, + + [Description("Anime")] + Anime = 3, + + [Description("Rock")] + Rock = 4, + + [Description("Pop")] + Pop = 5, + + [Description("Other")] + Other = 6, + + [Description("Novelty")] + Novelty = 7, + + // genre_id 8 doesn't exist + + [Description("Hip-Hop")] + HipHop = 9, + + [Description("Electronic")] + Electronic = 10 + } + + public enum BeatmapSetOnlineLanguage + { + Any, + Other, + English, + Japanese, + Chinese, + Instrumental, + Korean, + French, + German, + Swedish, + Spanish, + Italian + } + public class BeatmapSetOnlineCovers { public string CoverLowRes { get; set; } diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs b/osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs deleted file mode 100644 index 0fb0dec904..0000000000 --- a/osu.Game/Beatmaps/BeatmapSetOnlineLanguage.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Beatmaps -{ - public enum BeatmapSetOnlineLanguage - { - Any = 0, - Other = 1, - English = 2, - Japanese = 3, - Chinese = 4, - Instrumental = 5, - Korean = 6, - French = 7, - German = 8, - Swedish = 9, - Spanish = 10, - Italian = 11 - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 27ca58fbd3..0e4e9db948 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -132,12 +133,8 @@ namespace osu.Game.Overlays.BeatmapSet { source.Text = b.NewValue?.Metadata.Source ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; - - var genreId = b.NewValue?.OnlineInfo.Genre ?? BeatmapSetOnlineGenre.Unspecified; - genre.Text = genreId.ToString(); - - var languageId = b.NewValue?.OnlineInfo.Language ?? BeatmapSetOnlineLanguage.Other; - language.Text = languageId.ToString(); + genre.Text = (b.NewValue?.OnlineInfo.Genre ?? BeatmapSetOnlineGenre.Unspecified).GetDescription(); + language.Text = (b.NewValue?.OnlineInfo.Language ?? BeatmapSetOnlineLanguage.Other).ToString(); }; } From 09d679de8d6367ec6894e470318d3cda625d5fd3 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 12 Jul 2019 08:50:53 +0200 Subject: [PATCH 029/645] Move text display layout to Toast. --- .../UserInterface/TestSceneOnScreenDisplay.cs | 4 ++ osu.Game/Overlays/OSD/Toast.cs | 35 +++++++++++++++- osu.Game/Overlays/OSD/TrackedSettingToast.cs | 41 +++---------------- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index ca14822205..4decfc7dd6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -90,6 +90,10 @@ namespace osu.Game.Tests.Visual.UserInterface private class EmptyToast : Toast { + public EmptyToast() + : base("", "", "") + { + } } private class TestOnScreenDisplay : OnScreenDisplay diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index c6e3227cd1..6572830d10 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -4,6 +4,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.OSD @@ -13,7 +16,7 @@ namespace osu.Game.Overlays.OSD private readonly Container content; protected override Container Content => content; - protected Toast() + protected Toast(string description, string value, string keybinding) { Anchor = Anchor.Centre; Origin = Anchor.Centre; @@ -35,7 +38,35 @@ namespace osu.Game.Overlays.OSD Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - } + }, + new OsuSpriteText + { + Padding = new MarginPadding(10), + Name = "Description", + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black), + Spacing = new Vector2(1, 0), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = description.ToUpperInvariant() + }, + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), + Padding = new MarginPadding { Left = 10, Right = 10 }, + Name = "Value", + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Text = value + }, + new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Name = "Shortcut", + Margin = new MarginPadding { Bottom = 15 }, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Text = string.IsNullOrEmpty(keybinding) ? "NO KEY BOUND" : keybinding.ToUpperInvariant() + }, }; } } diff --git a/osu.Game/Overlays/OSD/TrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs index 8def8476f0..454ba84d70 100644 --- a/osu.Game/Overlays/OSD/TrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -9,9 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osuTK; using osuTK.Graphics; @@ -20,55 +18,29 @@ namespace osu.Game.Overlays.OSD public class TrackedSettingToast : Toast { public TrackedSettingToast(SettingDescription description) + : base(description.Name, description.Value, description.Shortcut) { - SpriteText textLine2; FillFlowContainer optionLights; Children = new Drawable[] { - new OsuSpriteText - { - Padding = new MarginPadding(10), - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black), - Spacing = new Vector2(1, 0), - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = description.Name.ToUpperInvariant() - }, - textLine2 = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), - Padding = new MarginPadding { Left = 10, Right = 10 }, - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Text = description.Value - }, new FillFlowContainer { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, Direction = FillDirection.Vertical, + Margin = new MarginPadding { Top = 70 }, Children = new Drawable[] { optionLights = new FillFlowContainer { - Padding = new MarginPadding { Top = 20, Bottom = 5 }, + Padding = new MarginPadding { Bottom = 5 }, Spacing = new Vector2(5, 0), Direction = FillDirection.Horizontal, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Both }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Margin = new MarginPadding { Bottom = 15 }, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Alpha = 0.3f, - Text = string.IsNullOrEmpty(description.Shortcut) ? "NO KEY BOUND" : description.Shortcut.ToUpperInvariant() - }, } } }; @@ -90,9 +62,6 @@ namespace osu.Game.Overlays.OSD break; } - textLine2.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; - textLine2.Y = optionCount > 0 ? 0 : 5; - for (int i = 0; i < optionCount; i++) { optionLights.Add(new OptionLight From bbc3cbf5632fbe5fd8adffd0c9c29db639d4b7dc Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 12 Jul 2019 20:22:31 +0200 Subject: [PATCH 030/645] Restore deleted line --- osu.Game/Overlays/OSD/Toast.cs | 6 ++++-- osu.Game/Overlays/OSD/TrackedSettingToast.cs | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index 6572830d10..67c9b46c77 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -16,6 +16,8 @@ namespace osu.Game.Overlays.OSD private readonly Container content; protected override Container Content => content; + protected readonly OsuSpriteText ValueText; + protected Toast(string description, string value, string keybinding) { Anchor = Anchor.Centre; @@ -49,13 +51,13 @@ namespace osu.Game.Overlays.OSD Origin = Anchor.TopCentre, Text = description.ToUpperInvariant() }, - new OsuSpriteText + ValueText = new OsuSpriteText { Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), Padding = new MarginPadding { Left = 10, Right = 10 }, Name = "Value", Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, + Origin = Anchor.Centre, Text = value }, new OsuSpriteText diff --git a/osu.Game/Overlays/OSD/TrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs index 454ba84d70..9812dcd797 100644 --- a/osu.Game/Overlays/OSD/TrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -62,6 +62,8 @@ namespace osu.Game.Overlays.OSD break; } + ValueText.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; + for (int i = 0; i < optionCount; i++) { optionLights.Add(new OptionLight From 2926932a1acf5adc8da8125ba83b05a7960ebb60 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 20 Jul 2019 21:10:17 +0200 Subject: [PATCH 031/645] Add MusicControllerToast used to display current music playback status on OSD --- osu.Game/OsuGame.cs | 6 +-- osu.Game/Overlays/OSD/MusicControllerToast.cs | 13 ++++++ osu.Game/Overlays/OSD/OsdIconToast.cs | 45 ------------------- 3 files changed, 16 insertions(+), 48 deletions(-) create mode 100644 osu.Game/Overlays/OSD/MusicControllerToast.cs delete mode 100644 osu.Game/Overlays/OSD/OsdIconToast.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index bae301a8a6..dde87cd2ed 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -726,21 +726,21 @@ namespace osu.Game if (!musicController.IsLoaded) return true; if (musicController.PlayTrack()) - osd.Display(new Overlays.OSD.OsdIconToast(musicController.IsPlaying ? "Play track" : "Pause track", musicController.IsPlaying ? FontAwesome.Solid.PlayCircle : FontAwesome.Solid.PauseCircle)); + osd.Display(new Overlays.OSD.MusicControllerToast(musicController.IsPlaying ? "Play track" : "Pause track")); return true; case GlobalAction.MusicNext: if (!musicController.IsLoaded) return true; if (musicController.NextTrack()) - osd.Display(new Overlays.OSD.OsdIconToast("Next track", FontAwesome.Solid.FastForward)); + osd.Display(new Overlays.OSD.MusicControllerToast("Next track")); return true; case GlobalAction.MusicPrev: if (!musicController.IsLoaded) return true; if (musicController.PreviousTrack()) - osd.Display(new Overlays.OSD.OsdIconToast("Previous track", FontAwesome.Solid.FastBackward)); + osd.Display(new Overlays.OSD.MusicControllerToast("Previous track")); return true; } diff --git a/osu.Game/Overlays/OSD/MusicControllerToast.cs b/osu.Game/Overlays/OSD/MusicControllerToast.cs new file mode 100644 index 0000000000..d9e0ad2c07 --- /dev/null +++ b/osu.Game/Overlays/OSD/MusicControllerToast.cs @@ -0,0 +1,13 @@ +// 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.OSD +{ + public class MusicControllerToast : Toast + { + public MusicControllerToast(string value) + : base("Music Playback", value, "") + { + } + } +} diff --git a/osu.Game/Overlays/OSD/OsdIconToast.cs b/osu.Game/Overlays/OSD/OsdIconToast.cs deleted file mode 100644 index 0e2bcd377f..0000000000 --- a/osu.Game/Overlays/OSD/OsdIconToast.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; - -namespace osu.Game.Overlays.OSD -{ - public class OsdIconToast : OsdToast - { - public OsdIconToast(string message, IconUsage icon) - { - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Direction = FillDirection.Vertical, - Spacing = new osuTK.Vector2(10), - Children = new Drawable[] - { - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light), - Text = message - }, - new SpriteIcon - { - Icon = icon, - Size = new osuTK.Vector2(45), - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - } - } - } - }; - } - } -} From 7b82d184bd48dd3130552596ff1115a58986c651 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 11:07:53 +0300 Subject: [PATCH 032/645] Add bindable boolean for break times --- osu.Game/Screens/Play/BreakOverlay.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index d390787090..0941b8a452 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -2,7 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -35,6 +37,11 @@ namespace osu.Game.Screens.Play public override bool RemoveCompletedTransforms => false; + /// + /// Whether we are currently in the break time range. + /// + public readonly BindableBool IsBreakTime = new BindableBool(); + private readonly Container remainingTimeAdjustmentBox; private readonly Container remainingTimeBox; private readonly RemainingTimeCounter remainingTimeCounter; @@ -109,6 +116,13 @@ namespace osu.Game.Screens.Play initializeBreaks(); } + protected override void Update() + { + base.Update(); + + IsBreakTime.Value = breaks.Where(b => b.HasEffect).Any(b => Clock.CurrentTime >= b.StartTime && Clock.CurrentTime <= b.EndTime); + } + private void initializeBreaks() { if (!IsLoaded) return; // we need a clock. From 0ea0a10ca45ee73e08efad09e55e98f17b1ee2da Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 11:26:38 +0300 Subject: [PATCH 033/645] Expose as IBindable --- osu.Game/Screens/Play/BreakOverlay.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 0941b8a452..593b54afb8 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -41,6 +41,9 @@ namespace osu.Game.Screens.Play /// Whether we are currently in the break time range. /// public readonly BindableBool IsBreakTime = new BindableBool(); + public IBindable IsBreakTime => isBreakTime; + + private readonly BindableBool isBreakTime = new BindableBool(); private readonly Container remainingTimeAdjustmentBox; private readonly Container remainingTimeBox; From 69d2f57f4fadc108076365780f13b96b6e8e08cc Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 11:27:01 +0300 Subject: [PATCH 034/645] Avoid using LINQ --- osu.Game/Screens/Play/BreakOverlay.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 593b54afb8..bebbbc5b68 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -123,7 +122,24 @@ namespace osu.Game.Screens.Play { base.Update(); - IsBreakTime.Value = breaks.Where(b => b.HasEffect).Any(b => Clock.CurrentTime >= b.StartTime && Clock.CurrentTime <= b.EndTime); + updateBreakTimeBindable(); + } + + private void updateBreakTimeBindable() + { + foreach (var b in breaks) + { + if (!b.HasEffect) + continue; + + if (Clock.CurrentTime >= b.StartTime && Clock.CurrentTime <= b.EndTime) + { + isBreakTime.Value = true; + return; + } + } + + isBreakTime.Value = false; } private void initializeBreaks() From 9bd66b6e7a777f9273efd5b6c7734db909c78b2f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 11:27:32 +0300 Subject: [PATCH 035/645] Better xmldoc --- osu.Game/Screens/Play/BreakOverlay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index bebbbc5b68..5958ca77d8 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -37,9 +37,8 @@ namespace osu.Game.Screens.Play public override bool RemoveCompletedTransforms => false; /// - /// Whether we are currently in the break time range. + /// Whether the gameplay is currently in a break. /// - public readonly BindableBool IsBreakTime = new BindableBool(); public IBindable IsBreakTime => isBreakTime; private readonly BindableBool isBreakTime = new BindableBool(); From 172a9ce33a29a5286d23f46fc0b752e795362e12 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 11:40:45 +0300 Subject: [PATCH 036/645] Use a for loop instead of foreach avoid allocating an iterator --- osu.Game/Screens/Play/BreakOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 5958ca77d8..918bb1e5c9 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -126,12 +126,12 @@ namespace osu.Game.Screens.Play private void updateBreakTimeBindable() { - foreach (var b in breaks) + for (int i = 0; i < breaks.Count; i++) { - if (!b.HasEffect) + if (!breaks[i].HasEffect) continue; - if (Clock.CurrentTime >= b.StartTime && Clock.CurrentTime <= b.EndTime) + if (Clock.CurrentTime >= breaks[i].StartTime && Clock.CurrentTime <= breaks[i].EndTime) { isBreakTime.Value = true; return; From 5a55433d6c7e2b76e8b7ceabd732374e0573efc1 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 11:53:32 +0300 Subject: [PATCH 037/645] Return if breaks are null Fixes a test --- osu.Game/Screens/Play/BreakOverlay.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 918bb1e5c9..8b9431a87c 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -126,6 +126,9 @@ namespace osu.Game.Screens.Play private void updateBreakTimeBindable() { + if (breaks == null) + return; + for (int i = 0; i < breaks.Count; i++) { if (!breaks[i].HasEffect) From cdda264c491c4cef4b122ece777e04413e57cbc5 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 25 Jul 2019 12:28:21 +0300 Subject: [PATCH 038/645] Use global index and move it to find if break time Avoid using iterations --- osu.Game/Screens/Play/BreakOverlay.cs | 38 ++++++++++++++++++--------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 8b9431a87c..0470cdb0d5 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -30,6 +31,8 @@ namespace osu.Game.Screens.Play set { breaks = value; + currentBreakIndex = 0; + initializeBreaks(); } } @@ -41,6 +44,7 @@ namespace osu.Game.Screens.Play /// public IBindable IsBreakTime => isBreakTime; + private int currentBreakIndex; private readonly BindableBool isBreakTime = new BindableBool(); private readonly Container remainingTimeAdjustmentBox; @@ -126,22 +130,30 @@ namespace osu.Game.Screens.Play private void updateBreakTimeBindable() { - if (breaks == null) - return; - - for (int i = 0; i < breaks.Count; i++) + if (breaks == null || !breaks.Any()) { - if (!breaks[i].HasEffect) - continue; - - if (Clock.CurrentTime >= breaks[i].StartTime && Clock.CurrentTime <= breaks[i].EndTime) - { - isBreakTime.Value = true; - return; - } + isBreakTime.Value = false; + return; } - isBreakTime.Value = false; + int indexDirection = Clock.CurrentTime < breaks[currentBreakIndex].StartTime ? -1 : (Clock.CurrentTime > breaks[currentBreakIndex].EndTime ? 1 : 0); + + while (Clock.CurrentTime < breaks[currentBreakIndex].StartTime || Clock.CurrentTime > breaks[currentBreakIndex].EndTime) + { + currentBreakIndex += indexDirection; + + if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) + break; + } + + if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) + { + isBreakTime.Value = false; + currentBreakIndex = 0; + return; + } + + isBreakTime.Value = true; } private void initializeBreaks() From 5e5101280054709321e3f528312605be91843b28 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Thu, 25 Jul 2019 22:54:05 +0930 Subject: [PATCH 039/645] Rewrite updateBreakTimeBindable --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 26 ++++++++++++++++- osu.Game/Screens/Play/BreakOverlay.cs | 29 +++++++------------ 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index 3cd1b8307a..ffa822d175 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -1,8 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; @@ -11,11 +16,30 @@ namespace osu.Game.Tests.Visual.Gameplay [TestFixture] public class TestSceneBreakOverlay : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BreakOverlay), + }; + private readonly BreakOverlay breakOverlay; + private readonly IBindable isBreakTimeBindable = new BindableBool(); public TestSceneBreakOverlay() { - Child = breakOverlay = new BreakOverlay(true); + SpriteText breakTimeText; + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + breakTimeText = new SpriteText(), + breakOverlay = new BreakOverlay(true) + } + }; + + isBreakTimeBindable.BindTo(breakOverlay.IsBreakTime); + isBreakTimeBindable.BindValueChanged(e => breakTimeText.Text = $"IsBreakTime: {e.NewValue}", true); AddStep("2s break", () => startBreak(2000)); AddStep("5s break", () => startBreak(5000)); diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 0470cdb0d5..aceacdbab1 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Play set { breaks = value; - currentBreakIndex = 0; + nearestBreakIndex = 0; initializeBreaks(); } @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Play /// public IBindable IsBreakTime => isBreakTime; - private int currentBreakIndex; + private int nearestBreakIndex; private readonly BindableBool isBreakTime = new BindableBool(); private readonly Container remainingTimeAdjustmentBox; @@ -136,24 +136,17 @@ namespace osu.Game.Screens.Play return; } - int indexDirection = Clock.CurrentTime < breaks[currentBreakIndex].StartTime ? -1 : (Clock.CurrentTime > breaks[currentBreakIndex].EndTime ? 1 : 0); + while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) + nearestBreakIndex++; - while (Clock.CurrentTime < breaks[currentBreakIndex].StartTime || Clock.CurrentTime > breaks[currentBreakIndex].EndTime) - { - currentBreakIndex += indexDirection; + while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) + nearestBreakIndex--; - if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) - break; - } - - if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) - { - isBreakTime.Value = false; - currentBreakIndex = 0; - return; - } - - isBreakTime.Value = true; + // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. + // If the overlay never shows (break.HasEffect is false), IsBreakTime should be false. + // We also assume that the overlay's fade out transform is "not break time". + var nearestBreak = breaks[nearestBreakIndex]; + isBreakTime.Value = nearestBreak.HasEffect && Clock.CurrentTime >= nearestBreak.StartTime && Clock.CurrentTime <= nearestBreak.EndTime - fade_duration; } private void initializeBreaks() From 1d6c321e14ff3c820ae2f3578f62e239cacbdd18 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 26 Jul 2019 08:34:18 +0930 Subject: [PATCH 040/645] Ensure we don't ping-pong nearestBreakIndex between breaks --- osu.Game/Screens/Play/BreakOverlay.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index aceacdbab1..50b2c97f59 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -136,11 +136,16 @@ namespace osu.Game.Screens.Play return; } - while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) - nearestBreakIndex++; - - while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) - nearestBreakIndex--; + if (Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) + { + while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) + nearestBreakIndex++; + } + else + { + while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) + nearestBreakIndex--; + } // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. // If the overlay never shows (break.HasEffect is false), IsBreakTime should be false. From a08d54eb06b2b2686152b9b04729ba3aabe65fdb Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 03:11:59 +0300 Subject: [PATCH 041/645] Remove unnecessary checks --- osu.Game/Screens/Play/BreakOverlay.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 50b2c97f59..aceacdbab1 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -136,16 +136,11 @@ namespace osu.Game.Screens.Play return; } - if (Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) - { - while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) - nearestBreakIndex++; - } - else - { - while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) - nearestBreakIndex--; - } + while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) + nearestBreakIndex++; + + while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) + nearestBreakIndex--; // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. // If the overlay never shows (break.HasEffect is false), IsBreakTime should be false. From b4c93b1777646c59507bed626c0c79d2e5f4f82b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 05:11:01 +0300 Subject: [PATCH 042/645] Use lookup direction than 2 while loops --- osu.Game/Screens/Play/BreakOverlay.cs | 31 +++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index aceacdbab1..9091e54159 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -31,7 +31,9 @@ namespace osu.Game.Screens.Play set { breaks = value; - nearestBreakIndex = 0; + + // reset index in case the new breaks list is smaller than last one + currentBreakIndex = 0; initializeBreaks(); } @@ -44,7 +46,7 @@ namespace osu.Game.Screens.Play /// public IBindable IsBreakTime => isBreakTime; - private int nearestBreakIndex; + private int currentBreakIndex; private readonly BindableBool isBreakTime = new BindableBool(); private readonly Container remainingTimeAdjustmentBox; @@ -133,20 +135,31 @@ namespace osu.Game.Screens.Play if (breaks == null || !breaks.Any()) { isBreakTime.Value = false; + currentBreakIndex = 0; return; } - while (nearestBreakIndex < breaks.Count - 1 && Clock.CurrentTime > breaks[nearestBreakIndex].EndTime) - nearestBreakIndex++; + var lastIndex = currentBreakIndex; + var lookupDirection = Clock.CurrentTime > breaks[lastIndex].EndTime ? 1 : (Clock.CurrentTime < breaks[lastIndex].StartTime ? -1 : 0); - while (nearestBreakIndex > 0 && Clock.CurrentTime < breaks[nearestBreakIndex].StartTime) - nearestBreakIndex--; + while (Clock.CurrentTime < breaks[currentBreakIndex].StartTime || Clock.CurrentTime > breaks[currentBreakIndex].EndTime) + { + currentBreakIndex += lookupDirection; + + // restore index if out of bounds + if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) + { + isBreakTime.Value = false; + currentBreakIndex = lastIndex; + return; + } + } // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. - // If the overlay never shows (break.HasEffect is false), IsBreakTime should be false. + // If the current break doesn't have effects, IsBreakTime should be false. // We also assume that the overlay's fade out transform is "not break time". - var nearestBreak = breaks[nearestBreakIndex]; - isBreakTime.Value = nearestBreak.HasEffect && Clock.CurrentTime >= nearestBreak.StartTime && Clock.CurrentTime <= nearestBreak.EndTime - fade_duration; + var currentBreak = breaks[currentBreakIndex]; + isBreakTime.Value = currentBreak.HasEffect && Clock.CurrentTime <= currentBreak.EndTime - fade_duration; } private void initializeBreaks() From 91fa8a6552c4591ad78b891be086159aa556baf6 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 08:09:18 +0300 Subject: [PATCH 043/645] Simplify null and any check --- osu.Game/Screens/Play/BreakOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 9091e54159..86a991c02e 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -132,7 +132,7 @@ namespace osu.Game.Screens.Play private void updateBreakTimeBindable() { - if (breaks == null || !breaks.Any()) + if (breaks?.Any() != true) { isBreakTime.Value = false; currentBreakIndex = 0; From 806d41daf499df87917abaf0c3dd8772ee557e75 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 08:11:13 +0300 Subject: [PATCH 044/645] Add function to reset break index --- osu.Game/Screens/Play/BreakOverlay.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 86a991c02e..99361a5bd7 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play breaks = value; // reset index in case the new breaks list is smaller than last one - currentBreakIndex = 0; + resetBreakIndex(); initializeBreaks(); } @@ -130,12 +130,17 @@ namespace osu.Game.Screens.Play updateBreakTimeBindable(); } + private void resetBreakIndex() + { + isBreakTime.Value = false; + currentBreakIndex = 0; + } + private void updateBreakTimeBindable() { if (breaks?.Any() != true) { - isBreakTime.Value = false; - currentBreakIndex = 0; + resetBreakIndex(); return; } From 3fa6804501a0d417feb4a876160fc83731101140 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 08:12:32 +0300 Subject: [PATCH 045/645] Use better loops for moving index Easy to read, suggested by peppy --- osu.Game/Screens/Play/BreakOverlay.cs | 31 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 99361a5bd7..f3decb38fb 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -144,19 +144,28 @@ namespace osu.Game.Screens.Play return; } - var lastIndex = currentBreakIndex; - var lookupDirection = Clock.CurrentTime > breaks[lastIndex].EndTime ? 1 : (Clock.CurrentTime < breaks[lastIndex].StartTime ? -1 : 0); + var time = Clock.CurrentTime; - while (Clock.CurrentTime < breaks[currentBreakIndex].StartTime || Clock.CurrentTime > breaks[currentBreakIndex].EndTime) + if (time > breaks[currentBreakIndex].EndTime) { - currentBreakIndex += lookupDirection; - - // restore index if out of bounds - if (currentBreakIndex < 0 || currentBreakIndex >= breaks.Count) + for (int i = currentBreakIndex; i < breaks.Count; i++) { - isBreakTime.Value = false; - currentBreakIndex = lastIndex; - return; + if (time <= breaks[i].EndTime) + { + currentBreakIndex = i; + break; + } + } + } + else if (time < breaks[currentBreakIndex].StartTime) + { + for (int i = currentBreakIndex; i >= 0; i--) + { + if (time >= breaks[i].StartTime) + { + currentBreakIndex = i; + break; + } } } @@ -164,7 +173,7 @@ namespace osu.Game.Screens.Play // If the current break doesn't have effects, IsBreakTime should be false. // We also assume that the overlay's fade out transform is "not break time". var currentBreak = breaks[currentBreakIndex]; - isBreakTime.Value = currentBreak.HasEffect && Clock.CurrentTime <= currentBreak.EndTime - fade_duration; + isBreakTime.Value = currentBreak.HasEffect && time >= currentBreak.StartTime && time <= currentBreak.EndTime - fade_duration; } private void initializeBreaks() From 6fac716ec704f1c07436d57a2979e95f0b504966 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 08:15:46 +0300 Subject: [PATCH 046/645] Use container instead of fill flow --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index ffa822d175..85f69bf058 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -27,13 +27,17 @@ namespace osu.Game.Tests.Visual.Gameplay public TestSceneBreakOverlay() { SpriteText breakTimeText; - Child = new FillFlowContainer + Child = new Container { RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, Children = new Drawable[] { - breakTimeText = new SpriteText(), + breakTimeText = new SpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Bottom = 35 }, + }, breakOverlay = new BreakOverlay(true) } }; From 5a94a223147b4e774452154b41ed2c4794d30615 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 09:17:39 +0300 Subject: [PATCH 047/645] Add a quick check if we're not in a break with current index --- osu.Game/Screens/Play/BreakOverlay.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index f3decb38fb..8f07b90b30 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -146,6 +146,16 @@ namespace osu.Game.Screens.Play var time = Clock.CurrentTime; + if (currentBreakIndex < breaks.Count - 1) + { + // Quick check if we're not in a break with our current index. + if (time > breaks[currentBreakIndex].EndTime && time < breaks[currentBreakIndex + 1].StartTime) + { + isBreakTime.Value = false; + return; + } + } + if (time > breaks[currentBreakIndex].EndTime) { for (int i = currentBreakIndex; i < breaks.Count; i++) From 4c9e8527d86b57c65774b89c7db6ae552c9ae64b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 26 Jul 2019 09:24:53 +0300 Subject: [PATCH 048/645] Modify global index directly in the for loop Moves the global index to a near break if not in a break yet --- osu.Game/Screens/Play/BreakOverlay.cs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 8f07b90b30..005cdd36d7 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -158,25 +158,15 @@ namespace osu.Game.Screens.Play if (time > breaks[currentBreakIndex].EndTime) { - for (int i = currentBreakIndex; i < breaks.Count; i++) - { - if (time <= breaks[i].EndTime) - { - currentBreakIndex = i; + for (; currentBreakIndex < breaks.Count; currentBreakIndex++) + if (time <= breaks[currentBreakIndex].EndTime) break; - } - } } else if (time < breaks[currentBreakIndex].StartTime) { - for (int i = currentBreakIndex; i >= 0; i--) - { - if (time >= breaks[i].StartTime) - { - currentBreakIndex = i; + for (; currentBreakIndex >= 0; currentBreakIndex--) + if (time >= breaks[currentBreakIndex].StartTime) break; - } - } } // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. From 46f17885c6378aaaeb19e7cd0043629cefa494ff Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 27 Jul 2019 15:51:14 +0300 Subject: [PATCH 049/645] Rewrite break overlay test --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 180 +++++++++++------- 1 file changed, 107 insertions(+), 73 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index 85f69bf058..bbebd62b26 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -3,11 +3,10 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; +using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; @@ -21,96 +20,131 @@ namespace osu.Game.Tests.Visual.Gameplay typeof(BreakOverlay), }; - private readonly BreakOverlay breakOverlay; - private readonly IBindable isBreakTimeBindable = new BindableBool(); + private readonly BreakOverlay breakOverlay, manualBreakOverlay; + private readonly ManualClock manualClock = new ManualClock(); + + private readonly IReadOnlyList testBreaks = new List + { + new BreakPeriod + { + StartTime = 1000, + EndTime = 5000, + }, + new BreakPeriod + { + StartTime = 6000, + EndTime = 13500, + }, + }; public TestSceneBreakOverlay() { - SpriteText breakTimeText; - Child = new Container + Add(breakOverlay = new BreakOverlay(true)); + Add(manualBreakOverlay = new BreakOverlay(true) { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - breakTimeText = new SpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Margin = new MarginPadding { Bottom = 35 }, - }, - breakOverlay = new BreakOverlay(true) - } - }; - - isBreakTimeBindable.BindTo(breakOverlay.IsBreakTime); - isBreakTimeBindable.BindValueChanged(e => breakTimeText.Text = $"IsBreakTime: {e.NewValue}", true); - - AddStep("2s break", () => startBreak(2000)); - AddStep("5s break", () => startBreak(5000)); - AddStep("10s break", () => startBreak(10000)); - AddStep("15s break", () => startBreak(15000)); - AddStep("2s, 2s", startMultipleBreaks); - AddStep("0.5s, 0.7s, 1s, 2s", startAnotherMultipleBreaks); + Alpha = 0, + Clock = new FramedClock(manualClock), + }); } - private void startBreak(double duration) + [Test] + public void TestShowBreaks() { - breakOverlay.Breaks = new List + loadClockStep(false); + + addShowBreakStep(2); + addShowBreakStep(5); + addShowBreakStep(15); + } + + [Test] + public void TestNoEffectsBreak() + { + var shortBreak = new BreakPeriod { EndTime = 500 }; + + loadClockStep(true); + AddStep("start short break", () => manualBreakOverlay.Breaks = new[] { shortBreak }); + + seekBreakStep("seek back to 0", 0, false); + addBreakSeeks(shortBreak, false); + } + + [Test] + public void TestMultipleBreaks() + { + loadClockStep(true); + AddStep("start multiple breaks", () => manualBreakOverlay.Breaks = testBreaks); + + seekBreakStep("seek back to 0", 0, false); + foreach (var b in testBreaks) + addBreakSeeks(b, false); + } + + [Test] + public void TestRewindBreaks() + { + loadClockStep(true); + AddStep("start multiple breaks in rewind", () => manualBreakOverlay.Breaks = testBreaks); + + seekBreakStep("seek back to 0", 0, false); + foreach (var b in testBreaks.Reverse()) + addBreakSeeks(b, true); + } + + [Test] + public void TestSkipBreaks() + { + loadClockStep(true); + AddStep("start multiple breaks with skipping", () => manualBreakOverlay.Breaks = testBreaks); + + var b = testBreaks.Last(); + seekBreakStep("seek back to 0", 0, false); + addBreakSeeks(b, false); + } + + private void addShowBreakStep(double seconds) + { + AddStep($"show '{seconds}s' break", () => breakOverlay.Breaks = new List { new BreakPeriod { StartTime = Clock.CurrentTime, - EndTime = Clock.CurrentTime + duration, + EndTime = Clock.CurrentTime + seconds * 1000, } - }; + }); } - private void startMultipleBreaks() + private void loadClockStep(bool loadManual) { - double currentTime = Clock.CurrentTime; - - breakOverlay.Breaks = new List + AddStep($"load {(loadManual ? "manual" : "normal")} clock", () => { - new BreakPeriod - { - StartTime = currentTime, - EndTime = currentTime + 2000, - }, - new BreakPeriod - { - StartTime = currentTime + 4000, - EndTime = currentTime + 6000, - } - }; + breakOverlay.FadeTo(loadManual ? 0 : 1); + manualBreakOverlay.FadeTo(loadManual ? 1 : 0); + }); } - private void startAnotherMultipleBreaks() + private void addBreakSeeks(BreakPeriod b, bool isReversed) { - double currentTime = Clock.CurrentTime; - - breakOverlay.Breaks = new List + if (isReversed) { - new BreakPeriod // Duration is less than 650 - too short to appear - { - StartTime = currentTime, - EndTime = currentTime + 500, - }, - new BreakPeriod - { - StartTime = currentTime + 1500, - EndTime = currentTime + 2200, - }, - new BreakPeriod - { - StartTime = currentTime + 3200, - EndTime = currentTime + 4200, - }, - new BreakPeriod - { - StartTime = currentTime + 5200, - EndTime = currentTime + 7200, - } - }; + seekBreakStep("seek to break after end", b.EndTime + 500, false); + seekBreakStep("seek to break end", b.EndTime, false); + seekBreakStep("seek to break middle", b.StartTime + b.Duration / 2, b.HasEffect); + seekBreakStep("seek to break start", b.StartTime, b.HasEffect); + } + else + { + seekBreakStep("seek to break start", b.StartTime, b.HasEffect); + seekBreakStep("seek to break middle", b.StartTime + b.Duration / 2, b.HasEffect); + seekBreakStep("seek to break end", b.EndTime, false); + seekBreakStep("seek to break after end", b.EndTime + 500, false); + } + } + + private void seekBreakStep(string seekStepDescription, double time, bool onBreak) + { + AddStep(seekStepDescription, () => manualClock.CurrentTime = time); + AddAssert($"is{(!onBreak ? " not " : " ")}break time", () => manualBreakOverlay.IsBreakTime.Value == onBreak); } } } From 6c580ac9d5c4456bc91a1f8a51f4d92457167669 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 27 Jul 2019 15:52:01 +0300 Subject: [PATCH 050/645] Use while loops instead --- osu.Game/Screens/Play/BreakOverlay.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index f96c176104..532109d14b 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -158,15 +158,13 @@ namespace osu.Game.Screens.Play if (time > breaks[currentBreakIndex].EndTime) { - for (; currentBreakIndex < breaks.Count; currentBreakIndex++) - if (time <= breaks[currentBreakIndex].EndTime) - break; + while (time > breaks[currentBreakIndex].EndTime && currentBreakIndex < breaks.Count - 1) + currentBreakIndex++; } else if (time < breaks[currentBreakIndex].StartTime) { - for (; currentBreakIndex >= 0; currentBreakIndex--) - if (time >= breaks[currentBreakIndex].StartTime) - break; + while (time < breaks[currentBreakIndex].StartTime && currentBreakIndex > 0) + currentBreakIndex--; } // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. From 95b568eb4646c45b2169899d599114f86c350865 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 27 Jul 2019 15:52:30 +0300 Subject: [PATCH 051/645] Remove unnecessary condition --- osu.Game/Screens/Play/BreakOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 532109d14b..7e87c44259 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -161,7 +161,7 @@ namespace osu.Game.Screens.Play while (time > breaks[currentBreakIndex].EndTime && currentBreakIndex < breaks.Count - 1) currentBreakIndex++; } - else if (time < breaks[currentBreakIndex].StartTime) + else { while (time < breaks[currentBreakIndex].StartTime && currentBreakIndex > 0) currentBreakIndex--; From 4d49b38277ec35df3723eac519e6cba80f681e1a Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 28 Jul 2019 05:21:27 +0300 Subject: [PATCH 052/645] Add a function for loading a list of breaks --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index bbebd62b26..c238f42b60 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -63,9 +63,8 @@ namespace osu.Game.Tests.Visual.Gameplay var shortBreak = new BreakPeriod { EndTime = 500 }; loadClockStep(true); - AddStep("start short break", () => manualBreakOverlay.Breaks = new[] { shortBreak }); + loadBreaksStep("short break", new[] { shortBreak }); - seekBreakStep("seek back to 0", 0, false); addBreakSeeks(shortBreak, false); } @@ -73,9 +72,8 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestMultipleBreaks() { loadClockStep(true); - AddStep("start multiple breaks", () => manualBreakOverlay.Breaks = testBreaks); + loadBreaksStep("multiple breaks", testBreaks); - seekBreakStep("seek back to 0", 0, false); foreach (var b in testBreaks) addBreakSeeks(b, false); } @@ -84,9 +82,8 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestRewindBreaks() { loadClockStep(true); - AddStep("start multiple breaks in rewind", () => manualBreakOverlay.Breaks = testBreaks); + loadBreaksStep("multiple breaks", testBreaks); - seekBreakStep("seek back to 0", 0, false); foreach (var b in testBreaks.Reverse()) addBreakSeeks(b, true); } @@ -95,10 +92,9 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestSkipBreaks() { loadClockStep(true); - AddStep("start multiple breaks with skipping", () => manualBreakOverlay.Breaks = testBreaks); + loadBreaksStep("multiple breaks", testBreaks); var b = testBreaks.Last(); - seekBreakStep("seek back to 0", 0, false); addBreakSeeks(b, false); } @@ -123,6 +119,12 @@ namespace osu.Game.Tests.Visual.Gameplay }); } + private void loadBreaksStep(string breakDescription, IReadOnlyList breaks) + { + AddStep($"load {breakDescription}", () => manualBreakOverlay.Breaks = breaks); + seekBreakStep("seek back to 0", 0, false); + } + private void addBreakSeeks(BreakPeriod b, bool isReversed) { if (isReversed) From 4143bafd67ac14e61b98855797a96bec2fac4647 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 28 Jul 2019 05:22:09 +0300 Subject: [PATCH 053/645] More simplifies --- osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index c238f42b60..d2db92c855 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Gameplay }; private readonly BreakOverlay breakOverlay, manualBreakOverlay; - private readonly ManualClock manualClock = new ManualClock(); + private readonly ManualClock manualClock; private readonly IReadOnlyList testBreaks = new List { @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Gameplay Add(manualBreakOverlay = new BreakOverlay(true) { Alpha = 0, - Clock = new FramedClock(manualClock), + Clock = new FramedClock(manualClock = new ManualClock()), }); } @@ -94,8 +94,7 @@ namespace osu.Game.Tests.Visual.Gameplay loadClockStep(true); loadBreaksStep("multiple breaks", testBreaks); - var b = testBreaks.Last(); - addBreakSeeks(b, false); + addBreakSeeks(testBreaks.Last(), false); } private void addShowBreakStep(double seconds) From 1dd3a6630082b0e0b88b43be089f471b54d19aec Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 28 Jul 2019 09:16:19 +0300 Subject: [PATCH 054/645] Remove unnecessary index resets --- osu.Game/Screens/Play/BreakOverlay.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 7e87c44259..726c825c84 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -33,7 +33,8 @@ namespace osu.Game.Screens.Play breaks = value; // reset index in case the new breaks list is smaller than last one - resetBreakIndex(); + isBreakTime.Value = false; + currentBreakIndex = 0; initializeBreaks(); } @@ -126,23 +127,13 @@ namespace osu.Game.Screens.Play protected override void Update() { base.Update(); - updateBreakTimeBindable(); } - private void resetBreakIndex() - { - isBreakTime.Value = false; - currentBreakIndex = 0; - } - private void updateBreakTimeBindable() { if (breaks?.Any() != true) - { - resetBreakIndex(); return; - } var time = Clock.CurrentTime; From 5bf0277fd401b5d668bd8939ba7a41264a1ca6c9 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 28 Jul 2019 09:17:13 +0300 Subject: [PATCH 055/645] Remove unnecessary quick check Not saving for anything --- osu.Game/Screens/Play/BreakOverlay.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 726c825c84..e3e4014eb3 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -137,16 +137,6 @@ namespace osu.Game.Screens.Play var time = Clock.CurrentTime; - if (currentBreakIndex < breaks.Count - 1) - { - // Quick check if we're not in a break with our current index. - if (time > breaks[currentBreakIndex].EndTime && time < breaks[currentBreakIndex + 1].StartTime) - { - isBreakTime.Value = false; - return; - } - } - if (time > breaks[currentBreakIndex].EndTime) { while (time > breaks[currentBreakIndex].EndTime && currentBreakIndex < breaks.Count - 1) From 37c32659429787f33f3a78005142d5803feb1ac8 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 28 Jul 2019 09:21:54 +0300 Subject: [PATCH 056/645] Manually call the update function on retrieving IsBreakTime value --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index d2db92c855..890c575eb6 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; -using osu.Framework.Graphics; +using osu.Framework.Bindables; using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; @@ -20,8 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay typeof(BreakOverlay), }; - private readonly BreakOverlay breakOverlay, manualBreakOverlay; private readonly ManualClock manualClock; + private readonly BreakOverlay breakOverlay; + private readonly TestBreakOverlay manualBreakOverlay; private readonly IReadOnlyList testBreaks = new List { @@ -40,7 +41,7 @@ namespace osu.Game.Tests.Visual.Gameplay public TestSceneBreakOverlay() { Add(breakOverlay = new BreakOverlay(true)); - Add(manualBreakOverlay = new BreakOverlay(true) + Add(manualBreakOverlay = new TestBreakOverlay(true) { Alpha = 0, Clock = new FramedClock(manualClock = new ManualClock()), @@ -147,5 +148,24 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep(seekStepDescription, () => manualClock.CurrentTime = time); AddAssert($"is{(!onBreak ? " not " : " ")}break time", () => manualBreakOverlay.IsBreakTime.Value == onBreak); } + + private class TestBreakOverlay : BreakOverlay + { + public new IBindable IsBreakTime + { + get + { + // Manually call the update function as it might take up to 2 frames for an automatic update to happen + Update(); + + return base.IsBreakTime; + } + } + + public TestBreakOverlay(bool letterboxing) + : base(letterboxing) + { + } + } } } From c9e45f8cdc2e5b26e6d099e21bf2e7d731fa2dab Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 28 Jul 2019 09:27:02 +0300 Subject: [PATCH 057/645] Assign clocks instead of creating 2 separate overlays --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index 890c575eb6..eaae647dbc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -20,9 +20,7 @@ namespace osu.Game.Tests.Visual.Gameplay typeof(BreakOverlay), }; - private readonly ManualClock manualClock; - private readonly BreakOverlay breakOverlay; - private readonly TestBreakOverlay manualBreakOverlay; + private readonly TestBreakOverlay breakOverlay; private readonly IReadOnlyList testBreaks = new List { @@ -40,12 +38,7 @@ namespace osu.Game.Tests.Visual.Gameplay public TestSceneBreakOverlay() { - Add(breakOverlay = new BreakOverlay(true)); - Add(manualBreakOverlay = new TestBreakOverlay(true) - { - Alpha = 0, - Clock = new FramedClock(manualClock = new ManualClock()), - }); + Add(breakOverlay = new TestBreakOverlay(true)); } [Test] @@ -112,16 +105,12 @@ namespace osu.Game.Tests.Visual.Gameplay private void loadClockStep(bool loadManual) { - AddStep($"load {(loadManual ? "manual" : "normal")} clock", () => - { - breakOverlay.FadeTo(loadManual ? 0 : 1); - manualBreakOverlay.FadeTo(loadManual ? 1 : 0); - }); + AddStep($"load {(loadManual ? "manual" : "normal")} clock", () => breakOverlay.SwitchClock(loadManual)); } private void loadBreaksStep(string breakDescription, IReadOnlyList breaks) { - AddStep($"load {breakDescription}", () => manualBreakOverlay.Breaks = breaks); + AddStep($"load {breakDescription}", () => breakOverlay.Breaks = breaks); seekBreakStep("seek back to 0", 0, false); } @@ -145,12 +134,22 @@ namespace osu.Game.Tests.Visual.Gameplay private void seekBreakStep(string seekStepDescription, double time, bool onBreak) { - AddStep(seekStepDescription, () => manualClock.CurrentTime = time); - AddAssert($"is{(!onBreak ? " not " : " ")}break time", () => manualBreakOverlay.IsBreakTime.Value == onBreak); + AddStep(seekStepDescription, () => breakOverlay.ManualClockTime = time); + AddAssert($"is{(!onBreak ? " not " : " ")}break time", () => breakOverlay.IsBreakTime.Value == onBreak); } private class TestBreakOverlay : BreakOverlay { + private readonly FramedClock framedManualClock; + private readonly ManualClock manualClock; + private IFrameBasedClock normalClock; + + public double ManualClockTime + { + get => manualClock.CurrentTime; + set => manualClock.CurrentTime = value; + } + public new IBindable IsBreakTime { get @@ -165,6 +164,15 @@ namespace osu.Game.Tests.Visual.Gameplay public TestBreakOverlay(bool letterboxing) : base(letterboxing) { + framedManualClock = new FramedClock(manualClock = new ManualClock()); + } + + public void SwitchClock(bool setManual) => Clock = setManual ? framedManualClock : normalClock; + + protected override void LoadComplete() + { + base.LoadComplete(); + normalClock = Clock; } } } From f4effd12c301ecece374df443cc08bd0e2bf2958 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sun, 28 Jul 2019 21:04:55 +0200 Subject: [PATCH 058/645] make legacy skins animatable --- osu.Game/Skinning/LegacySkin.cs | 38 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 513a024a36..24c6c9e4ec 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; +using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; @@ -52,22 +53,29 @@ namespace osu.Game.Skinning public override Drawable GetDrawableComponent(string componentName) { + bool animatable = false; + (bool looping, double frametime) animationData = (false, 1000 / 60d); + switch (componentName) { case "Play/Miss": componentName = "hit0"; + animatable = true; break; case "Play/Meh": componentName = "hit50"; + animatable = true; break; case "Play/Good": componentName = "hit100"; + animatable = true; break; case "Play/Great": componentName = "hit300"; + animatable = true; break; case "Play/osu/number-text": @@ -81,15 +89,31 @@ namespace osu.Game.Skinning }; } - // temporary allowance is given for skins the fact that stable handles non-animatable items such as hitcircles (incorrectly) - // by (incorrectly) displaying the first frame of animation rather than the non-animated version. - // users have used this to "hide" certain elements like hit300. - var texture = GetTexture($"{componentName}-0") ?? GetTexture(componentName); + var texture = GetTexture($"{componentName}-0"); - if (texture == null) - return null; + if (texture != null && animatable) + { + var animation = new TextureAnimation { DefaultFrameLength = animationData.frametime }; - return new Sprite { Texture = texture }; + for (int i = 1; texture != null; i++) + { + animation.AddFrame(texture); + texture = GetTexture($"{componentName}-{i}"); + } + + animation.Repeat = animationData.looping; + + return animation; + } + else + { + texture = GetTexture(componentName); + + if (texture == null) + return null; + + return new Sprite { Texture = texture }; + } } public override Texture GetTexture(string componentName) From 0635680db52db1d6063c09dbdf88fa459a07b64f Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 29 Jul 2019 11:49:59 +0200 Subject: [PATCH 059/645] fix some code quality --- osu.Game/Skinning/LegacySkin.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 24c6c9e4ec..c9c64c96f2 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -54,28 +54,33 @@ namespace osu.Game.Skinning public override Drawable GetDrawableComponent(string componentName) { bool animatable = false; - (bool looping, double frametime) animationData = (false, 1000 / 60d); + bool looping = true; + const double frametime = 1000 / 60d; switch (componentName) { case "Play/Miss": componentName = "hit0"; animatable = true; + looping = false; break; case "Play/Meh": componentName = "hit50"; animatable = true; + looping = false; break; case "Play/Good": componentName = "hit100"; animatable = true; + looping = false; break; case "Play/Great": componentName = "hit300"; animatable = true; + looping = false; break; case "Play/osu/number-text": @@ -93,7 +98,7 @@ namespace osu.Game.Skinning if (texture != null && animatable) { - var animation = new TextureAnimation { DefaultFrameLength = animationData.frametime }; + var animation = new TextureAnimation { DefaultFrameLength = frametime }; for (int i = 1; texture != null; i++) { @@ -101,7 +106,9 @@ namespace osu.Game.Skinning texture = GetTexture($"{componentName}-{i}"); } - animation.Repeat = animationData.looping; + // This comment can be removed once we have components which are looping + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + animation.Repeat = looping; return animation; } @@ -109,10 +116,7 @@ namespace osu.Game.Skinning { texture = GetTexture(componentName); - if (texture == null) - return null; - - return new Sprite { Texture = texture }; + return texture == null ? null : new Sprite { Texture = texture }; } } From 195609816674f0428a281d12e4c0757cba08169a Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 30 Jul 2019 13:58:08 +0900 Subject: [PATCH 060/645] Add a fallback for humanizer localization failure --- osu.Game/Graphics/DrawableDate.cs | 4 +-- .../BeatmapSet/Scores/TopScoreUserSection.cs | 4 +-- osu.Game/Utils/HumanizerUtils.cs | 36 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Utils/HumanizerUtils.cs diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 125c994c92..533f02af7b 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -2,11 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using System; -using Humanizer; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Sprites; +using osu.Game.Utils; namespace osu.Game.Graphics { @@ -71,7 +71,7 @@ namespace osu.Game.Graphics Scheduler.AddDelayed(updateTimeWithReschedule, timeUntilNextUpdate); } - protected virtual string Format() => Date.Humanize(); + protected virtual string Format() => HumanizerUtils.Humanize(Date); private void updateTime() => Text = Format(); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index ffc39e5af2..38a909411a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using Humanizer; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -14,6 +13,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; using osu.Game.Users.Drawables; +using osu.Game.Utils; using osuTK; using osuTK.Graphics; @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { avatar.User = value.User; flag.Country = value.User.Country; - date.Text = $@"achieved {value.Date.Humanize()}"; + date.Text = $@"achieved {HumanizerUtils.Humanize(value.Date)}"; usernameText.Clear(); usernameText.AddUserLink(value.User); diff --git a/osu.Game/Utils/HumanizerUtils.cs b/osu.Game/Utils/HumanizerUtils.cs new file mode 100644 index 0000000000..398c76a09f --- /dev/null +++ b/osu.Game/Utils/HumanizerUtils.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Globalization; +using Humanizer; + +namespace osu.Game.Utils +{ + public static class HumanizerUtils + { + /// + /// Humanizes a string using the system culture, then falls back if one cannot be found. + /// + /// A localization lookup failure will throw an exception of type + /// + /// + /// The time to humanize. + /// A humanized string of the given time. + public static string Humanize(DateTimeOffset dateTimeOffset) + { + string offset; + + try + { + offset = dateTimeOffset.Humanize(); + } + catch (ArgumentException) + { + offset = dateTimeOffset.Humanize(culture: new CultureInfo("en-US")); + } + + return offset; + } + } +} From e8e5b2742d545d1344769afe965073aaeae00e3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 30 Jul 2019 18:31:57 +0900 Subject: [PATCH 061/645] Fix manual clock usage --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 65 +++++++++---------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index eaae647dbc..ed5861b47d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; -using osu.Framework.Bindables; using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; using osu.Game.Screens.Play; @@ -44,7 +43,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestShowBreaks() { - loadClockStep(false); + setClock(false); addShowBreakStep(2); addShowBreakStep(5); @@ -56,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var shortBreak = new BreakPeriod { EndTime = 500 }; - loadClockStep(true); + setClock(true); loadBreaksStep("short break", new[] { shortBreak }); addBreakSeeks(shortBreak, false); @@ -65,7 +64,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestMultipleBreaks() { - loadClockStep(true); + setClock(true); loadBreaksStep("multiple breaks", testBreaks); foreach (var b in testBreaks) @@ -75,7 +74,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestRewindBreaks() { - loadClockStep(true); + setClock(true); loadBreaksStep("multiple breaks", testBreaks); foreach (var b in testBreaks.Reverse()) @@ -85,7 +84,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestSkipBreaks() { - loadClockStep(true); + setClock(true); loadBreaksStep("multiple breaks", testBreaks); addBreakSeeks(testBreaks.Last(), false); @@ -103,46 +102,50 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private void loadClockStep(bool loadManual) + private void setClock(bool useManual) { - AddStep($"load {(loadManual ? "manual" : "normal")} clock", () => breakOverlay.SwitchClock(loadManual)); + AddStep($"set {(useManual ? "manual" : "realtime")} clock", () => breakOverlay.SwitchClock(useManual)); } private void loadBreaksStep(string breakDescription, IReadOnlyList breaks) { AddStep($"load {breakDescription}", () => breakOverlay.Breaks = breaks); - seekBreakStep("seek back to 0", 0, false); + seekAndAssertBreak("seek back to 0", 0, false); } private void addBreakSeeks(BreakPeriod b, bool isReversed) { if (isReversed) { - seekBreakStep("seek to break after end", b.EndTime + 500, false); - seekBreakStep("seek to break end", b.EndTime, false); - seekBreakStep("seek to break middle", b.StartTime + b.Duration / 2, b.HasEffect); - seekBreakStep("seek to break start", b.StartTime, b.HasEffect); + seekAndAssertBreak("seek to break after end", b.EndTime + 500, false); + seekAndAssertBreak("seek to break end", b.EndTime, false); + seekAndAssertBreak("seek to break middle", b.StartTime + b.Duration / 2, b.HasEffect); + seekAndAssertBreak("seek to break start", b.StartTime, b.HasEffect); } else { - seekBreakStep("seek to break start", b.StartTime, b.HasEffect); - seekBreakStep("seek to break middle", b.StartTime + b.Duration / 2, b.HasEffect); - seekBreakStep("seek to break end", b.EndTime, false); - seekBreakStep("seek to break after end", b.EndTime + 500, false); + seekAndAssertBreak("seek to break start", b.StartTime, b.HasEffect); + seekAndAssertBreak("seek to break middle", b.StartTime + b.Duration / 2, b.HasEffect); + seekAndAssertBreak("seek to break end", b.EndTime, false); + seekAndAssertBreak("seek to break after end", b.EndTime + 500, false); } } - private void seekBreakStep(string seekStepDescription, double time, bool onBreak) + private void seekAndAssertBreak(string seekStepDescription, double time, bool shouldBeBreak) { AddStep(seekStepDescription, () => breakOverlay.ManualClockTime = time); - AddAssert($"is{(!onBreak ? " not " : " ")}break time", () => breakOverlay.IsBreakTime.Value == onBreak); + AddAssert($"is{(!shouldBeBreak ? " not" : string.Empty)} break time", () => + { + breakOverlay.ProgressTime(); + return breakOverlay.IsBreakTime.Value == shouldBeBreak; + }); } private class TestBreakOverlay : BreakOverlay { private readonly FramedClock framedManualClock; private readonly ManualClock manualClock; - private IFrameBasedClock normalClock; + private IFrameBasedClock originalClock; public double ManualClockTime { @@ -150,29 +153,25 @@ namespace osu.Game.Tests.Visual.Gameplay set => manualClock.CurrentTime = value; } - public new IBindable IsBreakTime - { - get - { - // Manually call the update function as it might take up to 2 frames for an automatic update to happen - Update(); - - return base.IsBreakTime; - } - } - public TestBreakOverlay(bool letterboxing) : base(letterboxing) { framedManualClock = new FramedClock(manualClock = new ManualClock()); + ProcessCustomClock = false; } - public void SwitchClock(bool setManual) => Clock = setManual ? framedManualClock : normalClock; + public void ProgressTime() + { + framedManualClock.ProcessFrame(); + Update(); + } + + public void SwitchClock(bool setManual) => Clock = setManual ? framedManualClock : originalClock; protected override void LoadComplete() { base.LoadComplete(); - normalClock = Clock; + originalClock = Clock; } } } From e6e315e07bd952625a01bdd9c1578224d41d3dd0 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 30 Jul 2019 13:29:41 +0300 Subject: [PATCH 062/645] Expose current break index --- .../Visual/Gameplay/TestSceneBreakOverlay.cs | 2 ++ osu.Game/Screens/Play/BreakOverlay.cs | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index ed5861b47d..bb89c85e93 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -147,6 +147,8 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly ManualClock manualClock; private IFrameBasedClock originalClock; + public new int CurrentBreakIndex => base.CurrentBreakIndex; + public double ManualClockTime { get => manualClock.CurrentTime; diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index e3e4014eb3..93267e5f2a 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Play // reset index in case the new breaks list is smaller than last one isBreakTime.Value = false; - currentBreakIndex = 0; + CurrentBreakIndex = 0; initializeBreaks(); } @@ -47,7 +47,8 @@ namespace osu.Game.Screens.Play /// public IBindable IsBreakTime => isBreakTime; - private int currentBreakIndex; + protected int CurrentBreakIndex; + private readonly BindableBool isBreakTime = new BindableBool(); private readonly Container remainingTimeAdjustmentBox; @@ -137,21 +138,21 @@ namespace osu.Game.Screens.Play var time = Clock.CurrentTime; - if (time > breaks[currentBreakIndex].EndTime) + if (time > breaks[CurrentBreakIndex].EndTime) { - while (time > breaks[currentBreakIndex].EndTime && currentBreakIndex < breaks.Count - 1) - currentBreakIndex++; + while (time > breaks[CurrentBreakIndex].EndTime && CurrentBreakIndex < breaks.Count - 1) + CurrentBreakIndex++; } else { - while (time < breaks[currentBreakIndex].StartTime && currentBreakIndex > 0) - currentBreakIndex--; + while (time < breaks[CurrentBreakIndex].StartTime && CurrentBreakIndex > 0) + CurrentBreakIndex--; } // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. // If the current break doesn't have effects, IsBreakTime should be false. // We also assume that the overlay's fade out transform is "not break time". - var currentBreak = breaks[currentBreakIndex]; + var currentBreak = breaks[CurrentBreakIndex]; isBreakTime.Value = currentBreak.HasEffect && time >= currentBreak.StartTime && time <= currentBreak.EndTime - fade_duration; } From f2ab259c21aefc7900f983b1cffc087229f0a349 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 30 Jul 2019 13:30:26 +0300 Subject: [PATCH 063/645] Add an assert if current break index has skipped a break --- osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs index bb89c85e93..879e15c548 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakOverlay.cs @@ -87,7 +87,12 @@ namespace osu.Game.Tests.Visual.Gameplay setClock(true); loadBreaksStep("multiple breaks", testBreaks); - addBreakSeeks(testBreaks.Last(), false); + seekAndAssertBreak("seek to break start", testBreaks[1].StartTime, true); + AddAssert("is skipped to break #2", () => breakOverlay.CurrentBreakIndex == 1); + + seekAndAssertBreak("seek to break middle", testBreaks[1].StartTime + testBreaks[1].Duration / 2, true); + seekAndAssertBreak("seek to break end", testBreaks[1].EndTime, false); + seekAndAssertBreak("seek to break after end", testBreaks[1].EndTime + 500, false); } private void addShowBreakStep(double seconds) From 3af1aaeabe8571674c01f721e01dd0628b89edbe Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 31 Jul 2019 15:19:02 +0300 Subject: [PATCH 064/645] Unsubscribe from Completed event on old beatmap --- osu.Game/OsuGame.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e71dd67bf2..431e6c91f9 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,8 +307,11 @@ namespace osu.Game if (nextBeatmap?.Track != null) nextBeatmap.Track.Completed += currentTrackCompleted; - beatmap.OldValue?.Dispose(); + var oldBeatmap = beatmap.OldValue; + if (oldBeatmap?.Track != null) + oldBeatmap.Track.Completed -= currentTrackCompleted; + oldBeatmap?.Dispose(); nextBeatmap?.LoadBeatmapAsync(); } From 0f1dd8a46e4d5e43e0c1e138886d790a84539cea Mon Sep 17 00:00:00 2001 From: DTSDAO Date: Wed, 31 Jul 2019 21:44:57 +0800 Subject: [PATCH 065/645] Undo #5533 for causing crashes --- osu.iOS/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 4fbc67e27b..0775d1522d 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -14,8 +14,6 @@ 0.1.0 LSRequiresIPhoneOS - LSSupportsOpeningDocumentsInPlace - MinimumOSVersion 10.0 UIDeviceFamily From 7b95741dab566f5ef85ae01d1b169dbd3e9f18a0 Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 31 Jul 2019 21:55:56 +0200 Subject: [PATCH 066/645] fix crash and add some tests - still missing special skin textures --- .../Resources/default-skin/hit0@2x.png | Bin 0 -> 16112 bytes .../Resources/default-skin/hit100@2x.png | Bin 0 -> 31228 bytes .../Resources/default-skin/hit100k@2x.png | Bin 0 -> 21318 bytes .../Resources/default-skin/hit300@2x.png | Bin 0 -> 36873 bytes .../Resources/default-skin/hit300g@2x.png | Bin 0 -> 39840 bytes .../Resources/default-skin/hit50@2x.png | Bin 0 -> 26015 bytes .../Resources/metrics-skin/hit0@2x.PNG | Bin 0 -> 9492 bytes .../Resources/metrics-skin/hit100@2x.PNG | Bin 0 -> 8371 bytes .../Resources/metrics-skin/hit300@2x.PNG | Bin 0 -> 9589 bytes .../Resources/metrics-skin/hit50@2x.PNG | Bin 0 -> 9299 bytes .../TestSceneDrawableJudgement.cs | 39 ++++++++++++++++++ osu.Game/Skinning/LegacySkin.cs | 2 +- 12 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit0@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100k@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300g@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit50@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.PNG create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit100@2x.PNG create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit300@2x.PNG create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.PNG create mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit0@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bdb2bcbc41085fef9d4bd351bdeae81f0da331f4 GIT binary patch literal 16112 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit100@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7db8eb312403e739d8dc61b280f930443ad0d81c GIT binary patch literal 31228 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2c7c07852ff6e84edc2164b4487aaaa6cb4d8fe4 GIT binary patch literal 36873 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%0DE1j{G{fQ$Fey0U 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300g@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/hit300g@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce746e3a494f4446cc451f5924240f4c8eecb4b GIT binary patch literal 39840 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%0DP1I3KX^ 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 eY4UfV&i_BJT8gC9ZPy+E0000_|)(jNwS@P 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.PNG b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f64feded0cc2fc38672c081da38fe214d2546df3 GIT binary patch literal 9299 zcmZ`&pup=OL6CLN(;pu4%fq-7AfxT&H=@>SaCSq9g2H#cP;Mjy!`&(-LenQSKe=rYnE6#xL{{Rjgxfh+X(=`{QlpD zfeIH{005K#8IY)&`_hU2hhKQJNkW{XpBaLXIkKw)KHmetc<>VNYGJ>|+2|w_pp)iY zEzCF++6vTSuEyQ~xTdD`GU86Nm0%YI*zk+1law-;Ug%~)8{P!yybCbw^r-%{-qKiP zg;-e9T2zwtHttrOc6xYP;xy)W%6rEsh6OMB|1Qu$cP_FlNyCCHg`bec{{KS^$EK+597m6ieVe3=py3L`$qiNbIRH-sxbN@O@J*zu&l&r;7FM=cz ztmGWa$)`o@$o|TQP}0+k(7jCg$C-7)=A=)s6MMlP`IaxE5>KWq&`=v`0IOhb9}u=O zxQ4>{s2uBq_DYPv8E}4!;$EuCPXVs4D~ZF$Zp3_b=-9s3?{x82&uJ&MEc0Sri9E zft2kT0V-a|DmlsZ;2xb)2XB&I*iC-B>J0mK$~$y=>=2qT=!`M4LBMp4S}^-P)|e&c zaH%`yn215wvR}Usx9XEKAW7CUmd-c(Z)%;}NTPaslOIgbHe@{=x9)XOBWx z%iD09WAuZdw#by?azil|m12M8QP%yOzLdADdHpVNrcm{7=aS(E9%8_BFq>=-$ zT8EDxVuEQ%qBuZ&bM9@yGm<5Gnq>oiKOMYb54usgKH->(dg`V@mT+2^lkX+*mem__ z1OgoyD~_}SY7UCCR^z%F=4!%iCfHSLYPDssfo3Z%4YanB+S8%eXPs4M3pj%K^J-uf z*2|J9c5n@t-El;INO@?gA}>FTy7I($`+Hr7n1w6R1zp>kx%BuF3k@&dST=a1LLz!p zr=i-3K`QqbTEj=qnJ7MMn=f-O3>}?T+va6tt|i-bEM%!ID#5+z?j6hpAiQCor%tS* z9!j^S?%AaN&tA%60VA!D6z_(#b7`oeSjrO zr0qvI3!C`sON|m3ZZ&-Vh%qyF63kYPTR5j_!OmXbDb@NXD(18qgng*CTiou->ibw3*w*<8A9Z@VNUOQa|v(Uy^{ zyT{%L_Zvg0Uin|9tYf*M#4?)wQkVVHg7By!ldy)+DH6n*35n-|29Q#o$*@Gn?_~yP%U;ohV|cX0K=-k>vB+ES)#Jcp&ypR5EHIh z(wqt2iVVAev@WS3ESux}j|~^uR{fi#ru>QW7R)yc3|C5$#g^a3B@$6LZ8$D|>a~mc zsd0gd6MqZ}FU|g|C5JA-oda!Pyv4z5o#JbLbjQs0hNw{S{ld|+u^!@@?%)SA^~w0ohF#S$Ta(BXV|6WP zIOm^|*;^lBT7y0bUEWEA-4>>vSEoG)VFyOt%s2d7SRm00Ei=cP_NGp}{9~m>54pnm z&I`jCd5>Uhb+&m%l_3pyxf2<8T~<5XvNDHsKOXVZDgF|KmIp6ipV+# zc)1Th)1A+uFW2kvN#^&E@FdG{@nv;!A~KkeUtZp+oY>_PFrFZ1pd-Veh|PfpD2BIy zva+L-_B@g(eb4DvtNohl^9-t1lhq_ix84Qi+B^B;-X=VQzvZ+#q6MN=VTXO;n`WKa4cYa#h5et z$E~m~(jmiAh#p^{ci77_2xYM%iJWBzjbwKvfCXVeMybVq@C{b#-HUn8Y{mB;zYUh| zhDJB}oNEE_JmsH75bb8J#WrG>mo}vx6BdnVz%t?>+5X6XUht+SkAp2@Xo8Wt84ic5tT? zejMtCXeIlO;m9Z9K#a~)*iU5~iW|d@ehX_ApRhiqgRuBe3HJ_B&-BOY-^8x6?^I9V zCnHEO32j+eG}*Y*6p+!8K(Z(uIjj!f5`o=-G%M zW6VR6(=!|FNc>5S1!~1FIHc13kOWU9oq?p`BVl0;b( zkztl}4aJu&q@-QRk zG<1N?!?%A{iTawn&Arhv#t@@rWK)ESLha@+p0#lf-A(K%&%M>q-z;{`rgiWoot450 zI6rhBW$a^ZwZdLE-$G2Nd``Bc38QSrH#FHr)-x}bbWn|${9wcmiF!IC$=qT z8%A-l#Hh7mqA`2M25sP58zniwnjzh^!*Ids6c^-sM1#9)$qVJq{kQb6B>+REAh#Dm6s7uv66!GJTtHvBVcv|tQ(tvp)sVv6uN4#0 zSrFFuOIFup3oBh!TJ9Nv8Rr)pqiqV&oxJWSySWT2p<-ke{}Q>;@)tIeH)QJTubmot zR-^6Ro;0;x->=n5Ae5I~t^3Fcj&=;@Gf^Z&w%u=Tgs-?D1Lie1g+Bf=e@6el^DIi# zG(@csIk>5GV)keHFxUbZEB;-1M@(^I5Kg-NV~%t_8x25gAP^_ct$^b7j1dJ~D(VuH zbkgI%9ep-Zei>kjVpFhf0m!}U)yN=6c;)o>({+6Kt=POScIoYO$ue}7SElU7`{L|48W!odUp&N&q?5U9zokAMoAu-_9)^- zLNr{gqXPhX;T3RS(*L02ufF6xc)+#742d@z>)|^;H_kXk!aVBi**%8q&A_7g`Gz5- zt$6ulD(fhlD#2maWx0l$_`H->8G`G+`uh|8q&d4HT$;VRLQ%>^#@xnWJ;_AmL!)6K zu{XMx)}p|$JTE3vlG`on0X?EDD7kAWvS8Ds48NzV#KFTEkbJ>4hr`r4uaFV~S7k;u z-UzCHBK>%&G@C1cZpM+(pAZ*7gt5dc0nomKr9A62!!hG2!qJvQxHobqihXmMxP1%z zeR%@G++gqxIa&ujUU92^$=a;{bN_VZ?n6D+kruE@7Em+zM>ABLd*oAEECC)8?%@ua zJx5?2C3XoMRyexE27t|`yekIGYtWk-w8BC)kaErOH^Fj|u_R@{E(Q`KayjG}`MlNw zS|Z-GbjmpU8nNW~VHmTw6niPK$NXdcm)(Lo+HqI^%m&)Ez(U2Dl|+0he*ZzjRWDN4CgIY!%VwZ~hI<jM`xQla~^#D=iCyYhqQIfczF9km+nFDmL_;lf$TD_aVSe&cEi}6BO?w1;)fa( z@mgeM^AhX8W093jBU)twH4+2wsuq_suMbUP zN(b<1Obash*D>+B z+r3*=rjRO=*`ZgaKY>SHByr09Jx3v>fj8mb$<7OCR^N?ijs9n}^op_m?q7&#$~ zvRk`wqf7-hSNFlIBY8N1)&0Z&*=Plg#{gsM-* zON8sg^$%PaXim1JdODq4*(zQW(hoU`3-V2kx(DH}WtOotf)(!bj{$82!*)v8`2Dtb z(2!7`)r4Luc3Qd7W@Q@&OLldAWDLq5mVVz)&Pbvj#sDm97|v>(m#VnpZsSB zSY2Kc?s(hx856dC`0a#faK2=RIKv?F+!Y?QGIUX^F>-U@ zBuCH+Uh7(%9)l%o93FvDN+i;n!RRc6J3o(BSo#)!lj=+T6R%U2lVt+NeQ}TFAhf5N zoby-0+cL*LEv$#{<{M|!V+>7TZ61@Gm-V0u!(MtrCygVNPp~}014gJv0NQ)}=n-TE zn;Vz0QL zd&3RdNTsIRC{`!0FPUiW=6<$LBj^d2K`n?vqZw4 zNCB#3M7pcZZht(l3Y8TH!fN!-nGfc>HPsTN|9G+P*up5+LUh+c?1cj7J=4R!2k)OW zwwPjv|9!9PBWdw{RjW+J7Y9nnt1wV<^w!C6*cSJEZO*y|@!V!~O*j_-r!zokfiXzm zaTvaY-wwudZJ>-|Nb1j+DI|l{GD=8}eG#4-mR;ClJbAiIcTAF61kAog`O4Bm{s3Rmu1}o*W!j>Cjy8PrJl7^q(k_v0>nbMfEi_M1 zB-wC_BaefaIo5wu3qcWv-QlacHJmxpq&1DdwI>WA%sphahrMZ6FxHV&?CPNTZ?Pt* zp>ViXns^3BI~9$Q99Wy7pTQAM^o&Mti1DpMsT+iZr3@b%1^11_U-+4{Q!4wJ$12U) zT?%+)_|FbnK8{n*l_h-o*PN4V^>l-bW(P@zLar>g_}@AV)+?jG&gAZVu36oQfHbd6 z^8}TxvM{%V>oz}IfARVjb&p9y?Xznkm5JAW{QH&P6j|(SuuWsEmjJnvUxr(c^Y$@h z1`o<}UnCDO2$ub;{3tWT6I{|+FrT@LhWNaa<-6?eZIB&MhK;hWX?Jny@gQ)}TsUMV zh4FrvuhTFlGGog-stH99{uj3_0T#$mN4REQHY@I|rSKdX`DXn;To^46CjjJumRepM z&JnPf572J>jN{?>)zj?v+jVo9LCa$unAQhv0K>=Xe8$moEt;+yIh)L6RW&6FZm=aF zV9@HR=ghlO=FzsgzIMX~aFq$2S^k7s1jk?kFM^~T*`z*mt4#5z$Jx2()8Rp$BL%3L zz2g?DwKYQB*#0k_RXzmtw}8ha2m$*6LVmZ+f4!Jas%zwWojR3m_S2ozo-o{Ae=XT! zGTQ2RiP-~O=YFDNc?@u6k*-a{{0fj!_|3a3NHsoC89)Az&qo0sJwc`CG{x0*+liM|p)L!=EmLYXX^5f)ymog%`mt4KTWq?;_}kYiDT2ua5YZKnxc3*lZ?|$>7#Q>06Wz_Ydt1RM|lqSgKtlD z4Y}rt4R>ahDa-H11Q$qc1h~pEcnMsbtNQQvL+N)-dbW z9&fXekcp+s$Z>pJ*bX1TZu>x`;B)Hoa>0Ba3!6zjbRpQ->(e~!1~^iA`wqqq!y2<- zj)<{8y00)0y9e{fc_P0}n1|A^y|C7B_vCFjpD=Al@>k(8@joMF6pmQ25I1Y{(Mfw! z{{!lpP~{Dzkd2OuX0h^lKNp6MRhd7PIKnZ^u2hm9Uw?*47I4IPEk*r1w#Cyssr)E& zlYAERm0hVE-C}f7nbg02>UmHZ^*LMTiVVM$Kzm2I z0-JT#mYe5=-H;9b<6mc7H-O)|x$`?a&O@hr;(rYTtwt&ZZz`-XbWY7_<|XnPneeh* zbQD^97Uzj|qbcNRjoAFke6*KJM`G_jIqhog(fg;}*b1I!{M*pD&k`-U_z?xo1plvlm}B38v zKFU(g5-op{A(?Uu%_IDvP<->&K@~rl;adP5DJ$;!n!&pqrOVD1BsY7$(Wj_r$SPN^ zJH`LZuovPiYGcnw^zSE;_dE=UH!t?7GFRfEn6JXwiFMyQ2pIPy<_ehHJm<07%CkB* zK1Mgs`no69q9k`)%20}(l10c~Tzzq){niBJ)>X~84g2<6;@^F3M%ulXw(qsL84Tu# zMG{2YswF;CV5{Z$xD%exXk#{BM?%Q31~QNLBflX`DK0>ADE{tqGw8{W{e zfvXIIIlJZSLx8Z{sUjtT_j-%M?o=TAmNDkJ0|Z*35`GP!sFi)Fv4!izgr*&+p9tXO z6~kg`Dj4UTSgyon4PFUB9qyjo9mcWKrF{S+}e z_btMCqjO-r!#E@ir0B|ij0=)(jkClDqair_M!C^eQS5YGq6sueJJQ$MUW}c8sY@$s zGUqX89r`!jY>V+2@i2*^CW6@8EPm^sF)!VF(C`#8bQaVphx|CO)yg)eshPU?+Z#J0 zO^0xY{NO&iD=X)(MoqP?!XkcLh$I?P0`JhLMi|nuPB{9r{lK<70F?_O*|DAmfe+mRh~3sK_qEWRQFTWumIJF?vnx~f22u26Pq-`(z1tzS z8uCK^(^Y!xpXhRB<{UX+ifsvcWyKJI|U9+TAUs3r}K$bJ`ebk_Tn z&s>7ciqb>^t)6P+BiLt)vu3zOB4TcF$;n|IOceDbjCi+($>!2i{o!>jqy~47e}hG% zQ=;wkl$zFYcf*tiD!E(K*;TpoFo3(>hrYlNql^y^#zJ}rV!jzUQgz25ZUY)N+aeAr z!`dz@QCFUnoj%v&X|35&Hz=-)yyF+al$S&8`^cm13ro@7N>Wy*eT9shM`|ddJGiVF zx_Z)VUsv*B&M48Up?HCVa`$!tPG@QRURpVJCN$H4KnCgij+{JvJBSLP{Sj)@0w|Y* z691={wY7x1SOy@C=e8ubobp$YheM`j1K<4^ZQf0Y*a^k4l9y(WW}*)J{P2-~dLCXbH|f^Pan828o6w-6_wRnA1#7>+B^AydQuzL_BXNl~TS0Lx|% z|1B3#Pmrp!QTJjAaX+>nN?H$A9H4{dZVfXoM%>bNi0!E=0Ag=g?R#}UsL$p&2Yf*t8FM( zAabzgfR!Sn?V^6r^QlPDg^tll--!^VXV*k}F<&4uEJjKv z^ksS4o5k$L3RZzAsD;)+Fi~oZq9*E3rlBfagyVTp$h8;jTPV4Hk+P*9>eQb`r8sv1a61l>`U1{DC~weJEj@g$-$XVh3E{Y z2EtF;nieNN>HO$_R$?kb`nhk>9gW+RQSuIUhQ4Yx70yTvA8#6MN5S0#Fy}MhF;I;p z6Sq-x`a9twJ;4>RZTQooVU%2aZt~A7T3TZU72M=iL+;JhYW$)+lNUVVuXKHJj(5(Q z1zeoHJ+3*A;i#A|t@+%GQHI(mm}NSAS=@>npV9!}&H6X}(C2Y=c}ybmx~@p)h*Dpr zG#GH|PE7O^slDVdm)b%PJsr__BQ~a?oD(Gz%XOuKT^UJ70}evANhpMk>bTw$dO2E+y` z3qfJ*G;f^!4R00JnK-=8OrMEiBMwhu@@N>ba|Mq1_*9nbYEJfv62pqBa1!)u5f>Sx z6Fp6q4I6Lyr@iS_sb67Lx8Y7XV0A}}dq615j&3$RiXpBP1U*A~_L-Db!h~Jz*~BP} z__@8-O&r#D62?7B)st*qFmv5rf4;-te{QD-8-b5$=puZA#8;gN@|Vo7eWvaBf^ev0 zdu)w46#8y{*L;`F7w@(f`XcDa^d$+0Dq`6HcN*=XG3Z&GAxLo-1GUnmaB0E+xq-6-Hbd>A#2pUU!& zV?9|~z3+aDJTQfDpf4dW!*p!fpi2UjV@}0y#P7yo&(nI}g{@v;>rj4$iq4*NJHUee zSS#IJH9Ft;3}}i;53cYg-HjHD0&T$5qGtc8v!pd_>6&77H zk!&x#8o9t)e%ySK1S2)oU`;xtJ8E3=Zlq0(X!}TS{r9|$ z#j6T>U5+i77!mkJe)??a*!((y1r_dS%DHtU8}!7CxF?lR$4oI-72c99SX2LwE)i)o3ooE%?D)J>DG|DuLk@$tzJSNx!6*C9m~ak0pCd4NAkMW;~6#|5TP+J-R^W_g?&*yHlNcR!=|0MOdI} z^JJ%bg@)m*jXQ!>V9o3eenrLif-B}?D={J|JHj3@&GM?5t_Pt_Jl2P>WmAN0^$zcj+qfRU1j zaa2F1g5DneNu9^<_O`J4`zkNl>BQ@f zUJ!y%upiia^S+0<^_;sl>7;5Fx1*jLV9GMsd)!UbsI%K16j)60RmBtrhlvsW&?Nka z{<#tE9vVLAUp|iChGAV^SWKh=A4}>%hz|{?N(UPf-EKm0qB)?s`8qr5rqaTyBZI6Q zKyjd4YjixdY!#Q4kc<+qO%gTqGUq_OsSIb}E6X&!eHH}aWJW3Hu!. 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.Extensions; +using osu.Framework.Graphics; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Osu.Tests +{ + public class TestSceneDrawableJudgement : SkinnableTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DrawableJudgement), + typeof(DrawableOsuJudgement) + }; + + public TestSceneDrawableJudgement() + { + foreach (HitResult result in Enum.GetValues(typeof(HitResult))) + { + JudgementResult judgement = new JudgementResult(null) + { + Type = result, + }; + + AddStep("Show " + result.GetDescription(), () => SetContents(() => new DrawableOsuJudgement(judgement, null) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + })); + } + } + } +} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 5357a75e00..3426ddaf16 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -140,7 +140,7 @@ namespace osu.Game.Skinning if (texture != null && animatable) { - var animation = new TextureAnimation { DefaultFrameLength = frametime }; + var animation = new TextureAnimation { DefaultFrameLength = frametime, AutoSizeAxes = Axes.None }; for (int i = 1; texture != null; i++) { From 852079d43852a255b7d238f1691c3214d5221830 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 1 Aug 2019 01:35:42 +0300 Subject: [PATCH 067/645] Remove redundant ScreenshotManager.Update override --- osu.Game/Graphics/ScreenshotManager.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 5ad5e5569a..524a4742c0 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -92,7 +92,8 @@ namespace osu.Game.Graphics using (var image = await host.TakeScreenshotAsync()) { - Interlocked.Decrement(ref screenShotTasks); + if (Interlocked.Decrement(ref screenShotTasks) == 0 && cursorVisibility.Value == false) + cursorVisibility.Value = true; var fileName = getFileName(); if (fileName == null) return; @@ -125,14 +126,6 @@ namespace osu.Game.Graphics } }); - protected override void Update() - { - base.Update(); - - if (cursorVisibility.Value == false && Interlocked.CompareExchange(ref screenShotTasks, 0, 0) == 0) - cursorVisibility.Value = true; - } - private string getFileName() { var dt = DateTime.Now; From 8a64ab03847c9ebdb7c2d9d5081e306410f9ee1b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 12:35:17 +0900 Subject: [PATCH 068/645] Remove generics from IApplicableToBeatmap --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 3 +-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 3 +-- .../Mods/ManiaModMirror.cs | 4 +-- .../Mods/ManiaModRandom.cs | 4 +-- osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +-- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 3 +-- .../Rulesets/Mods/IApplicableToBeatmap.cs | 13 ++++------ osu.Game/Rulesets/Mods/ModTimeRamp.cs | 26 +++++++------------ osu.Game/Rulesets/Mods/ModWindDown.cs | 6 ++--- osu.Game/Rulesets/Mods/ModWindUp.cs | 6 ++--- osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- 11 files changed, 28 insertions(+), 45 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index ea9f225cc1..6f1a7873ec 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -11,7 +11,6 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -108,7 +107,7 @@ namespace osu.Game.Rulesets.Catch case ModType.Fun: return new Mod[] { - new MultiMod(new ModWindUp(), new ModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()) }; default: diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index d83033f9c6..8966b5058f 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Game.Graphics; -using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -154,7 +153,7 @@ namespace osu.Game.Rulesets.Mania case ModType.Fun: return new Mod[] { - new MultiMod(new ModWindUp(), new ModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()) }; default: diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs index 17f4098420..485595cea9 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mania.Beatmaps; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModMirror : Mod, IApplicableToBeatmap + public class ManiaModMirror : Mod, IApplicableToBeatmap { public override string Name => "Mirror"; public override string Acronym => "MR"; @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override double ScoreMultiplier => 1; public override bool Ranked => true; - public void ApplyToBeatmap(Beatmap beatmap) + public void ApplyToBeatmap(IBeatmap beatmap) { var availableColumns = ((ManiaBeatmap)beatmap).TotalColumns; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs index ba16140644..9275371a61 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModRandom : Mod, IApplicableToBeatmap + public class ManiaModRandom : Mod, IApplicableToBeatmap { public override string Name => "Random"; public override string Acronym => "RD"; @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override string Description => @"Shuffle around the keys!"; public override double ScoreMultiplier => 1; - public void ApplyToBeatmap(Beatmap beatmap) + public void ApplyToBeatmap(IBeatmap beatmap) { var availableColumns = ((ManiaBeatmap)beatmap).TotalColumns; var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList(); diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 7f45fbe1dd..d50d4f401c 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -14,7 +14,6 @@ using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -136,7 +135,7 @@ namespace osu.Game.Rulesets.Osu new OsuModWiggle(), new OsuModSpinIn(), new MultiMod(new OsuModGrow(), new OsuModDeflate()), - new MultiMod(new ModWindUp(), new ModWindDown()), + new MultiMod(new ModWindUp(), new ModWindDown()), }; case ModType.System: diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index a67004e9c7..83356b77c2 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Replays.Types; -using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Difficulty; @@ -107,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko case ModType.Fun: return new Mod[] { - new MultiMod(new ModWindUp(), new ModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()) }; default: diff --git a/osu.Game/Rulesets/Mods/IApplicableToBeatmap.cs b/osu.Game/Rulesets/Mods/IApplicableToBeatmap.cs index a634976b3c..cff669bf53 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToBeatmap.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToBeatmap.cs @@ -2,21 +2,18 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Beatmaps; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mods { /// - /// Interface for a that applies changes to a - /// after conversion and post-processing has completed. + /// Interface for a that applies changes to a after conversion and post-processing has completed. /// - public interface IApplicableToBeatmap : IApplicableMod - where TObject : HitObject + public interface IApplicableToBeatmap : IApplicableMod { /// - /// Applies this to a . + /// Applies this to an . /// - /// The to apply to. - void ApplyToBeatmap(Beatmap beatmap); + /// The to apply to. + void ApplyToBeatmap(IBeatmap beatmap); } } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index a5f96087c0..9edf57ad00 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -13,27 +13,21 @@ using osuTK; namespace osu.Game.Rulesets.Mods { - public abstract class ModTimeRamp : Mod + public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap { - public override Type[] IncompatibleMods => new[] { typeof(ModTimeAdjust) }; - - protected abstract double FinalRateAdjustment { get; } - } - - public abstract class ModTimeRamp : ModTimeRamp, IUpdatableByPlayfield, IApplicableToClock, IApplicableToBeatmap - where T : HitObject - { - private double finalRateTime; - - private double beginRampTime; - - private IAdjustableClock clock; - /// /// The point in the beatmap at which the final ramping rate should be reached. /// private const double final_rate_progress = 0.75f; + public override Type[] IncompatibleMods => new[] { typeof(ModTimeAdjust) }; + + protected abstract double FinalRateAdjustment { get; } + + private double finalRateTime; + private double beginRampTime; + private IAdjustableClock clock; + public virtual void ApplyToClock(IAdjustableClock clock) { this.clock = clock; @@ -44,7 +38,7 @@ namespace osu.Game.Rulesets.Mods applyAdjustment(1); } - public virtual void ApplyToBeatmap(Beatmap beatmap) + public virtual void ApplyToBeatmap(IBeatmap beatmap) { HitObject lastObject = beatmap.HitObjects.LastOrDefault(); diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 5d71c8950b..b2e3abb59d 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -4,12 +4,10 @@ using System; using System.Linq; using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mods { - public class ModWindDown : ModTimeRamp - where T : HitObject + public class ModWindDown : ModTimeRamp { public override string Name => "Wind Down"; public override string Acronym => "WD"; @@ -19,6 +17,6 @@ namespace osu.Game.Rulesets.Mods protected override double FinalRateAdjustment => -0.25; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModWindUp)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModWindUp)).ToArray(); } } diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index aae85cec19..8df35a1de2 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -4,12 +4,10 @@ using System; using System.Linq; using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mods { - public class ModWindUp : ModTimeRamp - where T : HitObject + public class ModWindUp : ModTimeRamp { public override string Name => "Wind Up"; public override string Acronym => "WU"; @@ -19,6 +17,6 @@ namespace osu.Game.Rulesets.Mods protected override double FinalRateAdjustment => 0.5; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModWindDown)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModWindDown)).ToArray(); } } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 52fba9cab3..faa6b98c86 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -278,7 +278,7 @@ namespace osu.Game.Rulesets.UI if (mods == null) return; - foreach (var mod in mods.OfType>()) + foreach (var mod in mods.OfType()) mod.ApplyToBeatmap(Beatmap); } From bc80fa11bbeee2b39174ec1b68132cc3a6468bfe Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 12:41:46 +0900 Subject: [PATCH 069/645] Mode IApplicableToBeatmap application to WorkingBeatmap --- osu.Game/Beatmaps/WorkingBeatmap.cs | 3 +++ osu.Game/Rulesets/UI/DrawableRuleset.cs | 15 --------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 949a2aab6f..baf921ddfc 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -141,6 +141,9 @@ namespace osu.Game.Beatmaps processor?.PostProcess(); + foreach (var mod in mods.OfType()) + mod.ApplyToBeatmap(Beatmap); + return converted; } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index faa6b98c86..ac81fdc719 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -109,8 +109,6 @@ namespace osu.Game.Rulesets.UI Beatmap = (Beatmap)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods); - applyBeatmapMods(mods); - KeyBindingInputManager = CreateInputManager(); playfield = new Lazy(CreatePlayfield); @@ -269,19 +267,6 @@ namespace osu.Game.Rulesets.UI public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); - /// - /// Applies the active mods to the Beatmap. - /// - /// - private void applyBeatmapMods(IReadOnlyList mods) - { - if (mods == null) - return; - - foreach (var mod in mods.OfType()) - mod.ApplyToBeatmap(Beatmap); - } - /// /// Applies the active mods to this DrawableRuleset. /// From 0108700793069bd524b390e50e44ea7b00869247 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 31 Jul 2019 19:48:50 +0900 Subject: [PATCH 070/645] Make beatmap conversion test use WorkingBeatmap --- .../ManiaBeatmapConversionTest.cs | 39 ++++++++-- osu.Game/Beatmaps/WorkingBeatmap.cs | 10 ++- .../Tests/Beatmaps/BeatmapConversionTest.cs | 72 ++++++++++++++----- 3 files changed, 94 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 6b95975059..51c7ba029a 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -35,11 +35,37 @@ namespace osu.Game.Rulesets.Mania.Tests }; } - protected override ManiaConvertMapping CreateConvertMapping() => new ManiaConvertMapping(Converter); + private readonly Dictionary rngSnapshots = new Dictionary(); + + protected override void OnConversionGenerated(HitObject original, IEnumerable result, IBeatmapConverter beatmapConverter) + { + base.OnConversionGenerated(original, result, beatmapConverter); + + rngSnapshots[original] = new RngSnapshot(beatmapConverter); + } + + protected override ManiaConvertMapping CreateConvertMapping(HitObject source) => new ManiaConvertMapping(rngSnapshots[source]); protected override Ruleset CreateRuleset() => new ManiaRuleset(); } + public class RngSnapshot + { + public readonly uint RandomW; + public readonly uint RandomX; + public readonly uint RandomY; + public readonly uint RandomZ; + + public RngSnapshot(IBeatmapConverter converter) + { + var maniaConverter = (ManiaBeatmapConverter)converter; + RandomW = maniaConverter.Random.W; + RandomX = maniaConverter.Random.X; + RandomY = maniaConverter.Random.Y; + RandomZ = maniaConverter.Random.Z; + } + } + public class ManiaConvertMapping : ConvertMapping, IEquatable { public uint RandomW; @@ -51,13 +77,12 @@ namespace osu.Game.Rulesets.Mania.Tests { } - public ManiaConvertMapping(IBeatmapConverter converter) + public ManiaConvertMapping(RngSnapshot snapshot) { - var maniaConverter = (ManiaBeatmapConverter)converter; - RandomW = maniaConverter.Random.W; - RandomX = maniaConverter.Random.X; - RandomY = maniaConverter.Random.Y; - RandomZ = maniaConverter.Random.Z; + RandomW = snapshot.RandomW; + RandomX = snapshot.RandomX; + RandomY = snapshot.RandomY; + RandomZ = snapshot.RandomZ; } public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ; diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index baf921ddfc..6b3a21a2c1 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -89,6 +89,14 @@ namespace osu.Game.Beatmaps return path; } + /// + /// Creates a to convert a for a specified . + /// + /// The to be converted. + /// The for which should be converted. + /// The applicable . + protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); + /// /// Constructs a playable from using the applicable converters for a specific . /// @@ -104,7 +112,7 @@ namespace osu.Game.Beatmaps { var rulesetInstance = ruleset.CreateInstance(); - IBeatmapConverter converter = rulesetInstance.CreateBeatmapConverter(Beatmap); + IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance); // Check if the beatmap can be converted if (!converter.CanConvert) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 6a5e17eb38..1f2d457624 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -4,13 +4,16 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using Newtonsoft.Json; using NUnit.Framework; -using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; namespace osu.Game.Tests.Beatmaps @@ -25,8 +28,6 @@ namespace osu.Game.Tests.Beatmaps protected abstract string ResourceAssembly { get; } - protected IBeatmapConverter Converter { get; private set; } - protected void Test(string name) { var ourResult = convert(name); @@ -98,26 +99,33 @@ namespace osu.Game.Tests.Beatmaps var rulesetInstance = CreateRuleset(); beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); - Converter = rulesetInstance.CreateBeatmapConverter(beatmap); + var converterResult = new Dictionary>(); - var result = new ConvertResult(); - - Converter.ObjectConverted += (orig, converted) => + var working = new ConversionWorkingBeatmap(beatmap) { - converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); - - var mapping = CreateConvertMapping(); - mapping.StartTime = orig.StartTime; - - foreach (var obj in converted) - mapping.Objects.AddRange(CreateConvertValue(obj)); - result.Mappings.Add(mapping); + ConversionGenerated = (o, r, c) => + { + converterResult[o] = r; + OnConversionGenerated(o, r, c); + } }; - IBeatmap convertedBeatmap = Converter.Convert(); - rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess(); + working.GetPlayableBeatmap(rulesetInstance.RulesetInfo, Array.Empty()); - return result; + return new ConvertResult + { + Mappings = converterResult.Select(r => + { + var mapping = CreateConvertMapping(r.Key); + mapping.StartTime = r.Key.StartTime; + mapping.Objects.AddRange(r.Value.SelectMany(CreateConvertValue)); + return mapping; + }).ToList() + }; + } + + protected virtual void OnConversionGenerated(HitObject original, IEnumerable result, IBeatmapConverter beatmapConverter) + { } private ConvertResult read(string name) @@ -154,7 +162,7 @@ namespace osu.Game.Tests.Beatmaps /// This should be used to validate the integrity of the conversion process after a conversion has occurred. /// /// - protected virtual TConvertMapping CreateConvertMapping() => new TConvertMapping(); + protected virtual TConvertMapping CreateConvertMapping(HitObject source) => new TConvertMapping(); /// /// A to which further transforms can be added. - public static TransformSequence TransformBlendingMode(this T drawable, BlendingMode newValue, double delay = 0) + public static TransformSequence TransformBlendingMode(this T drawable, BlendingParameters newValue, double delay = 0) where T : Drawable - => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingMode(), newValue, delay)); + => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingParameters(), newValue, delay)); } - public class TransformBlendingMode : Transform + public class TransformBlendingParameters : Transform { - private BlendingMode valueAt(double time) + private BlendingParameters valueAt(double time) => time < EndTime ? StartValue : EndValue; public override string TargetMember => nameof(Drawable.Blending); protected override void Apply(Drawable d, double time) => d.Blending = valueAt(time); - protected override void ReadIntoStartValue(Drawable d) => StartValue = d.Blending.Mode; + protected override void ReadIntoStartValue(Drawable d) => StartValue = d.Blending; } } diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index 8f8ec22aae..37c3ff495f 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -69,7 +69,7 @@ namespace osu.Game.Storyboards applyCommands(drawable, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); applyCommands(drawable, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); applyCommands(drawable, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); - applyCommands(drawable, getCommands(g => g.BlendingMode, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); + applyCommands(drawable, getCommands(g => g.BlendingParameters, triggeredGroups), (d, value) => d.Blending = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); if (drawable is IFlippable flippable) { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 758c4dda4c..8176b61fca 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index d6ad35b663..332d891416 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,8 +118,8 @@ - - + + From cca64771dd73030f81a6f9b1019223aacb746294 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 13:56:49 +0900 Subject: [PATCH 370/645] Add comment about placement of default loading --- osu.Game/Skinning/LegacySkin.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 5a05420e75..2be31c5ee0 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -43,6 +43,7 @@ namespace osu.Game.Skinning public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : this(skin, new LegacySkinResourceStore(skin, storage), audioManager, "skin.ini") { + // defaults should only be applied for non-beatmap skins (which are parsed via this constructor). if (!Configuration.CustomColours.ContainsKey("SliderBall")) Configuration.CustomColours["SliderBall"] = new Color4(2, 170, 255, 255); } From 724365c6d12e4b1f24824dfc7a20448839066f32 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 14:01:07 +0900 Subject: [PATCH 371/645] Minor tidying --- osu.Game/Screens/Menu/IntroScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 6a98c78d5f..4d0f7ff87a 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Menu [BackgroundDependencyLoader] private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) { - // we take a lease on the beatmap bindable to prevent music playback from changing / pausing during intros, as it is causing weird interactions with certains intros. + // prevent user from changing beatmap while the intro is still runnning. beatmap = base.Beatmap.BeginLease(false); menuVoice = config.GetBindable(OsuSetting.MenuVoice); @@ -114,9 +114,9 @@ namespace osu.Game.Screens.Menu protected void LoadMenu() { - DidLoadMenu = true; beatmap.Return(); + DidLoadMenu = true; this.Push(mainMenu); } } From ae7bedacc1a05d9ea4d70eae3c4faee003f6e497 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2019 05:20:49 +0000 Subject: [PATCH 372/645] Bump ppy.osu.Framework.iOS from 2019.816.0 to 2019.821.0 Bumps [ppy.osu.Framework.iOS](https://github.com/ppy/osu-framework) from 2019.816.0 to 2019.821.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.816.0...2019.821.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index d6ad35b663..6e459bdd23 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -119,7 +119,7 @@ - + From 9ce783fbf284d8b6e84798a96e336b454bbc367c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2019 05:21:25 +0000 Subject: [PATCH 373/645] Bump ppy.osu.Framework.Android from 2019.816.0 to 2019.821.0 Bumps [ppy.osu.Framework.Android](https://github.com/ppy/osu-framework) from 2019.816.0 to 2019.821.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.816.0...2019.821.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android.props b/osu.Android.props index bb283dc0c5..fe6420ead8 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + From 444f2b9387bf6c850dd95e49ddd7ce3ed09cfbd6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 14:31:19 +0900 Subject: [PATCH 374/645] Specify font size in a saner way --- osu.Game/Skinning/LegacySkin.cs | 35 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 21e8995981..de6346c9dc 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -135,7 +135,7 @@ namespace osu.Game.Skinning case "Play/osu/number-text": return !hasFont(Configuration.HitCircleFont) ? null - : new LegacySpriteText(Textures, Configuration.HitCircleFont) + : new LegacySpriteText(this, Configuration.HitCircleFont) { Scale = new Vector2(0.96f), // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size @@ -282,45 +282,38 @@ namespace osu.Game.Skinning { private readonly LegacyGlyphStore glyphStore; - public LegacySpriteText(TextureStore textures, string font) + public LegacySpriteText(ISkin skin, string font) { Shadow = false; UseFullGlyphHeight = false; - Font = new FontUsage(font, 16); - glyphStore = new LegacyGlyphStore(textures); + Font = new FontUsage(font, OsuFont.DEFAULT_FONT_SIZE); + glyphStore = new LegacyGlyphStore(skin); } protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore); private class LegacyGlyphStore : ITexturedGlyphLookupStore { - private readonly TextureStore textures; + private readonly ISkin skin; - public LegacyGlyphStore(TextureStore textures) + public LegacyGlyphStore(ISkin skin) { - this.textures = textures; + this.skin = skin; } public ITexturedCharacterGlyph Get(string fontName, char character) { - string textureName = $"{fontName}-{character}"; - - // Approximate value that brings character sizing roughly in-line with stable - float ratio = 36; - - var texture = textures.Get($"{textureName}@2x"); - - if (texture == null) - { - ratio = 18; - texture = textures.Get(textureName); - } + var texture = skin.GetTexture($"{fontName}-{character}"); if (texture != null) - texture.ScaleAdjust = ratio; + // Approximate value that brings character sizing roughly in-line with stable + texture.ScaleAdjust *= 18; - return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture?.Width ?? 0, null), texture, 1f / ratio); + if (texture == null) + return null; + + return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture?.Width ?? 0, null), texture, 1f / texture.ScaleAdjust); } public Task GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character)); From 4186d2566a4a85d09507804fa90b0a9a67228cea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 15:11:33 +0900 Subject: [PATCH 375/645] Remove unnecessary null checks --- osu.Game/Skinning/LegacySkin.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index e2ef3183da..a81e8c2b67 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -317,7 +317,7 @@ namespace osu.Game.Skinning if (texture == null) return null; - return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture?.Width ?? 0, null), texture, 1f / texture.ScaleAdjust); + return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture.Width, null), texture, 1f / texture.ScaleAdjust); } public Task GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character)); From 28dfe072a50f5998b5d31ea9b5bba01c0f9846a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 15:11:46 +0900 Subject: [PATCH 376/645] Update one more blending mode change post-master merge --- osu.Game/Skinning/LegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index a81e8c2b67..48310cf027 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -380,7 +380,7 @@ namespace osu.Game.Skinning new Sprite { Texture = skin.GetTexture("sliderb-spec"), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, }; } From 71cbc3525d98e3177c60c60f0677dece66ad9105 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 21 Aug 2019 09:16:09 +0300 Subject: [PATCH 377/645] Add/remove displays only if necessary --- .../HitErrorDisplay/HitErrorDisplayOverlay.cs | 62 ++++++++++++++----- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index 1c61904461..fae1b68e4a 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Play.HitErrorDisplay @@ -22,6 +21,9 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly HitWindows hitWindows; private readonly ScoreProcessor processor; + private BarHitErrorDisplay leftDisplay; + private BarHitErrorDisplay rightDisplay; + public HitErrorDisplayOverlay(ScoreProcessor processor) { this.processor = processor; @@ -43,38 +45,69 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private void onTypeChanged(ValueChangedEvent type) { - clear(); - switch (type.NewValue) { case ScoreMeterType.None: + removeLeftDisplay(); + removeRightDisplay(); break; case ScoreMeterType.HitErrorBoth: - createNew(); - createNew(true); + addLeftDisplay(); + addRightDisplay(); break; case ScoreMeterType.HitErrorLeft: - createNew(); + addLeftDisplay(); + removeRightDisplay(); break; case ScoreMeterType.HitErrorRight: - createNew(true); + addRightDisplay(); + removeLeftDisplay(); break; } } - private void clear() + private void addLeftDisplay() { - Children.ForEach(t => - { - processor.NewJudgement -= t.OnNewJudgement; - t.FadeOut(fade_duration, Easing.OutQuint).Expire(); - }); + if (leftDisplay != null) + return; + + leftDisplay = createNew(); } - private void createNew(bool reversed = false) + private void addRightDisplay() + { + if (rightDisplay != null) + return; + + rightDisplay = createNew(true); + } + + private void removeRightDisplay() + { + if (rightDisplay == null) + return; + + processor.NewJudgement -= rightDisplay.OnNewJudgement; + + rightDisplay.FadeOut(fade_duration, Easing.OutQuint).Expire(); + rightDisplay = null; + } + + private void removeLeftDisplay() + { + if (leftDisplay == null) + return; + + processor.NewJudgement -= leftDisplay.OnNewJudgement; + + leftDisplay.FadeOut(fade_duration, Easing.OutQuint).Expire(); + leftDisplay = null; + } + + private BarHitErrorDisplay createNew(bool reversed = false) { var display = new BarHitErrorDisplay(hitWindows, reversed) { @@ -87,6 +120,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay processor.NewJudgement += display.OnNewJudgement; Add(display); display.FadeInFromZero(fade_duration, Easing.OutQuint); + return display; } } } From a994ad9c84047e583471443c0d68f4ecc0e94dc4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 21 Aug 2019 09:40:15 +0300 Subject: [PATCH 378/645] Use moving average to calculate arrow position --- .../HitErrorDisplay/BarHitErrorDisplay.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index d8ae3dd9b0..d24982635b 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly SpriteIcon arrow; private readonly FillFlowContainer bar; private readonly Container judgementsContainer; - private readonly Queue judgementOffsets = new Queue(); + private readonly List judgementOffsets = new List(); private readonly double maxHitWindows; public BarHitErrorDisplay(HitWindows hitWindows, bool reversed = false) @@ -154,14 +154,23 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private float getRelativeJudgementPosition(double value) => (float)(value / maxHitWindows); + private double sum = 0; + private float calculateArrowPosition(JudgementResult newJudgement) { + var offset = newJudgement.TimeOffset; + + sum += offset; + + judgementOffsets.Add(offset); + if (judgementOffsets.Count > stored_judgements_amount) - judgementOffsets.Dequeue(); + { + sum -= judgementOffsets[0]; + judgementOffsets.RemoveAt(0); + } - judgementOffsets.Enqueue(newJudgement.TimeOffset); - - return getRelativeJudgementPosition(judgementOffsets.Average()); + return getRelativeJudgementPosition(sum / stored_judgements_amount); } } } From a5acc913eab464a2f0e313df630a1a1a6736e87b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 21 Aug 2019 09:58:47 +0300 Subject: [PATCH 379/645] CI fixes --- osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index d24982635b..d2bef75fd7 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -14,7 +14,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; -using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { @@ -154,7 +153,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private float getRelativeJudgementPosition(double value) => (float)(value / maxHitWindows); - private double sum = 0; + private double sum; private float calculateArrowPosition(JudgementResult newJudgement) { From 0ccfaeb8d9896ae901e09a8eb284477514cd5fde Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 21 Aug 2019 10:13:59 +0300 Subject: [PATCH 380/645] Simplify moving average --- .../Play/HitErrorDisplay/BarHitErrorDisplay.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index d2bef75fd7..85d017073a 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -14,6 +14,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; +using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { @@ -153,21 +154,17 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private float getRelativeJudgementPosition(double value) => (float)(value / maxHitWindows); - private double sum; - private float calculateArrowPosition(JudgementResult newJudgement) { - var offset = newJudgement.TimeOffset; + judgementOffsets.Add(newJudgement.TimeOffset); - sum += offset; + if (judgementOffsets.Count < stored_judgements_amount) + return getRelativeJudgementPosition(judgementOffsets.Average()); - judgementOffsets.Add(offset); + double sum = 0; - if (judgementOffsets.Count > stored_judgements_amount) - { - sum -= judgementOffsets[0]; - judgementOffsets.RemoveAt(0); - } + for (int i = judgementOffsets.Count - stored_judgements_amount; i < judgementOffsets.Count; i++) + sum += judgementOffsets[i]; return getRelativeJudgementPosition(sum / stored_judgements_amount); } From fb8d8f9438d8b4b704a3201ccc371c07211b80be Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2019 08:27:56 +0000 Subject: [PATCH 381/645] Bump SharpCompress from 0.23.0 to 0.24.0 Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.23.0 to 0.24.0. - [Release notes](https://github.com/adamhathcock/sharpcompress/releases) - [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.23...0.24) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 758c4dda4c..9318468c78 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index d6ad35b663..aebef4dc3a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -120,7 +120,7 @@ - + From 727a6abaf775ff392b4ac135c1f2a188ab1d4d14 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 21 Aug 2019 12:16:30 +0300 Subject: [PATCH 382/645] Simplify caching --- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 5606328575..0f7b26835b 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -15,6 +15,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { + [Cached(typeof(IPreviewTrackOwner))] public abstract class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler { private SampleChannel samplePopIn; @@ -38,13 +39,6 @@ namespace osu.Game.Graphics.Containers protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(this); - return dependencies; - } - [BackgroundDependencyLoader(true)] private void load(AudioManager audio) { From 87f3184fccee86fe7d3dc94c5ce38d98108ae8a6 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 21 Aug 2019 15:14:33 +0300 Subject: [PATCH 383/645] Try retrieving samples without bank names Fallback for spinner bonus samples --- osu.Game/Skinning/SkinnableSound.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8e2b5cec98..b50cc19482 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -55,8 +55,16 @@ namespace osu.Game.Skinning foreach (var lookup in info.LookupNames) { var ch = getSampleFunction($"Gameplay/{lookup}"); + if (ch == null) - continue; + { + // Try fallback to non-bank samples. + var bank = lookup.Split('/').Last().Split('-')[0] + '-'; + ch = getSampleFunction($"Gameplay/{lookup.Replace(bank, "")}"); + + if (ch == null) + continue; + } ch.Volume.Value = info.Volume / 100.0; return ch; From 7bf430afd5be08dec4dd0aefb4734a42cd1ebc52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 21:16:06 +0900 Subject: [PATCH 384/645] Add padding back to difficulty icons on carousel --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 4ceb82d4cc..0259f3cd81 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -98,6 +98,7 @@ namespace osu.Game.Screens.Select.Carousel new FillFlowContainer { AutoSizeAxes = Axes.Both, + Spacing = new Vector2(3), Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList() }, } From acc07c1d6548cd2a26882b73a8fb4ad3db8599c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 22:18:29 +0900 Subject: [PATCH 385/645] Remove mod icon offset --- osu.Game/Rulesets/UI/ModIcon.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 5bb1de7a38..88a2338b94 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -52,7 +52,6 @@ namespace osu.Game.Rulesets.UI Anchor = Anchor.Centre, Size = new Vector2(size), Icon = OsuIcon.ModBg, - Y = -6.5f, Shadow = true, }, modIcon = new SpriteIcon From 4f98361da3b3bcf7b5764522f683eb4b116bebdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 22:22:03 +0900 Subject: [PATCH 386/645] One more offset removed --- osu.Game/Overlays/SettingsSubPanel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/SettingsSubPanel.cs b/osu.Game/Overlays/SettingsSubPanel.cs index 7f794e2927..5000156e97 100644 --- a/osu.Game/Overlays/SettingsSubPanel.cs +++ b/osu.Game/Overlays/SettingsSubPanel.cs @@ -57,7 +57,6 @@ namespace osu.Game.Overlays { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Y = -15, Size = new Vector2(15), Shadow = true, Icon = FontAwesome.Solid.ChevronLeft From db1ff6d211e1d482cea28b922c8a04ac79efab4a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 22 Aug 2019 13:48:27 +0900 Subject: [PATCH 387/645] Fix video decoding loop running permanently in the background --- osu.Game/Screens/Menu/IntroTriangles.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index f5a72c2c1d..bb3a8f0013 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -139,7 +139,7 @@ namespace osu.Game.Screens.Menu private RulesetFlow rulesets; private Container rulesetsScale; private Drawable logoContainerSecondary; - private Drawable logoContainer; + private Drawable lazerLogo; private GlitchingTriangles triangles; @@ -191,7 +191,7 @@ namespace osu.Game.Screens.Menu RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Child = logoContainer = new LazerLogo(textures.GetStream("Menu/logo-triangles.mp4")) + Child = lazerLogo = new LazerLogo(textures.GetStream("Menu/logo-triangles.mp4")) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -222,7 +222,7 @@ namespace osu.Game.Screens.Menu const float scale_adjust = 0.8f; rulesets.Hide(); - logoContainer.Hide(); + lazerLogo.Hide(); background.Hide(); using (BeginAbsoluteSequence(0, true)) @@ -269,14 +269,17 @@ namespace osu.Game.Screens.Menu rulesets.FadeOut(); // matching flyte curve y = 0.25x^2 + (max(0, x - 0.7) / 0.3) ^ 5 - logoContainer.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint); + lazerLogo.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint); logoContainerSecondary.ScaleTo(scale_start).Then().ScaleTo(scale_start - scale_adjust * 0.25f, logo_scale_duration, Easing.InQuad); } using (BeginDelayedSequence(logo_2, true)) { - logoContainer.FadeOut().OnComplete(_ => + lazerLogo.FadeOut().OnComplete(_ => { + lazerLogo.Expire(); + lazerLogo.Dispose(); // explicit disposal as we are pushing a new screen and the expire may not get run. + logo.FadeIn(); background.FadeIn(); From 66d84401678a10e3692c95da2042f7c6a71bda94 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 22 Aug 2019 12:50:47 +0300 Subject: [PATCH 388/645] Move non-bank samples logic to LegacySkin --- osu.Game/Skinning/LegacySkin.cs | 14 +++++++++++++- osu.Game/Skinning/SkinnableSound.cs | 10 +--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 48310cf027..73957a203e 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -212,7 +212,19 @@ namespace osu.Game.Skinning return texture; } - public override SampleChannel GetSample(string sampleName) => Samples.Get(sampleName); + public override SampleChannel GetSample(string sampleName) + { + var sample = Samples.Get(sampleName); + + if (sample == null) + { + // Try fallback to non-bank samples. + var bank = sampleName.Split('/').Last().Split('-')[0] + '-'; + sample = Samples.Get($"Gameplay/{sampleName.Replace(bank, "")}"); + } + + return sample; + } private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index b50cc19482..8e2b5cec98 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -55,16 +55,8 @@ namespace osu.Game.Skinning foreach (var lookup in info.LookupNames) { var ch = getSampleFunction($"Gameplay/{lookup}"); - if (ch == null) - { - // Try fallback to non-bank samples. - var bank = lookup.Split('/').Last().Split('-')[0] + '-'; - ch = getSampleFunction($"Gameplay/{lookup.Replace(bank, "")}"); - - if (ch == null) - continue; - } + continue; ch.Volume.Value = info.Volume / 100.0; return ch; From f4d2bb036b3bcd9ed7819ad1380e1310bf8a2984 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 22 Aug 2019 16:50:54 +0300 Subject: [PATCH 389/645] Expand KudosuAction list --- .../Visual/Online/TestSceneKudosuHistory.cs | 80 +++++++++++++++++++ .../Requests/GetUserKudosuHistoryRequest.cs | 5 ++ .../Kudosu/DrawableKudosuHistoryItem.cs | 35 ++++++++ 3 files changed, 120 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index dcf2bec239..8badfeaa23 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -150,6 +150,86 @@ namespace osu.Game.Tests.Visual.Online Username = @"Username6", Url = @"https://osu.ppy.sh/u/1234" } + }, + new APIKudosuHistory + { + Amount = 11, + CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)), + Action = KudosuAction.AllowKudosuGive, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 7", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username7", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 24, + CreatedAt = new DateTimeOffset(new DateTime(2014, 6, 11)), + Action = KudosuAction.DeleteReset, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 8", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username8", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 12, + CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)), + Action = KudosuAction.RestoreGive, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 9", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username9", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 2, + CreatedAt = new DateTimeOffset(new DateTime(2012, 6, 11)), + Action = KudosuAction.RecalculateGive, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 10", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username10", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 32, + CreatedAt = new DateTimeOffset(new DateTime(2019, 8, 11)), + Action = KudosuAction.RecalculateReset, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 11", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username11", + Url = @"https://osu.ppy.sh/u/1234" + } } }; } diff --git a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs index af37bd4b51..dd6f2ccf22 100644 --- a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs @@ -27,5 +27,10 @@ namespace osu.Game.Online.API.Requests VoteReset, DenyKudosuReset, Revoke, + AllowKudosuGive, + DeleteReset, + RestoreGive, + RecalculateGive, + RecalculateReset } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index e5f5b720c2..3cc39f0e73 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -91,6 +91,41 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu addMainPart($@"Denied kudosu by {userLinkTemplate()} for the post "); addPostPart(); break; + + case KudosuAction.AllowKudosuGive: + linkFlowContainer.AddText(@"Received "); + addKudosuPart(); + addMainPart(@" from kudosu deny repeal of modding post "); + addPostPart(); + break; + + case KudosuAction.DeleteReset: + linkFlowContainer.AddText(@"Lost "); + addKudosuPart(); + addMainPart(@" from modding post deletion of "); + addPostPart(); + break; + + case KudosuAction.RestoreGive: + linkFlowContainer.AddText(@"Received "); + addKudosuPart(); + addMainPart(@" from modding post restoration of "); + addPostPart(); + break; + + case KudosuAction.RecalculateGive: + linkFlowContainer.AddText(@"Received "); + addKudosuPart(); + addMainPart(@" from votes recalculation in modding post of "); + addPostPart(); + break; + + case KudosuAction.RecalculateReset: + linkFlowContainer.AddText(@"Lost "); + addKudosuPart(); + addMainPart(@" from votes recalculation in modding post of "); + addPostPart(); + break; } } From a30567394ed1973230716b6d6b55090a1097d407 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 23 Aug 2019 12:39:24 +0900 Subject: [PATCH 390/645] Remove bottom margin from show more button --- osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs index 5ed546c62b..cf4e1c0dde 100644 --- a/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs +++ b/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs @@ -124,14 +124,12 @@ namespace osu.Game.Overlays.Profile.Sections private class ChevronIcon : SpriteIcon { - private const int bottom_margin = 2; private const int icon_size = 8; public ChevronIcon() { Anchor = Anchor.Centre; Origin = Anchor.Centre; - Margin = new MarginPadding { Bottom = bottom_margin }; Size = new Vector2(icon_size); Icon = FontAwesome.Solid.ChevronDown; } From 900df5d72f576a0f31d0840b3d1672314eb5e02a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 23 Aug 2019 13:02:50 +0900 Subject: [PATCH 391/645] Fix crash on closing game --- osu.Game/Screens/Menu/IntroTriangles.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index bb3a8f0013..db970dd76e 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -138,7 +138,7 @@ namespace osu.Game.Screens.Menu private RulesetFlow rulesets; private Container rulesetsScale; - private Drawable logoContainerSecondary; + private Container logoContainerSecondary; private Drawable lazerLogo; private GlitchingTriangles triangles; @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Menu { this.game = game; - InternalChildren = new[] + InternalChildren = new Drawable[] { triangles = new GlitchingTriangles { @@ -277,7 +277,7 @@ namespace osu.Game.Screens.Menu { lazerLogo.FadeOut().OnComplete(_ => { - lazerLogo.Expire(); + logoContainerSecondary.Remove(lazerLogo); lazerLogo.Dispose(); // explicit disposal as we are pushing a new screen and the expire may not get run. logo.FadeIn(); From c41b1e9eb4c900906c3d092c09c29142eb3bd314 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 22 Aug 2019 21:36:21 -0700 Subject: [PATCH 392/645] Fix alignment and size of mute button --- osu.Game/Overlays/Volume/MuteButton.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index a4884dc2c1..0f69f11985 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -65,13 +65,14 @@ namespace osu.Game.Overlays.Volume { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(20), } }); Current.ValueChanged += muted => { icon.Icon = muted.NewValue ? FontAwesome.Solid.VolumeMute : FontAwesome.Solid.VolumeUp; + icon.Size = new Vector2(muted.NewValue ? 18 : 20); + icon.Margin = new MarginPadding { Right = muted.NewValue ? 2 : 0 }; }; Current.TriggerChange(); From c55d237db6e2db0fc3e468d98ae74bc9a7f6adf3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 23 Aug 2019 17:42:40 +0900 Subject: [PATCH 393/645] Use BindValueChanged --- osu.Game/Overlays/Volume/MuteButton.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 0f69f11985..6d876a77b1 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -68,14 +68,12 @@ namespace osu.Game.Overlays.Volume } }); - Current.ValueChanged += muted => + Current.BindValueChanged(muted => { icon.Icon = muted.NewValue ? FontAwesome.Solid.VolumeMute : FontAwesome.Solid.VolumeUp; icon.Size = new Vector2(muted.NewValue ? 18 : 20); icon.Margin = new MarginPadding { Right = muted.NewValue ? 2 : 0 }; - }; - - Current.TriggerChange(); + }, true); } protected override bool OnHover(HoverEvent e) From cb54fbee875d7806c3bbc0867242cc2c9e7e1211 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2019 09:29:35 +0000 Subject: [PATCH 394/645] Bump ppy.osu.Framework.Android from 2019.821.0 to 2019.823.0 Bumps [ppy.osu.Framework.Android](https://github.com/ppy/osu-framework) from 2019.821.0 to 2019.823.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.821.0...2019.823.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android.props b/osu.Android.props index fe6420ead8..9c4a308271 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + From 4bc05818716e94dc4bc63b8122c127ac29c520f5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2019 09:33:38 +0000 Subject: [PATCH 395/645] Bump ppy.osu.Framework.iOS from 2019.821.0 to 2019.823.0 Bumps [ppy.osu.Framework.iOS](https://github.com/ppy/osu-framework) from 2019.821.0 to 2019.823.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.821.0...2019.823.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 05910f846a..39066cb440 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -119,7 +119,7 @@ - + From 11a61b953b15e669a1124c52b2a1e12140b0d327 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2019 09:43:34 +0000 Subject: [PATCH 396/645] Bump ppy.osu.Framework from 2019.821.0 to 2019.823.0 Bumps [ppy.osu.Framework](https://github.com/ppy/osu-framework) from 2019.821.0 to 2019.823.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.821.0...2019.823.0) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 905fa57f22..8c692132ad 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 05910f846a..3007a9cb86 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,7 +118,7 @@ - + From c836ef57217d086c22df6aa0d72738e2cc076706 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2019 10:04:00 +0000 Subject: [PATCH 397/645] Bump ppy.osu.Game.Resources from 2019.809.0 to 2019.823.0 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.809.0 to 2019.823.0. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.809.0...2019.823.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index fe6420ead8..232d89b375 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 905fa57f22..22af0a5f6d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 05910f846a..3fe4d1d613 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 050130e1591e6ec6991b9027fa51c0d085498307 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 23 Aug 2019 14:11:21 +0300 Subject: [PATCH 398/645] Refactor PaginatedContainer to centralise repetitive logic --- .../Beatmaps/PaginatedBeatmapContainer.cs | 48 +++---------- .../PaginatedMostPlayedBeatmapContainer.cs | 41 +++-------- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 38 ++-------- .../Profile/Sections/PaginatedContainer.cs | 72 +++++++++++++++---- .../Sections/Ranks/PaginatedScoreContainer.cs | 65 ++++++----------- .../PaginatedRecentActivityContainer.cs | 39 ++-------- 6 files changed, 110 insertions(+), 193 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 8a6b52b7ee..3fbd1dacd9 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -1,21 +1,22 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; +using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Direct; using osu.Game.Users; using osuTK; namespace osu.Game.Overlays.Profile.Sections.Beatmaps { - public class PaginatedBeatmapContainer : PaginatedContainer + public class PaginatedBeatmapContainer : PaginatedContainer { private const float panel_padding = 10f; private readonly BeatmapSetType type; - private GetUserBeatmapsRequest request; public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, string header, string missing = "None... yet.") : base(user, header, missing) @@ -27,40 +28,13 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps ItemsContainer.Spacing = new Vector2(panel_padding); } - protected override void ShowMore() + protected override APIRequest> CreateRequest() + => new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); + + protected override Drawable CreateDrawableItem(APIBeatmapSet item) => new DirectGridPanel(item.ToBeatmapSet(Rulesets)) { - request = new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - request.Success += sets => Schedule(() => - { - MoreButton.FadeTo(sets.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; - - if (!sets.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - foreach (var s in sets) - { - if (!s.OnlineBeatmapSetID.HasValue) - continue; - - ItemsContainer.Add(new DirectGridPanel(s.ToBeatmapSet(Rulesets)) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }); - } - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 23072f8d90..e444363e52 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -1,19 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; +using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Users; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer + public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer { - private GetUserMostPlayedBeatmapsRequest request; - public PaginatedMostPlayedBeatmapContainer(Bindable user) : base(user, "Most Played Beatmaps", "No records. :(") { @@ -22,35 +22,10 @@ namespace osu.Game.Overlays.Profile.Sections.Historical ItemsContainer.Direction = FillDirection.Vertical; } - protected override void ShowMore() - { - request = new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - request.Success += beatmaps => Schedule(() => - { - MoreButton.FadeTo(beatmaps.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; + protected override APIRequest> CreateRequest() + => new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - if (!beatmaps.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - MissingText.Hide(); - - foreach (var beatmap in beatmaps) - { - ItemsContainer.Add(new DrawableMostPlayedBeatmap(beatmap.GetBeatmapInfo(Rulesets), beatmap.PlayCount)); - } - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap item) + => new DrawableMostPlayedBeatmap(item.GetBeatmapInfo(Rulesets), item.PlayCount); } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 29b1d3c5aa..0e7cfc37c0 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -4,48 +4,24 @@ using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Game.Users; -using System.Linq; using osu.Framework.Bindables; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.API; +using System.Collections.Generic; namespace osu.Game.Overlays.Profile.Sections.Kudosu { - public class PaginatedKudosuHistoryContainer : PaginatedContainer + public class PaginatedKudosuHistoryContainer : PaginatedContainer { - private GetUserKudosuHistoryRequest request; - public PaginatedKudosuHistoryContainer(Bindable user, string header, string missing) : base(user, header, missing) { ItemsPerPage = 5; } - protected override void ShowMore() - { - request = new GetUserKudosuHistoryRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - request.Success += items => Schedule(() => - { - MoreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; + protected override APIRequest> CreateRequest() + => new GetUserKudosuHistoryRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - if (!items.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - MissingText.Hide(); - - foreach (var item in items) - ItemsContainer.Add(new DrawableKudosuHistoryItem(item)); - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item); } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index b459afcb49..e329fce67b 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -11,22 +11,25 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Rulesets; using osu.Game.Users; +using System.Collections.Generic; +using System.Linq; namespace osu.Game.Overlays.Profile.Sections { - public abstract class PaginatedContainer : FillFlowContainer + public abstract class PaginatedContainer : FillFlowContainer { - protected readonly FillFlowContainer ItemsContainer; - protected readonly ShowMoreButton MoreButton; - protected readonly OsuSpriteText MissingText; + private readonly ShowMoreButton moreButton; + private readonly OsuSpriteText missingText; + private APIRequest> retrievalRequest; + + [Resolved] + private IAPIProvider api { get; set; } protected int VisiblePages; protected int ItemsPerPage; protected readonly Bindable User = new Bindable(); - - protected IAPIProvider Api; - protected APIRequest RetrievalRequest; + protected readonly FillFlowContainer ItemsContainer; protected RulesetStore Rulesets; protected PaginatedContainer(Bindable user, string header, string missing) @@ -51,15 +54,15 @@ namespace osu.Game.Overlays.Profile.Sections RelativeSizeAxes = Axes.X, Spacing = new Vector2(0, 2), }, - MoreButton = new ShowMoreButton + moreButton = new ShowMoreButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Alpha = 0, Margin = new MarginPadding { Top = 10 }, - Action = ShowMore, + Action = showMore, }, - MissingText = new OsuSpriteText + missingText = new OsuSpriteText { Font = OsuFont.GetFont(size: 15), Text = missing, @@ -69,9 +72,8 @@ namespace osu.Game.Overlays.Profile.Sections } [BackgroundDependencyLoader] - private void load(IAPIProvider api, RulesetStore rulesets) + private void load(RulesetStore rulesets) { - Api = api; Rulesets = rulesets; User.ValueChanged += onUserChanged; @@ -84,9 +86,51 @@ namespace osu.Game.Overlays.Profile.Sections ItemsContainer.Clear(); if (e.NewValue != null) - ShowMore(); + showMore(); } - protected abstract void ShowMore(); + private void showMore() + { + retrievalRequest = CreateRequest(); + retrievalRequest.Success += items => UpdateItems(items); + + api.Queue(retrievalRequest); + } + + protected virtual void UpdateItems(List items) + { + Schedule(() => + { + moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); + moreButton.IsLoading = false; + + if (!items.Any() && VisiblePages == 1) + { + moreButton.Hide(); + moreButton.IsLoading = false; + missingText.Show(); + return; + } + + LoadComponentsAsync(items.Select(item => CreateDrawableItem(item)), i => + { + missingText.Hide(); + moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); + moreButton.IsLoading = false; + + ItemsContainer.AddRange(i); + }); + }); + } + + protected abstract APIRequest> CreateRequest(); + + protected abstract Drawable CreateDrawableItem(T item); + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + retrievalRequest?.Cancel(); + } } } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 4a9ac6e5c7..dfe300b069 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -5,18 +5,18 @@ using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Users; using System; -using System.Collections.Generic; -using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Online.API.Requests.Responses; +using System.Collections.Generic; +using osu.Game.Online.API; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class PaginatedScoreContainer : PaginatedContainer + public class PaginatedScoreContainer : PaginatedContainer { private readonly bool includeWeight; private readonly ScoreType type; - private GetUserScoresRequest request; public PaginatedScoreContainer(ScoreType type, Bindable user, string header, string missing, bool includeWeight = false) : base(user, header, missing) @@ -29,52 +29,27 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks ItemsContainer.Direction = FillDirection.Vertical; } - protected override void ShowMore() + protected override void UpdateItems(List items) { - request = new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - request.Success += scores => Schedule(() => - { - foreach (var s in scores) - s.Ruleset = Rulesets.GetRuleset(s.RulesetID); + foreach (var item in items) + item.Ruleset = Rulesets.GetRuleset(item.RulesetID); - if (!scores.Any() && VisiblePages == 1) - { - MoreButton.Hide(); - MoreButton.IsLoading = false; - MissingText.Show(); - return; - } - - IEnumerable drawableScores; - - switch (type) - { - default: - drawableScores = scores.Select(score => new DrawablePerformanceScore(score, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null)); - break; - - case ScoreType.Recent: - drawableScores = scores.Select(score => new DrawableTotalScore(score)); - break; - } - - LoadComponentsAsync(drawableScores, s => - { - MissingText.Hide(); - MoreButton.FadeTo(scores.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; - - ItemsContainer.AddRange(s); - }); - }); - - Api.Queue(request); + base.UpdateItems(items); } - protected override void Dispose(bool isDisposing) + protected override APIRequest> CreateRequest() + => new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); + + protected override Drawable CreateDrawableItem(APILegacyScoreInfo item) { - base.Dispose(isDisposing); - request?.Cancel(); + switch (type) + { + default: + return new DrawablePerformanceScore(item, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + + case ScoreType.Recent: + return new DrawableTotalScore(item); + } } } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index f2a778a874..0251dd0740 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -4,51 +4,24 @@ using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Game.Users; -using System.Linq; using osu.Framework.Bindables; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.API; +using System.Collections.Generic; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class PaginatedRecentActivityContainer : PaginatedContainer + public class PaginatedRecentActivityContainer : PaginatedContainer { - private GetUserRecentActivitiesRequest request; - public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) { ItemsPerPage = 5; } - protected override void ShowMore() - { - request = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - request.Success += activities => Schedule(() => - { - MoreButton.FadeTo(activities.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; + protected override APIRequest> CreateRequest() + => new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - if (!activities.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - MissingText.Hide(); - - foreach (APIRecentActivity activity in activities) - { - ItemsContainer.Add(new DrawableRecentActivity(activity)); - } - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + protected override Drawable CreateDrawableItem(APIRecentActivity item) => new DrawableRecentActivity(item); } } From 45c0826314fb89ec07026037aa93c7e50979cb80 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 23 Aug 2019 14:14:39 +0300 Subject: [PATCH 399/645] Remove repetitive code --- osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index e329fce67b..6c444b2e26 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -101,9 +101,6 @@ namespace osu.Game.Overlays.Profile.Sections { Schedule(() => { - moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); - moreButton.IsLoading = false; - if (!items.Any() && VisiblePages == 1) { moreButton.Hide(); From 6bf31e8f91111d762d657dd1f93dddfeb0577b2a Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 23 Aug 2019 13:15:38 +0200 Subject: [PATCH 400/645] Make song select grouping & sorting filters persistent --- osu.Game/Configuration/OsuConfigManager.cs | 6 +++ osu.Game/Screens/Select/FilterControl.cs | 54 +++++++--------------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 19f46c1d6a..6ebacc642d 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -8,6 +8,7 @@ using osu.Framework.Platform; using osu.Game.Overlays; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select; +using osu.Game.Screens.Select.Filter; namespace osu.Game.Configuration { @@ -25,6 +26,9 @@ namespace osu.Game.Configuration Set(OsuSetting.DisplayStarsMinimum, 0.0, 0, 10, 0.1); Set(OsuSetting.DisplayStarsMaximum, 10.0, 0, 10, 0.1); + Set(OsuSetting.SelectGroupingMode, GroupMode.All); + Set(OsuSetting.SelectSortingMode, SortMode.Title); + Set(OsuSetting.RandomSelectAlgorithm, RandomSelectAlgorithm.RandomPermutation); Set(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2, 1); @@ -150,6 +154,8 @@ namespace osu.Game.Configuration SaveUsername, DisplayStarsMinimum, DisplayStarsMaximum, + SelectGroupingMode, + SelectSortingMode, RandomSelectAlgorithm, ShowFpsDisplay, ChatDisplayHeight, diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 84e8e90f54..b97d64f013 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -29,40 +29,14 @@ namespace osu.Game.Screens.Select private readonly TabControl groupTabs; - private SortMode sort = SortMode.Title; + public readonly Bindable SortMode = new Bindable(Filter.SortMode.Title); - public SortMode Sort - { - get => sort; - set - { - if (sort != value) - { - sort = value; - FilterChanged?.Invoke(CreateCriteria()); - } - } - } - - private GroupMode group = GroupMode.All; - - public GroupMode Group - { - get => group; - set - { - if (group != value) - { - group = value; - FilterChanged?.Invoke(CreateCriteria()); - } - } - } + public readonly Bindable GroupMode = new Bindable(Filter.GroupMode.All); public FilterCriteria CreateCriteria() => new FilterCriteria { - Group = group, - Sort = sort, + Group = GroupMode.Value, + Sort = SortMode.Value, SearchText = searchTextBox.Text, AllowConvertedBeatmaps = showConverted.Value, Ruleset = ruleset.Value @@ -122,7 +96,7 @@ namespace osu.Game.Screens.Select Height = 24, Width = 0.5f, AutoSort = true, - Current = { Value = GroupMode.Title } + Current = GroupMode }, //spriteText = new OsuSpriteText //{ @@ -141,7 +115,7 @@ namespace osu.Game.Screens.Select Width = 0.5f, Height = 24, AutoSort = true, - Current = { Value = SortMode.Title } + Current = SortMode } } }, @@ -151,10 +125,8 @@ namespace osu.Game.Screens.Select searchTextBox.Current.ValueChanged += _ => FilterChanged?.Invoke(CreateCriteria()); - groupTabs.PinItem(GroupMode.All); - groupTabs.PinItem(GroupMode.RecentlyPlayed); - groupTabs.Current.ValueChanged += group => Group = group.NewValue; - sortTabs.Current.ValueChanged += sort => Sort = sort.NewValue; + groupTabs.PinItem(Filter.GroupMode.All); + groupTabs.PinItem(Filter.GroupMode.RecentlyPlayed); } public void Deactivate() @@ -184,7 +156,15 @@ namespace osu.Game.Screens.Select showConverted.ValueChanged += _ => updateCriteria(); ruleset.BindTo(parentRuleset); - ruleset.BindValueChanged(_ => updateCriteria(), true); + ruleset.BindValueChanged(_ => updateCriteria()); + + config.BindWith(OsuSetting.SelectGroupingMode, GroupMode); + config.BindWith(OsuSetting.SelectSortingMode, SortMode); + + GroupMode.BindValueChanged(_ => updateCriteria()); + SortMode.BindValueChanged(_ => updateCriteria()); + + updateCriteria(); } private void updateCriteria() => FilterChanged?.Invoke(CreateCriteria()); From 6ea10ada3451d0096c9e4da34f3e5ac51e50aaae Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 23 Aug 2019 13:31:45 +0200 Subject: [PATCH 401/645] Fix visual tests. --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 680250a226..2dbe53709b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -111,13 +111,13 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); - AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); - AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); - AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; }); - AddStep(@"Sort by DateAdded", delegate { songSelect.FilterControl.Sort = SortMode.DateAdded; }); - AddStep(@"Sort by BPM", delegate { songSelect.FilterControl.Sort = SortMode.BPM; }); - AddStep(@"Sort by Length", delegate { songSelect.FilterControl.Sort = SortMode.Length; }); - AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; }); + AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Artist; }); + AddStep(@"Sort by Title", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Title; }); + AddStep(@"Sort by Author", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Author; }); + AddStep(@"Sort by DateAdded", delegate { songSelect.FilterControl.SortMode.Value = SortMode.DateAdded; }); + AddStep(@"Sort by BPM", delegate { songSelect.FilterControl.SortMode.Value = SortMode.BPM; }); + AddStep(@"Sort by Length", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Length; }); + AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Difficulty; }); } [Test] From d8535574d10b26413c18639ccedc93ff15e00a4c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 14:32:43 +0300 Subject: [PATCH 402/645] Pass sample info to Skin.GetSample --- .../TestSceneCatcher.cs | 2 +- .../Gameplay/TestSceneSkinnableDrawable.cs | 7 ++++--- osu.Game/Skinning/DefaultSkin.cs | 3 ++- osu.Game/Skinning/ISkin.cs | 3 ++- osu.Game/Skinning/LegacySkin.cs | 20 +++++++++++-------- .../Skinning/LocalSkinOverrideContainer.cs | 7 ++++--- osu.Game/Skinning/Skin.cs | 3 ++- osu.Game/Skinning/SkinManager.cs | 3 ++- 8 files changed, 29 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 33f93cdb4a..72646e656e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Tests return null; } - public SampleChannel GetSample(string sampleName) => + public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException(); public Texture GetTexture(string componentName) => diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index 0b5978e3eb..6c003e62ec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; +using osu.Game.Audio; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Skinning; @@ -253,7 +254,7 @@ namespace osu.Game.Tests.Visual.Gameplay public Texture GetTexture(string componentName) => throw new NotImplementedException(); - public SampleChannel GetSample(string sampleName) => throw new NotImplementedException(); + public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException(); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); } @@ -264,7 +265,7 @@ namespace osu.Game.Tests.Visual.Gameplay public Texture GetTexture(string componentName) => throw new NotImplementedException(); - public SampleChannel GetSample(string sampleName) => throw new NotImplementedException(); + public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException(); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); } @@ -275,7 +276,7 @@ namespace osu.Game.Tests.Visual.Gameplay public Texture GetTexture(string componentName) => throw new NotImplementedException(); - public SampleChannel GetSample(string sampleName) => throw new NotImplementedException(); + public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException(); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); } diff --git a/osu.Game/Skinning/DefaultSkin.cs b/osu.Game/Skinning/DefaultSkin.cs index c7556dddd5..6072bb64ed 100644 --- a/osu.Game/Skinning/DefaultSkin.cs +++ b/osu.Game/Skinning/DefaultSkin.cs @@ -4,6 +4,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; +using osu.Game.Audio; namespace osu.Game.Skinning { @@ -19,6 +20,6 @@ namespace osu.Game.Skinning public override Texture GetTexture(string componentName) => null; - public override SampleChannel GetSample(string sampleName) => null; + public override SampleChannel GetSample(ISampleInfo sampleInfo) => null; } } diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index 0e67a1897c..4867aba0a9 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; +using osu.Game.Audio; namespace osu.Game.Skinning { @@ -17,7 +18,7 @@ namespace osu.Game.Skinning Texture GetTexture(string componentName); - SampleChannel GetSample(string sampleName); + SampleChannel GetSample(ISampleInfo sampleInfo); TValue GetValue(Func query) where TConfiguration : SkinConfiguration; } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 73957a203e..bf2f382527 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Framework.Text; +using osu.Game.Audio; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -212,18 +213,21 @@ namespace osu.Game.Skinning return texture; } - public override SampleChannel GetSample(string sampleName) + public override SampleChannel GetSample(ISampleInfo sampleInfo) { - var sample = Samples.Get(sampleName); - - if (sample == null) + foreach (var lookup in sampleInfo.LookupNames) { - // Try fallback to non-bank samples. - var bank = sampleName.Split('/').Last().Split('-')[0] + '-'; - sample = Samples.Get($"Gameplay/{sampleName.Replace(bank, "")}"); + var sample = Samples.Get(lookup); + + if (sample != null) + return sample; } - return sample; + if (sampleInfo is HitSampleInfo hsi) + // Try fallback to non-bank samples. + return Samples.Get($"{hsi.Name}"); + + return null; } private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index 7882e0f31b..fc36d1c8da 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; +using osu.Game.Audio; using osu.Game.Configuration; namespace osu.Game.Skinning @@ -49,13 +50,13 @@ namespace osu.Game.Skinning return fallbackSource.GetTexture(componentName); } - public SampleChannel GetSample(string sampleName) + public SampleChannel GetSample(ISampleInfo sampleInfo) { SampleChannel sourceChannel; - if (beatmapHitsounds.Value && (sourceChannel = skin?.GetSample(sampleName)) != null) + if (beatmapHitsounds.Value && (sourceChannel = skin?.GetSample(sampleInfo)) != null) return sourceChannel; - return fallbackSource?.GetSample(sampleName); + return fallbackSource?.GetSample(sampleInfo); } public TValue GetValue(Func query) where TConfiguration : SkinConfiguration diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 09c0d3d0bc..027d9df8b8 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; +using osu.Game.Audio; namespace osu.Game.Skinning { @@ -16,7 +17,7 @@ namespace osu.Game.Skinning public abstract Drawable GetDrawableComponent(string componentName); - public abstract SampleChannel GetSample(string sampleName); + public abstract SampleChannel GetSample(ISampleInfo sampleInfo); public abstract Texture GetTexture(string componentName); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 19997e8844..e747a8b1ce 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -15,6 +15,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Framework.Platform; +using osu.Game.Audio; using osu.Game.Database; using osu.Game.IO.Archives; @@ -120,7 +121,7 @@ namespace osu.Game.Skinning public Texture GetTexture(string componentName) => CurrentSkin.Value.GetTexture(componentName); - public SampleChannel GetSample(string sampleName) => CurrentSkin.Value.GetSample(sampleName); + public SampleChannel GetSample(ISampleInfo sampleInfo) => CurrentSkin.Value.GetSample(sampleInfo); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => CurrentSkin.Value.GetValue(query); } From 7e34afeab874911ef0fd3edb1ad94388fc681d9d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 23 Aug 2019 14:38:18 +0300 Subject: [PATCH 403/645] Conver to method group --- osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index 6c444b2e26..0e2b4c986a 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -82,6 +82,8 @@ namespace osu.Game.Overlays.Profile.Sections private void onUserChanged(ValueChangedEvent e) { + retrievalRequest?.Cancel(); + VisiblePages = 0; ItemsContainer.Clear(); @@ -92,7 +94,7 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { retrievalRequest = CreateRequest(); - retrievalRequest.Success += items => UpdateItems(items); + retrievalRequest.Success += UpdateItems; api.Queue(retrievalRequest); } @@ -109,13 +111,13 @@ namespace osu.Game.Overlays.Profile.Sections return; } - LoadComponentsAsync(items.Select(item => CreateDrawableItem(item)), i => + LoadComponentsAsync(items.Select(CreateDrawableItem), drawables => { missingText.Hide(); moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); moreButton.IsLoading = false; - ItemsContainer.AddRange(i); + ItemsContainer.AddRange(drawables); }); }); } From 0cde0982e595da7dc28240b78ed534e83f171507 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 23 Aug 2019 14:52:26 +0300 Subject: [PATCH 404/645] Use cansellation token --- osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index 0e2b4c986a..75601041e8 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets; using osu.Game.Users; using System.Collections.Generic; using System.Linq; +using System.Threading; namespace osu.Game.Overlays.Profile.Sections { @@ -21,6 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections private readonly ShowMoreButton moreButton; private readonly OsuSpriteText missingText; private APIRequest> retrievalRequest; + private CancellationTokenSource loadCancellation; [Resolved] private IAPIProvider api { get; set; } @@ -82,6 +84,7 @@ namespace osu.Game.Overlays.Profile.Sections private void onUserChanged(ValueChangedEvent e) { + loadCancellation?.Cancel(); retrievalRequest?.Cancel(); VisiblePages = 0; @@ -93,6 +96,8 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { + loadCancellation = new CancellationTokenSource(); + retrievalRequest = CreateRequest(); retrievalRequest.Success += UpdateItems; @@ -118,7 +123,7 @@ namespace osu.Game.Overlays.Profile.Sections moreButton.IsLoading = false; ItemsContainer.AddRange(drawables); - }); + }, loadCancellation.Token); }); } From 7b04fb1690fa32ccdd2f75d6bb4b4b33f5b6806f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 14:54:39 +0300 Subject: [PATCH 405/645] StoryboardSample -> StoryboardSampleInfo --- .../Formats/LegacyStoryboardDecoder.cs | 2 +- .../Drawables/DrawableStoryboardSample.cs | 24 +++++++++---------- osu.Game/Storyboards/StoryboardSample.cs | 10 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 17df9ccc7e..14c6ea5c8e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -121,7 +121,7 @@ namespace osu.Game.Beatmaps.Formats var layer = parseLayer(split[2]); var path = cleanFilename(split[3]); var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100; - storyboard.GetLayer(layer).Add(new StoryboardSample(path, time, volume)); + storyboard.GetLayer(layer).Add(new StoryboardSampleInfo(path, time, (int)volume)); break; } } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index ffd238d4e1..b04f1d4518 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.IO; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; @@ -17,25 +16,24 @@ namespace osu.Game.Storyboards.Drawables /// private const double allowable_late_start = 100; - private readonly StoryboardSample sample; + private readonly StoryboardSampleInfo sampleInfo; private SampleChannel channel; public override bool RemoveWhenNotAlive => false; - public DrawableStoryboardSample(StoryboardSample sample) + public DrawableStoryboardSample(StoryboardSampleInfo sampleInfo) { - this.sample = sample; - LifetimeStart = sample.StartTime; + this.sampleInfo = sampleInfo; + LifetimeStart = sampleInfo.StartTime; } [BackgroundDependencyLoader] private void load(IBindable beatmap) { - // Try first with the full name, then attempt with no path - channel = beatmap.Value.Skin.GetSample(sample.Path) ?? beatmap.Value.Skin.GetSample(Path.ChangeExtension(sample.Path, null)); + channel = beatmap.Value.Skin.GetSample(sampleInfo); if (channel != null) - channel.Volume.Value = sample.Volume / 100; + channel.Volume.Value = sampleInfo.Volume / 100.0; } protected override void Update() @@ -43,27 +41,27 @@ namespace osu.Game.Storyboards.Drawables base.Update(); // TODO: this logic will need to be consolidated with other game samples like hit sounds. - if (Time.Current < sample.StartTime) + if (Time.Current < sampleInfo.StartTime) { // We've rewound before the start time of the sample channel?.Stop(); // In the case that the user fast-forwards to a point far beyond the start time of the sample, // we want to be able to fall into the if-conditional below (therefore we must not have a life time end) - LifetimeStart = sample.StartTime; + LifetimeStart = sampleInfo.StartTime; LifetimeEnd = double.MaxValue; } - else if (Time.Current - Time.Elapsed < sample.StartTime) + else if (Time.Current - Time.Elapsed < sampleInfo.StartTime) { // We've passed the start time of the sample. We only play the sample if we're within an allowable range // from the sample's start, to reduce layering if we've been fast-forwarded far into the future - if (Time.Current - sample.StartTime < allowable_late_start) + if (Time.Current - sampleInfo.StartTime < allowable_late_start) channel?.Play(); // In the case that the user rewinds to a point far behind the start time of the sample, // we want to be able to fall into the if-conditional above (therefore we must not have a life time start) LifetimeStart = double.MinValue; - LifetimeEnd = sample.StartTime; + LifetimeEnd = sampleInfo.StartTime; } } } diff --git a/osu.Game/Storyboards/StoryboardSample.cs b/osu.Game/Storyboards/StoryboardSample.cs index 24231cdca6..4635109d51 100644 --- a/osu.Game/Storyboards/StoryboardSample.cs +++ b/osu.Game/Storyboards/StoryboardSample.cs @@ -1,21 +1,23 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Framework.Graphics; +using osu.Game.Audio; using osu.Game.Storyboards.Drawables; namespace osu.Game.Storyboards { - public class StoryboardSample : IStoryboardElement + public class StoryboardSampleInfo : IStoryboardElement, ISampleInfo { - public string Path { get; set; } + public string Path { get; } public bool IsDrawable => true; public double StartTime { get; } - public float Volume; + public int Volume { get; } - public StoryboardSample(string path, double time, float volume) + public StoryboardSampleInfo(string path, double time, int volume) { Path = path; StartTime = time; From b6b050d5e9662155924c3dfa5c41a22a7fbeb1cd Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 14:55:06 +0300 Subject: [PATCH 406/645] Add sample path to the lookup names --- osu.Game/Storyboards/StoryboardSample.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Storyboards/StoryboardSample.cs b/osu.Game/Storyboards/StoryboardSample.cs index 4635109d51..5d6ce215f5 100644 --- a/osu.Game/Storyboards/StoryboardSample.cs +++ b/osu.Game/Storyboards/StoryboardSample.cs @@ -17,6 +17,13 @@ namespace osu.Game.Storyboards public int Volume { get; } + public IEnumerable LookupNames => new[] + { + // Try first with the full name, then attempt with no path + Path, + System.IO.Path.ChangeExtension(Path, null), + }; + public StoryboardSampleInfo(string path, double time, int volume) { Path = path; From da72806693cc9688f189f61daa17f2f45ead6145 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 14:55:38 +0300 Subject: [PATCH 407/645] Remove lookup logic from SkinnableSound --- osu.Game/Skinning/SkinnableSound.cs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8e2b5cec98..23093d9bd9 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -43,28 +42,21 @@ namespace osu.Game.Skinning { channels = hitSamples.Select(s => { - var ch = loadChannel(s, skin.GetSample); + var ch = skin.GetSample(s); + if (ch == null && allowFallback) - ch = loadChannel(s, audio.Samples.Get); + if (s is HitSampleInfo hsi) + ch = audio.Samples.Get(string.IsNullOrEmpty(hsi.Namespace) + ? $"Gameplay/{hsi.Namespace}/{hsi.Bank}-{hsi.Name}" + : $"Gameplay/{hsi.Bank}-{hsi.Name}"); + + if (ch != null) + ch.Volume.Value = s.Volume / 100.0; + return ch; }).Where(c => c != null).ToArray(); } - private SampleChannel loadChannel(ISampleInfo info, Func getSampleFunction) - { - foreach (var lookup in info.LookupNames) - { - var ch = getSampleFunction($"Gameplay/{lookup}"); - if (ch == null) - continue; - - ch.Volume.Value = info.Volume / 100.0; - return ch; - } - - return null; - } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From ce5ee095b96111f95bb191dda6e3ea04342c8393 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 23 Aug 2019 14:03:56 +0200 Subject: [PATCH 408/645] Fetch config bindables in BDL. --- osu.Game/Screens/Select/FilterControl.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index b97d64f013..44bc3235ac 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -29,9 +29,9 @@ namespace osu.Game.Screens.Select private readonly TabControl groupTabs; - public readonly Bindable SortMode = new Bindable(Filter.SortMode.Title); + public Bindable SortMode; - public readonly Bindable GroupMode = new Bindable(Filter.GroupMode.All); + public Bindable GroupMode; public FilterCriteria CreateCriteria() => new FilterCriteria { @@ -96,7 +96,6 @@ namespace osu.Game.Screens.Select Height = 24, Width = 0.5f, AutoSort = true, - Current = GroupMode }, //spriteText = new OsuSpriteText //{ @@ -115,7 +114,6 @@ namespace osu.Game.Screens.Select Width = 0.5f, Height = 24, AutoSort = true, - Current = SortMode } } }, @@ -158,8 +156,11 @@ namespace osu.Game.Screens.Select ruleset.BindTo(parentRuleset); ruleset.BindValueChanged(_ => updateCriteria()); - config.BindWith(OsuSetting.SelectGroupingMode, GroupMode); - config.BindWith(OsuSetting.SelectSortingMode, SortMode); + SortMode = config.GetBindable(OsuSetting.SelectSortingMode); + GroupMode = config.GetBindable(OsuSetting.SelectGroupingMode); + + sortTabs.Current.BindTo(SortMode); + groupTabs.Current.BindTo(GroupMode); GroupMode.BindValueChanged(_ => updateCriteria()); SortMode.BindValueChanged(_ => updateCriteria()); From 94b5caf7404e072353884b2b278ddea8adce6baf Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 15:18:56 +0300 Subject: [PATCH 409/645] Fix build issues --- osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs | 1 + osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 72646e656e..406c0af28d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -15,6 +15,7 @@ using osu.Framework.Graphics.Sprites; using osuTK.Graphics; using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Textures; +using osu.Game.Audio; namespace osu.Game.Rulesets.Catch.Tests { diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 971518909d..953763c95d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Beatmaps.Formats int spriteCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSprite)); int animationCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardAnimation)); - int sampleCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSample)); + int sampleCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSampleInfo)); Assert.AreEqual(15, spriteCount); Assert.AreEqual(1, animationCount); From 72a644996c830cd5e1479024a02b81d58fe1e6f0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2019 13:41:27 +0000 Subject: [PATCH 410/645] Bump NUnit3TestAdapter from 3.14.0 to 3.15.0 Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 3.14.0 to 3.15.0. - [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases) - [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V3.14...V3.15) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 4100404da6..7c282f449b 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 013d2a71d4..4dcfc1b81f 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 92c5c77aac..197309c7c4 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 82055ecaee..a5db1625d9 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 50530088c2..4a9d88f3a6 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index 257db89a20..2a8bd393da 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -7,7 +7,7 @@ - + WinExe From 1295ec490f7c1e5aedba2d349cfc181ef4710114 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 17:57:31 +0300 Subject: [PATCH 411/645] Fix difficulty icon not wrapping correctly in beatmap set overlay --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 104315f1c2..28947b6f22 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -91,7 +91,8 @@ namespace osu.Game.Overlays.BeatmapSet { difficulties = new DifficultiesContainer { - AutoSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, OnLostHover = () => { From 67acf20805e083264d039d5c063f8bdd94026979 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 18:31:53 +0300 Subject: [PATCH 412/645] Add test beatmap set with many difficulties --- .../Online/TestSceneBeatmapSetOverlay.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index daee419b52..8f19df65a9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -135,6 +135,9 @@ namespace osu.Game.Tests.Visual.Online }); downloadAssert(true); + + AddStep("show many difficulties", () => overlay.ShowBeatmapSet(createManyDifficultiesBeatmapSet())); + downloadAssert(true); } [Test] @@ -222,6 +225,56 @@ namespace osu.Game.Tests.Visual.Online AddStep(@"show without reload", overlay.Show); } + private BeatmapSetInfo createManyDifficultiesBeatmapSet() + { + var beatmaps = new List(); + + for (int i = 1; i < 41; i++) + { + beatmaps.Add(new BeatmapInfo + { + OnlineBeatmapID = i * 10, + Version = $"Test #{i}", + Ruleset = Ruleset.Value, + StarDifficulty = 2 + i * 0.1, + BaseDifficulty = new BeatmapDifficulty + { + OverallDifficulty = 3.5f, + }, + OnlineInfo = new BeatmapOnlineInfo(), + Metrics = new BeatmapMetrics + { + Fails = Enumerable.Range(1, 100).Select(j => j % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(j => j % 12 - 6).ToArray(), + }, + }); + } + + return new BeatmapSetInfo + { + OnlineBeatmapSetID = 123, + Metadata = new BeatmapMetadata + { + Title = @"many difficulties beatmap", + Artist = @"none", + Author = new User + { + Username = @"BanchoBot", + Id = 3, + }, + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Preview = @"https://b.ppy.sh/preview/123.mp3", + HasVideo = true, + HasStoryboard = true, + Covers = new BeatmapSetOnlineCovers(), + }, + Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, + Beatmaps = beatmaps, + }; + } + private void downloadAssert(bool shown) { AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.DownloadButtonsVisible == shown); From f639df849fa3094a27a35fa08763e6eb501a0def Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 23:11:36 +0300 Subject: [PATCH 413/645] Allow for difficulty icon to contain content --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 5cce29d609..81f517dd86 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -19,23 +19,33 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class DifficultyIcon : Container, IHasCustomTooltip + public class DifficultyIcon : CompositeDrawable, IHasCustomTooltip { private readonly BeatmapInfo beatmap; private readonly RulesetInfo ruleset; + private readonly Container iconContainer; + + /// + /// Size of this difficulty icon. + /// + public new Vector2 Size + { + get => iconContainer.Size; + set => iconContainer.Size = value; + } + public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, bool shouldShowTooltip = true) { - if (beatmap == null) - throw new ArgumentNullException(nameof(beatmap)); - - this.beatmap = beatmap; + this.beatmap = beatmap ?? throw new ArgumentNullException(nameof(beatmap)); this.ruleset = ruleset ?? beatmap.Ruleset; if (shouldShowTooltip) TooltipContent = beatmap; - Size = new Vector2(20); + AutoSizeAxes = Axes.Both; + + InternalChild = iconContainer = new Container { Size = new Vector2(20f) }; } public string TooltipText { get; set; } @@ -47,7 +57,7 @@ namespace osu.Game.Beatmaps.Drawables [BackgroundDependencyLoader] private void load(OsuColour colours) { - Children = new Drawable[] + iconContainer.Children = new Drawable[] { new CircularContainer { From d4236c574f99853de259925ebdd44e9dc004200b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 23:30:54 +0300 Subject: [PATCH 414/645] Allow difficulty icon to be updateable --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 93 ++++++++++++------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 81f517dd86..6d9d0afc78 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -1,7 +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 System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -21,10 +22,22 @@ namespace osu.Game.Beatmaps.Drawables { public class DifficultyIcon : CompositeDrawable, IHasCustomTooltip { - private readonly BeatmapInfo beatmap; - private readonly RulesetInfo ruleset; + private BeatmapInfo beatmap; private readonly Container iconContainer; + private readonly Box iconBg; + + protected BeatmapInfo Beatmap + { + get => beatmap; + set + { + beatmap = value; + + if (IsLoaded) + updateIconColour(); + } + } /// /// Size of this difficulty icon. @@ -37,15 +50,46 @@ namespace osu.Game.Beatmaps.Drawables public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, bool shouldShowTooltip = true) { - this.beatmap = beatmap ?? throw new ArgumentNullException(nameof(beatmap)); + this.beatmap = beatmap; - this.ruleset = ruleset ?? beatmap.Ruleset; if (shouldShowTooltip) TooltipContent = beatmap; AutoSizeAxes = Axes.Both; - InternalChild = iconContainer = new Container { Size = new Vector2(20f) }; + InternalChild = iconContainer = new Container + { + Size = new Vector2(20f), + Children = new Drawable[] + { + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.84f), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.08f), + Type = EdgeEffectType.Shadow, + Radius = 5, + }, + Child = iconBg = new Box + { + RelativeSizeAxes = Axes.Both, + }, + }, + new ConstrainedIconContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) + Icon = (ruleset ?? beatmap?.Ruleset)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } + } + } + }; } public string TooltipText { get; set; } @@ -54,41 +98,18 @@ namespace osu.Game.Beatmaps.Drawables public object TooltipContent { get; set; } + private OsuColour colours; + [BackgroundDependencyLoader] private void load(OsuColour colours) { - iconContainer.Children = new Drawable[] - { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.84f), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Masking = true, - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.08f), - Type = EdgeEffectType.Shadow, - Radius = 5, - }, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.ForDifficultyRating(beatmap.DifficultyRating), - }, - }, - new ConstrainedIconContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) - Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } - } - }; + this.colours = colours; + + updateIconColour(); } + private void updateIconColour() => iconBg.Colour = colours.ForDifficultyRating(beatmap.DifficultyRating); + private class DifficultyIconTooltip : VisibilityContainer, ITooltip { private readonly OsuSpriteText difficultyName, starRating; From 83b6e0f30c674b19607cac50b79d899e036721a5 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 23:36:23 +0300 Subject: [PATCH 415/645] Implement grouped difficulty icon --- .../Drawables/GroupedDifficultyIcon.cs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs diff --git a/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs new file mode 100644 index 0000000000..17f2bf719d --- /dev/null +++ b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs @@ -0,0 +1,58 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets; +using osuTK.Graphics; + +namespace osu.Game.Beatmaps.Drawables +{ + public class GroupedDifficultyIcon : DifficultyIcon + { + private readonly OsuSpriteText counter; + + private List beatmaps; + + protected List Beatmaps + { + get => beatmaps; + set + { + beatmaps = value; + + updateDisplay(); + } + } + + public GroupedDifficultyIcon(List beatmaps, RulesetInfo ruleset, Color4 counterColour) + : base(null, ruleset, false) + { + this.beatmaps = beatmaps; + + AddInternal(counter = new OsuSpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Padding = new MarginPadding { Left = Size.X }, + Margin = new MarginPadding { Left = 2, Right = 5 }, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), + Colour = counterColour, + }); + + updateDisplay(); + } + + private void updateDisplay() + { + if (beatmaps == null || beatmaps.Count == 0) + return; + + Beatmap = beatmaps.OrderBy(b => b.StarDifficulty).Last(); + counter.Text = beatmaps.Count.ToString(); + } + } +} From 63e6aca61b6f4a246bc05d17d1fbc1cf6e9c2b57 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Fri, 23 Aug 2019 23:40:41 +0300 Subject: [PATCH 416/645] Add logic to create grouped difficulty icons in direct panel --- osu.Game/Overlays/Direct/DirectPanel.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 8199d80528..b2f3c6befb 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -18,6 +18,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -28,10 +29,12 @@ namespace osu.Game.Overlays.Direct public readonly BeatmapSetInfo SetInfo; private const double hover_transition_time = 400; + private const int maximum_difficulty_icons = 15; private Container content; private BeatmapSetOverlay beatmapSetOverlay; + private RulesetStore rulesets; public PreviewTrack Preview => PlayButton.Preview; public Bindable PreviewPlaying => PlayButton.Playing; @@ -67,9 +70,10 @@ namespace osu.Game.Overlays.Direct }; [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay) + private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay, RulesetStore rulesets) { this.beatmapSetOverlay = beatmapSetOverlay; + this.rulesets = rulesets; AddInternal(content = new Container { @@ -142,8 +146,18 @@ namespace osu.Game.Overlays.Direct { var icons = new List(); - foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty)) - icons.Add(new DifficultyIcon(b)); + if (SetInfo.Beatmaps.Count > maximum_difficulty_icons) + { + foreach (var ruleset in rulesets.AvailableRulesets) + { + List list; + if ((list = SetInfo.Beatmaps.FindAll(b => b.Ruleset.Equals(ruleset))).Count > 0) + icons.Add(new GroupedDifficultyIcon(list, ruleset, this is DirectListPanel ? Color4.White : Color4.Black)); + } + } + else + foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty)) + icons.Add(new DifficultyIcon(b)); return icons; } From 87340061e16d6d41c59802c5c9f9e3b1f0e90e01 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 00:06:28 +0300 Subject: [PATCH 417/645] Add logic to create grouped difficulty icons in carousel beatmap set --- .../Carousel/DrawableCarouselBeatmapSet.cs | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 0259f3cd81..c6bd726632 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; +using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -39,7 +40,7 @@ namespace osu.Game.Screens.Select.Carousel } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) + private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay, RulesetStore rulesets) { restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; @@ -95,11 +96,11 @@ namespace osu.Game.Screens.Select.Carousel TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapSet.Status }, - new FillFlowContainer + new FillFlowContainer { AutoSizeAxes = Axes.Both, Spacing = new Vector2(3), - Children = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList() + Children = getDifficultyIcons(rulesets), }, } } @@ -108,6 +109,27 @@ namespace osu.Game.Screens.Select.Carousel }; } + private const int maximum_difficulty_icons = 18; + + private List getDifficultyIcons(RulesetStore rulesets) + { + var beatmaps = ((CarouselBeatmapSet)Item).Beatmaps.ToList(); + var icons = new List(); + + if (beatmaps.Count > maximum_difficulty_icons) + { + foreach (var ruleset in rulesets.AvailableRulesets.OrderBy(r => r.ID)) + { + List list; + if ((list = beatmaps.FindAll(b => b.Beatmap.Ruleset.Equals(ruleset))).Count > 0) + icons.Add(new FilterableGroupedDifficultyIcon(list, ruleset)); + } + } + else beatmaps.ForEach(b => icons.Add(new FilterableDifficultyIcon(b))); + + return icons; + } + public MenuItem[] ContextMenuItems { get @@ -205,5 +227,21 @@ namespace osu.Game.Screens.Select.Carousel filtered.TriggerChange(); } } + + public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon + { + public FilterableGroupedDifficultyIcon(List items, RulesetInfo ruleset) + : base(items.Select(i => i.Beatmap).ToList(), ruleset, Color4.White) + { + items.ForEach(item => item.Filtered.ValueChanged += _ => + { + var hiddenItems = items.FindAll(i => !i.Filtered.Value); + var hasHidden = hiddenItems.Count > 0; + + this.FadeTo(hasHidden ? 1 : 0.1f, 100); + Beatmaps = (hasHidden ? hiddenItems : items).Select(i => i.Beatmap).ToList(); + }); + } + } } } From 8584d3ba231e6b8c67d7ea3f85bf3c5075c996c1 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 00:31:36 +0300 Subject: [PATCH 418/645] Add many difficulties beatmap direct panel to the tests --- .../Visual/Online/TestSceneDirectPanel.cs | 62 +++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 53dbaeddda..731cb62518 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Overlays.Direct; using osu.Game.Rulesets; -using osu.Game.Rulesets.Osu; using osu.Game.Users; using osuTK; @@ -24,7 +23,7 @@ namespace osu.Game.Tests.Visual.Online typeof(IconPill) }; - private BeatmapSetInfo getUndownloadableBeatmapSet(RulesetInfo ruleset) => new BeatmapSetInfo + private BeatmapSetInfo getUndownloadableBeatmapSet() => new BeatmapSetInfo { OnlineBeatmapSetID = 123, Metadata = new BeatmapMetadata @@ -56,23 +55,62 @@ namespace osu.Game.Tests.Visual.Online { new BeatmapInfo { - Ruleset = ruleset, + Ruleset = Ruleset.Value, Version = "Test", StarDifficulty = 6.42, } } }; - [BackgroundDependencyLoader] - private void load() + private BeatmapSetInfo getManyDifficultiesBeatmapSet(RulesetStore rulesets) { - var ruleset = new OsuRuleset().RulesetInfo; + var beatmaps = new List(); - var normal = CreateWorkingBeatmap(ruleset).BeatmapSetInfo; + for (int i = 0; i < 100; i++) + { + beatmaps.Add(new BeatmapInfo + { + Ruleset = rulesets.GetRuleset(i % 4), + StarDifficulty = 2 + i % 4 * 2, + BaseDifficulty = new BeatmapDifficulty + { + OverallDifficulty = 3.5f, + } + }); + } + + return new BeatmapSetInfo + { + OnlineBeatmapSetID = 1, + Metadata = new BeatmapMetadata + { + Title = "many difficulties beatmap", + Artist = "test", + Author = new User + { + Username = "BanchoBot", + Id = 3, + } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + HasVideo = true, + HasStoryboard = true, + Covers = new BeatmapSetOnlineCovers(), + }, + Beatmaps = beatmaps, + }; + } + + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + var normal = CreateWorkingBeatmap(Ruleset.Value).BeatmapSetInfo; normal.OnlineInfo.HasVideo = true; normal.OnlineInfo.HasStoryboard = true; - var undownloadable = getUndownloadableBeatmapSet(ruleset); + var undownloadable = getUndownloadableBeatmapSet(); + var manyDifficulties = getManyDifficultiesBeatmapSet(rulesets); Child = new BasicScrollContainer { @@ -81,15 +119,17 @@ namespace osu.Game.Tests.Visual.Online { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, + Direction = FillDirection.Full, Padding = new MarginPadding(20), - Spacing = new Vector2(0, 20), + Spacing = new Vector2(5, 20), Children = new Drawable[] { new DirectGridPanel(normal), - new DirectListPanel(normal), new DirectGridPanel(undownloadable), + new DirectGridPanel(manyDifficulties), + new DirectListPanel(normal), new DirectListPanel(undownloadable), + new DirectListPanel(manyDifficulties), }, }, }; From f6feef6b5661cb3b40276311ac2745ee5f3b1053 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 00:33:14 +0300 Subject: [PATCH 419/645] Remove redundant using directive --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 6d9d0afc78..7732aa96f8 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.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.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; From 8ccbe84f67b87ba97b45576c495a53e509fa878f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 01:30:33 +0300 Subject: [PATCH 420/645] Loop on distinct rulesets of beatmap instead of all --- osu.Game/Overlays/Direct/DirectPanel.cs | 12 +++--------- .../Select/Carousel/DrawableCarouselBeatmapSet.cs | 14 +++++--------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index b2f3c6befb..d6258061e1 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -34,7 +34,6 @@ namespace osu.Game.Overlays.Direct private Container content; private BeatmapSetOverlay beatmapSetOverlay; - private RulesetStore rulesets; public PreviewTrack Preview => PlayButton.Preview; public Bindable PreviewPlaying => PlayButton.Playing; @@ -70,10 +69,9 @@ namespace osu.Game.Overlays.Direct }; [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay, RulesetStore rulesets) + private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay) { this.beatmapSetOverlay = beatmapSetOverlay; - this.rulesets = rulesets; AddInternal(content = new Container { @@ -148,12 +146,8 @@ namespace osu.Game.Overlays.Direct if (SetInfo.Beatmaps.Count > maximum_difficulty_icons) { - foreach (var ruleset in rulesets.AvailableRulesets) - { - List list; - if ((list = SetInfo.Beatmaps.FindAll(b => b.Ruleset.Equals(ruleset))).Count > 0) - icons.Add(new GroupedDifficultyIcon(list, ruleset, this is DirectListPanel ? Color4.White : Color4.Black)); - } + foreach (var ruleset in SetInfo.Beatmaps.Select(b => b.Ruleset).Distinct()) + icons.Add(new GroupedDifficultyIcon(SetInfo.Beatmaps.FindAll(b => b.Ruleset.Equals(ruleset)), ruleset, this is DirectListPanel ? Color4.White : Color4.Black)); } else foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty)) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index c6bd726632..69b9aa399a 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -40,7 +40,7 @@ namespace osu.Game.Screens.Select.Carousel } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay, RulesetStore rulesets) + private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Select.Carousel { AutoSizeAxes = Axes.Both, Spacing = new Vector2(3), - Children = getDifficultyIcons(rulesets), + Children = getDifficultyIcons(), }, } } @@ -111,19 +111,15 @@ namespace osu.Game.Screens.Select.Carousel private const int maximum_difficulty_icons = 18; - private List getDifficultyIcons(RulesetStore rulesets) + private List getDifficultyIcons() { var beatmaps = ((CarouselBeatmapSet)Item).Beatmaps.ToList(); var icons = new List(); if (beatmaps.Count > maximum_difficulty_icons) { - foreach (var ruleset in rulesets.AvailableRulesets.OrderBy(r => r.ID)) - { - List list; - if ((list = beatmaps.FindAll(b => b.Beatmap.Ruleset.Equals(ruleset))).Count > 0) - icons.Add(new FilterableGroupedDifficultyIcon(list, ruleset)); - } + foreach (var ruleset in beatmaps.Select(b => b.Beatmap.Ruleset).Distinct()) + icons.Add(new FilterableGroupedDifficultyIcon(beatmaps.FindAll(b => b.Beatmap.Ruleset.Equals(ruleset)), ruleset)); } else beatmaps.ForEach(b => icons.Add(new FilterableDifficultyIcon(b))); From 830ddd6ed9a99c42bac7ba4dfa9714751b46076b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 01:31:53 +0300 Subject: [PATCH 421/645] Use all rulesets for many difficulties test --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 7c9b7c7815..6669ec7da3 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -516,6 +516,7 @@ namespace osu.Game.Tests.Visual.SongSelect OnlineBeatmapID = b * 10, Path = $"extra{b}.osu", Version = $"Extra {b}", + Ruleset = rulesets.GetRuleset((b - 1) % 4), StarDifficulty = 2, BaseDifficulty = new BeatmapDifficulty { From 008e39b7381c0b0b7ffcee28df42019ab967ba49 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 01:40:40 +0300 Subject: [PATCH 422/645] Remove redundant using directive --- osu.Game/Overlays/Direct/DirectPanel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index d6258061e1..7e16daee75 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -18,7 +18,6 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; From 0bcd323d17b12d1c48a13bbc7de2d674a156d513 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 09:30:43 +0300 Subject: [PATCH 423/645] Remove unnecessary string literal --- osu.Game/Skinning/LegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index bf2f382527..d699b1f3c6 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -225,7 +225,7 @@ namespace osu.Game.Skinning if (sampleInfo is HitSampleInfo hsi) // Try fallback to non-bank samples. - return Samples.Get($"{hsi.Name}"); + return Samples.Get(hsi.Name); return null; } From af4adb6339e807ee71be35766c1366fb67fcbf38 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 24 Aug 2019 09:43:55 +0300 Subject: [PATCH 424/645] Add xmldoc --- osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs index 17f2bf719d..b48b966918 100644 --- a/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs @@ -11,6 +11,12 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { + /// + /// A difficulty icon that contains a counter on the right-side of it. + /// + /// + /// Used in cases when there are too many difficulty icons to show. + /// public class GroupedDifficultyIcon : DifficultyIcon { private readonly OsuSpriteText counter; From b204e4419a9dab314f49a4dc52682b95fe8e66e2 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 24 Aug 2019 10:34:54 +0200 Subject: [PATCH 425/645] Rename SelectSortingMode & SelectGroupingMode -> SongSelectSortingMode & SongSelectGroupingMode --- osu.Game/Configuration/OsuConfigManager.cs | 8 ++++---- osu.Game/Screens/Select/FilterControl.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 6ebacc642d..b13e115387 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -26,8 +26,8 @@ namespace osu.Game.Configuration Set(OsuSetting.DisplayStarsMinimum, 0.0, 0, 10, 0.1); Set(OsuSetting.DisplayStarsMaximum, 10.0, 0, 10, 0.1); - Set(OsuSetting.SelectGroupingMode, GroupMode.All); - Set(OsuSetting.SelectSortingMode, SortMode.Title); + Set(OsuSetting.SongSelectGroupingMode, GroupMode.All); + Set(OsuSetting.SongSelectSortingMode, SortMode.Title); Set(OsuSetting.RandomSelectAlgorithm, RandomSelectAlgorithm.RandomPermutation); @@ -154,8 +154,8 @@ namespace osu.Game.Configuration SaveUsername, DisplayStarsMinimum, DisplayStarsMaximum, - SelectGroupingMode, - SelectSortingMode, + SongSelectGroupingMode, + SongSelectSortingMode, RandomSelectAlgorithm, ShowFpsDisplay, ChatDisplayHeight, diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 44bc3235ac..06b6cccf96 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -156,8 +156,8 @@ namespace osu.Game.Screens.Select ruleset.BindTo(parentRuleset); ruleset.BindValueChanged(_ => updateCriteria()); - SortMode = config.GetBindable(OsuSetting.SelectSortingMode); - GroupMode = config.GetBindable(OsuSetting.SelectGroupingMode); + SortMode = config.GetBindable(OsuSetting.SongSelectSortingMode); + GroupMode = config.GetBindable(OsuSetting.SongSelectGroupingMode); sortTabs.Current.BindTo(SortMode); groupTabs.Current.BindTo(GroupMode); From a19a9b90ede7f812335433b8f171a56fab578a29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 25 Aug 2019 11:38:26 +0900 Subject: [PATCH 426/645] Simplify group filter display --- .../Drawables/GroupedDifficultyIcon.cs | 33 ++----------------- .../Carousel/DrawableCarouselBeatmapSet.cs | 7 ++-- 2 files changed, 5 insertions(+), 35 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs index b48b966918..fbad113caa 100644 --- a/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/GroupedDifficultyIcon.cs @@ -19,46 +19,19 @@ namespace osu.Game.Beatmaps.Drawables /// public class GroupedDifficultyIcon : DifficultyIcon { - private readonly OsuSpriteText counter; - - private List beatmaps; - - protected List Beatmaps - { - get => beatmaps; - set - { - beatmaps = value; - - updateDisplay(); - } - } - public GroupedDifficultyIcon(List beatmaps, RulesetInfo ruleset, Color4 counterColour) - : base(null, ruleset, false) + : base(beatmaps.OrderBy(b => b.StarDifficulty).Last(), ruleset, false) { - this.beatmaps = beatmaps; - - AddInternal(counter = new OsuSpriteText + AddInternal(new OsuSpriteText { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Padding = new MarginPadding { Left = Size.X }, Margin = new MarginPadding { Left = 2, Right = 5 }, Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), + Text = beatmaps.Count.ToString(), Colour = counterColour, }); - - updateDisplay(); - } - - private void updateDisplay() - { - if (beatmaps == null || beatmaps.Count == 0) - return; - - Beatmap = beatmaps.OrderBy(b => b.StarDifficulty).Last(); - counter.Text = beatmaps.Count.ToString(); } } } diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 69b9aa399a..79e5debdd2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -231,11 +231,8 @@ namespace osu.Game.Screens.Select.Carousel { items.ForEach(item => item.Filtered.ValueChanged += _ => { - var hiddenItems = items.FindAll(i => !i.Filtered.Value); - var hasHidden = hiddenItems.Count > 0; - - this.FadeTo(hasHidden ? 1 : 0.1f, 100); - Beatmaps = (hasHidden ? hiddenItems : items).Select(i => i.Beatmap).ToList(); + // for now, fade the whole group based on the ratio of hidden items. + this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100); }); } } From 2e21fbcf6a2ce843172a1f58be10dbf01ffa758f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 25 Aug 2019 11:44:56 +0900 Subject: [PATCH 427/645] Fix incorrect colour usage --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectPanel.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 243e79eb9b..7bf94c1483 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -151,7 +151,7 @@ namespace osu.Game.Overlays.Direct AutoSizeAxes = Axes.X, Height = 20, Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, - Children = GetDifficultyIcons(), + Children = GetDifficultyIcons(colours), }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 5757e1445b..158ff648dd 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Direct AutoSizeAxes = Axes.X, Height = 20, Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, - Children = GetDifficultyIcons(), + Children = GetDifficultyIcons(colours), }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 7e16daee75..641423f21f 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -139,14 +139,14 @@ namespace osu.Game.Overlays.Direct }; } - protected List GetDifficultyIcons() + protected List GetDifficultyIcons(OsuColour colours) { var icons = new List(); if (SetInfo.Beatmaps.Count > maximum_difficulty_icons) { foreach (var ruleset in SetInfo.Beatmaps.Select(b => b.Ruleset).Distinct()) - icons.Add(new GroupedDifficultyIcon(SetInfo.Beatmaps.FindAll(b => b.Ruleset.Equals(ruleset)), ruleset, this is DirectListPanel ? Color4.White : Color4.Black)); + icons.Add(new GroupedDifficultyIcon(SetInfo.Beatmaps.FindAll(b => b.Ruleset.Equals(ruleset)), ruleset, this is DirectListPanel ? Color4.White : colours.Gray5)); } else foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty)) From 1d34124667666f291957df354b362873c534fce1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 25 Aug 2019 11:56:07 +0900 Subject: [PATCH 428/645] Revert all DifficultyIcon changes --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 91 ++++++++----------- 1 file changed, 36 insertions(+), 55 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 7732aa96f8..81f517dd86 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -20,22 +21,10 @@ namespace osu.Game.Beatmaps.Drawables { public class DifficultyIcon : CompositeDrawable, IHasCustomTooltip { - private BeatmapInfo beatmap; + private readonly BeatmapInfo beatmap; + private readonly RulesetInfo ruleset; private readonly Container iconContainer; - private readonly Box iconBg; - - protected BeatmapInfo Beatmap - { - get => beatmap; - set - { - beatmap = value; - - if (IsLoaded) - updateIconColour(); - } - } /// /// Size of this difficulty icon. @@ -48,46 +37,15 @@ namespace osu.Game.Beatmaps.Drawables public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, bool shouldShowTooltip = true) { - this.beatmap = beatmap; + this.beatmap = beatmap ?? throw new ArgumentNullException(nameof(beatmap)); + this.ruleset = ruleset ?? beatmap.Ruleset; if (shouldShowTooltip) TooltipContent = beatmap; AutoSizeAxes = Axes.Both; - InternalChild = iconContainer = new Container - { - Size = new Vector2(20f), - Children = new Drawable[] - { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.84f), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Masking = true, - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.08f), - Type = EdgeEffectType.Shadow, - Radius = 5, - }, - Child = iconBg = new Box - { - RelativeSizeAxes = Axes.Both, - }, - }, - new ConstrainedIconContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) - Icon = (ruleset ?? beatmap?.Ruleset)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } - } - } - }; + InternalChild = iconContainer = new Container { Size = new Vector2(20f) }; } public string TooltipText { get; set; } @@ -96,18 +54,41 @@ namespace osu.Game.Beatmaps.Drawables public object TooltipContent { get; set; } - private OsuColour colours; - [BackgroundDependencyLoader] private void load(OsuColour colours) { - this.colours = colours; - - updateIconColour(); + iconContainer.Children = new Drawable[] + { + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.84f), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.08f), + Type = EdgeEffectType.Shadow, + Radius = 5, + }, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.ForDifficultyRating(beatmap.DifficultyRating), + }, + }, + new ConstrainedIconContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) + Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } + } + }; } - private void updateIconColour() => iconBg.Colour = colours.ForDifficultyRating(beatmap.DifficultyRating); - private class DifficultyIconTooltip : VisibilityContainer, ITooltip { private readonly OsuSpriteText difficultyName, starRating; From ef397434f68b3e6ccd4fca8dc8ddead3f31928f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 25 Aug 2019 12:00:06 +0900 Subject: [PATCH 429/645] use GroupBy instead of Distinct+FindAll --- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 79e5debdd2..c9419107a2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -118,8 +118,8 @@ namespace osu.Game.Screens.Select.Carousel if (beatmaps.Count > maximum_difficulty_icons) { - foreach (var ruleset in beatmaps.Select(b => b.Beatmap.Ruleset).Distinct()) - icons.Add(new FilterableGroupedDifficultyIcon(beatmaps.FindAll(b => b.Beatmap.Ruleset.Equals(ruleset)), ruleset)); + foreach (var group in beatmaps.GroupBy(b => b.Beatmap.Ruleset)) + icons.Add(new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)); } else beatmaps.ForEach(b => icons.Add(new FilterableDifficultyIcon(b))); From 9881d3677df5896d28bb6e95d5ba7b4e65b0744d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 25 Aug 2019 12:05:46 +0900 Subject: [PATCH 430/645] Simplify icon creation --- .../Carousel/DrawableCarouselBeatmapSet.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index c9419107a2..0a8c61e3d2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Select.Carousel { AutoSizeAxes = Axes.Both, Spacing = new Vector2(3), - Children = getDifficultyIcons(), + ChildrenEnumerable = getDifficultyIcons(), }, } } @@ -111,19 +111,13 @@ namespace osu.Game.Screens.Select.Carousel private const int maximum_difficulty_icons = 18; - private List getDifficultyIcons() + private IEnumerable getDifficultyIcons() { var beatmaps = ((CarouselBeatmapSet)Item).Beatmaps.ToList(); - var icons = new List(); - if (beatmaps.Count > maximum_difficulty_icons) - { - foreach (var group in beatmaps.GroupBy(b => b.Beatmap.Ruleset)) - icons.Add(new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)); - } - else beatmaps.ForEach(b => icons.Add(new FilterableDifficultyIcon(b))); - - return icons; + return beatmaps.Count > maximum_difficulty_icons + ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) + : beatmaps.Select(b => new FilterableDifficultyIcon(b)); } public MenuItem[] ContextMenuItems From de2c6aa23d30e0480755f1d592f18c864f8b4316 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 12:21:11 +0900 Subject: [PATCH 431/645] Rename and expand usability of SkinProvidingContainer --- .../Skinning/BeatmapSkinProvidingContainer.cs | 38 ++++++++++++++++ ...Container.cs => SkinProvidingContainer.cs} | 44 ++++++++----------- 2 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 osu.Game/Skinning/BeatmapSkinProvidingContainer.cs rename osu.Game/Skinning/{LocalSkinOverrideContainer.cs => SkinProvidingContainer.cs} (60%) diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs new file mode 100644 index 0000000000..dc25a33f1e --- /dev/null +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -0,0 +1,38 @@ +// 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.Game.Configuration; + +namespace osu.Game.Skinning +{ + /// + /// A container which overrides existing skin options with beatmap-local values. + /// + public class BeatmapSkinProvidingContainer : SkinProvidingContainer + { + private readonly Bindable beatmapSkins = new Bindable(); + private readonly Bindable beatmapHitsounds = new Bindable(); + + protected override bool AllowConfigurationLookup => beatmapSkins.Value; + protected override bool AllowDrawableLookup(string componentName) => beatmapSkins.Value; + protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value; + protected override bool AllowSampleLookup(string componentName) => beatmapHitsounds.Value; + + public BeatmapSkinProvidingContainer(ISkin skin) + : base(skin) + { + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins); + config.BindWith(OsuSetting.BeatmapHitsounds, beatmapHitsounds); + + beatmapSkins.BindValueChanged(_ => TriggerSourceChanged()); + beatmapHitsounds.BindValueChanged(_ => TriggerSourceChanged()); + } + } +} diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs similarity index 60% rename from osu.Game/Skinning/LocalSkinOverrideContainer.cs rename to osu.Game/Skinning/SkinProvidingContainer.cs index 7882e0f31b..a92a0ae0d1 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -4,29 +4,32 @@ using System; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; -using osu.Game.Configuration; namespace osu.Game.Skinning { /// - /// A container which overrides existing skin options with beatmap-local values. + /// A container which adds a local to the hierarchy. /// - public class LocalSkinOverrideContainer : Container, ISkinSource + public class SkinProvidingContainer : Container, ISkinSource { public event Action SourceChanged; - private readonly Bindable beatmapSkins = new Bindable(); - private readonly Bindable beatmapHitsounds = new Bindable(); - private readonly ISkin skin; private ISkinSource fallbackSource; - public LocalSkinOverrideContainer(ISkin skin) + protected virtual bool AllowDrawableLookup(string componentName) => true; + + protected virtual bool AllowTextureLookup(string componentName) => true; + + protected virtual bool AllowSampleLookup(string componentName) => true; + + protected virtual bool AllowConfigurationLookup => true; + + public SkinProvidingContainer(ISkin skin) { this.skin = skin; } @@ -34,7 +37,7 @@ namespace osu.Game.Skinning public Drawable GetDrawableComponent(string componentName) { Drawable sourceDrawable; - if (beatmapSkins.Value && (sourceDrawable = skin?.GetDrawableComponent(componentName)) != null) + if (AllowDrawableLookup(componentName) && (sourceDrawable = skin?.GetDrawableComponent(componentName)) != null) return sourceDrawable; return fallbackSource?.GetDrawableComponent(componentName); @@ -43,7 +46,7 @@ namespace osu.Game.Skinning public Texture GetTexture(string componentName) { Texture sourceTexture; - if (beatmapSkins.Value && (sourceTexture = skin?.GetTexture(componentName)) != null) + if (AllowTextureLookup(componentName) && (sourceTexture = skin?.GetTexture(componentName)) != null) return sourceTexture; return fallbackSource.GetTexture(componentName); @@ -52,7 +55,7 @@ namespace osu.Game.Skinning public SampleChannel GetSample(string sampleName) { SampleChannel sourceChannel; - if (beatmapHitsounds.Value && (sourceChannel = skin?.GetSample(sampleName)) != null) + if (AllowSampleLookup(sampleName) && (sourceChannel = skin?.GetSample(sampleName)) != null) return sourceChannel; return fallbackSource?.GetSample(sampleName); @@ -61,14 +64,13 @@ namespace osu.Game.Skinning public TValue GetValue(Func query) where TConfiguration : SkinConfiguration { TValue val; - if ((skin as Skin)?.Configuration is TConfiguration conf) - if (beatmapSkins.Value && (val = query.Invoke(conf)) != null) - return val; + if (AllowConfigurationLookup && skin != null && (val = skin.GetValue(query)) != null) + return val; return fallbackSource == null ? default : fallbackSource.GetValue(query); } - private void onSourceChanged() => SourceChanged?.Invoke(); + protected virtual void TriggerSourceChanged() => SourceChanged?.Invoke(); protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { @@ -76,18 +78,10 @@ namespace osu.Game.Skinning fallbackSource = dependencies.Get(); if (fallbackSource != null) - fallbackSource.SourceChanged += onSourceChanged; + fallbackSource.SourceChanged += TriggerSourceChanged; dependencies.CacheAs(this); - var config = dependencies.Get(); - - config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins); - config.BindWith(OsuSetting.BeatmapHitsounds, beatmapHitsounds); - - beatmapSkins.BindValueChanged(_ => onSourceChanged()); - beatmapHitsounds.BindValueChanged(_ => onSourceChanged()); - return dependencies; } @@ -99,7 +93,7 @@ namespace osu.Game.Skinning base.Dispose(isDisposing); if (fallbackSource != null) - fallbackSource.SourceChanged -= onSourceChanged; + fallbackSource.SourceChanged -= TriggerSourceChanged; } } } From 5e362d10b1c26443bb6c95c3f61c0b5984e81b7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 12:21:49 +0900 Subject: [PATCH 432/645] Add ruleset-specific legacy skin providers This moves implementation of osu! skinnables to OsuLegacySkin. --- osu.Game.Rulesets.Osu/OsuLegacySkin.cs | 228 +++++++++++++++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 + osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 3 + osu.Game/Screens/Play/Player.cs | 41 ++-- osu.Game/Skinning/LegacySkin.cs | 137 -------------- 6 files changed, 261 insertions(+), 153 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/OsuLegacySkin.cs diff --git a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs new file mode 100644 index 0000000000..0085d64353 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs @@ -0,0 +1,228 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Animations; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Skinning; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu +{ + public class OsuLegacySkin : ISkin + { + private readonly ISkin source; + + private Lazy configuration; + + private Lazy hasHitCircle; + + /// + /// On osu-stable, hitcircles have 5 pixels of transparent padding on each side to allow for shadows etc. + /// Their hittable area is 128px, but the actual circle portion is 118px. + /// We must account for some gameplay elements such as slider bodies, where this padding is not present. + /// + private const float legacy_circle_radius = 64 - 5; + + public OsuLegacySkin(ISkinSource source) + { + this.source = source; + + source.SourceChanged += sourceChanged; + sourceChanged(); + } + + private void sourceChanged() + { + configuration = new Lazy(() => + { + var config = new SkinConfiguration(); + if (hasHitCircle.Value) + config.SliderPathRadius = legacy_circle_radius; + return config; + }); + + hasHitCircle = new Lazy(() => source.GetTexture("hitcircle") != null); + } + + private const double default_frame_time = 1000 / 60d; + + public Drawable GetDrawableComponent(string componentName) + { + switch (componentName) + { + case "Play/osu/sliderball": + var sliderBallContent = getAnimation("sliderb", true, true, ""); + + if (sliderBallContent != null) + { + var size = sliderBallContent.Size; + + sliderBallContent.RelativeSizeAxes = Axes.Both; + sliderBallContent.Size = Vector2.One; + + return new LegacySliderBall(sliderBallContent) + { + Size = size + }; + } + + return null; + + case "Play/osu/hitcircle": + if (hasHitCircle.Value) + return new LegacyMainCirclePiece(); + + return null; + } + + return null; + } + + private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-") + { + Texture texture; + + Texture getFrameTexture(int frame) => source.GetTexture($"{componentName}{animationSeparator}{frame}"); + + TextureAnimation animation = null; + + if (animatable) + { + for (int i = 0;; i++) + { + if ((texture = getFrameTexture(i)) == null) + break; + + if (animation == null) + animation = new TextureAnimation + { + DefaultFrameLength = default_frame_time, + Repeat = looping + }; + + animation.AddFrame(texture); + } + } + + if (animation != null) + return animation; + + if ((texture = source.GetTexture(componentName)) != null) + return new Sprite { Texture = texture }; + + return null; + } + + public Texture GetTexture(string componentName) => null; + + public SampleChannel GetSample(string sampleName) => null; + + public TValue GetValue(Func query) where TConfiguration : SkinConfiguration + => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; + + public class LegacySliderBall : CompositeDrawable + { + private readonly Drawable animationContent; + + public LegacySliderBall(Drawable animationContent) + { + this.animationContent = animationContent; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, DrawableHitObject drawableObject) + { + animationContent.Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; + + InternalChildren = new[] + { + new Sprite + { + Texture = skin.GetTexture("sliderb-nd"), + Colour = new Color4(5, 5, 5, 255), + }, + animationContent, + new Sprite + { + Texture = skin.GetTexture("sliderb-spec"), + Blending = BlendingParameters.Additive, + }, + }; + } + } + + public class LegacyMainCirclePiece : CompositeDrawable + { + public LegacyMainCirclePiece() + { + Size = new Vector2(128); + } + + private readonly IBindable state = new Bindable(); + + private readonly Bindable accentColour = new Bindable(); + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableObject, ISkinSource skin) + { + Sprite hitCircleSprite; + + InternalChildren = new Drawable[] + { + hitCircleSprite = new Sprite + { + Texture = skin.GetTexture("hitcircle"), + Colour = drawableObject.AccentColour.Value, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: 40), + UseFullGlyphHeight = false, + }, confineMode: ConfineMode.NoScaling) + { + Text = (((IHasComboInformation)drawableObject.HitObject).IndexInCurrentCombo + 1).ToString() + }, + new Sprite + { + Texture = skin.GetTexture("hitcircleoverlay"), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + + state.BindTo(drawableObject.State); + state.BindValueChanged(updateState, true); + + accentColour.BindTo(drawableObject.AccentColour); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); + } + + private void updateState(ValueChangedEvent state) + { + const double legacy_fade_duration = 240; + + switch (state.NewValue) + { + case ArmedState.Hit: + this.FadeOut(legacy_fade_duration, Easing.Out); + this.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + break; + } + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index d50d4f401c..4211ae253c 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -24,6 +24,7 @@ using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Difficulty; using osu.Game.Scoring; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { @@ -163,6 +164,8 @@ namespace osu.Game.Rulesets.Osu public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this); + public override ISkin CreateLegacySkinProvider(ISkinSource source) => new OsuLegacySkin(source); + public override int? LegacyID => 0; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new OsuReplayFrame(); diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 9037faf606..178183bd22 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.UI }, // Todo: This should not exist, but currently helps to reduce LOH allocations due to unbinding skin source events on judgement disposal // Todo: Remove when hitobjects are properly pooled - new LocalSkinOverrideContainer(null) + new SkinProvidingContainer(null) { RelativeSizeAxes = Axes.Both, Child = HitObjectContainer, diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 42b1322cae..2fbbd74d7a 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -18,6 +18,7 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; using osu.Game.Scoring; +using osu.Game.Skinning; namespace osu.Game.Rulesets { @@ -44,6 +45,8 @@ namespace osu.Game.Rulesets public ModAutoplay GetAutoplayMod() => GetAllMods().OfType().First(); + public virtual ISkin CreateLegacySkinProvider(ISkinSource source) => null; + protected Ruleset(RulesetInfo rulesetInfo = null) { RulesetInfo = rulesetInfo ?? createRulesetInfo(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e7398be176..deed17a049 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -60,7 +60,9 @@ namespace osu.Game.Screens.Play [Resolved] private ScoreManager scoreManager { get; set; } - private RulesetInfo ruleset; + private RulesetInfo rulesetInfo; + + private Ruleset ruleset; private IAPIProvider api; @@ -121,20 +123,29 @@ namespace osu.Game.Screens.Play InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime); + SkinProvidingContainer skinProvidingContainer = new BeatmapSkinProvidingContainer(working.Skin) + { + RelativeSizeAxes = Axes.Both, + }; + GameplayClockContainer.Children = new[] { DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both }, new ScalingContainer(ScalingMode.Gameplay) { - Child = new LocalSkinOverrideContainer(working.Skin) - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + Child = skinProvidingContainer.WithChild( + // the skinProvidingContainer is used as the fallback source here to allow the ruleset-specific skin implementation + // full access to all skin sources. + new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(skinProvidingContainer)) { - DrawableRuleset, - new ComboEffects(ScoreProcessor) + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + DrawableRuleset, + new ComboEffects(ScoreProcessor) + } } - } + ) }, breakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) { @@ -222,20 +233,20 @@ namespace osu.Game.Screens.Play if (beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); - ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; - var rulesetInstance = ruleset.CreateInstance(); + rulesetInfo = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; + ruleset = rulesetInfo.CreateInstance(); try { - DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(working, Mods.Value); + DrawableRuleset = ruleset.CreateDrawableRulesetWith(working, Mods.Value); } catch (BeatmapInvalidForRulesetException) { // we may fail to create a DrawableRuleset if the beatmap cannot be loaded with the user's preferred ruleset // let's try again forcing the beatmap's ruleset. - ruleset = beatmap.BeatmapInfo.Ruleset; - rulesetInstance = ruleset.CreateInstance(); - DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(Beatmap.Value, Mods.Value); + rulesetInfo = beatmap.BeatmapInfo.Ruleset; + ruleset = rulesetInfo.CreateInstance(); + DrawableRuleset = ruleset.CreateDrawableRulesetWith(Beatmap.Value, Mods.Value); } if (!DrawableRuleset.Objects.Any()) @@ -313,7 +324,7 @@ namespace osu.Game.Screens.Play var score = DrawableRuleset.ReplayScore?.ScoreInfo ?? new ScoreInfo { Beatmap = Beatmap.Value.BeatmapInfo, - Ruleset = ruleset, + Ruleset = rulesetInfo, Mods = Mods.Value.ToArray(), User = api.LocalUser.Value, }; diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 48310cf027..785daba878 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; @@ -20,8 +19,6 @@ using osu.Framework.Text; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.UI; using osuTK; using osuTK.Graphics; @@ -34,13 +31,6 @@ namespace osu.Game.Skinning protected IResourceStore Samples; - /// - /// On osu-stable, hitcircles have 5 pixels of transparent padding on each side to allow for shadows etc. - /// Their hittable area is 128px, but the actual circle portion is 118px. - /// We must account for some gameplay elements such as slider bodies, where this padding is not present. - /// - private const float legacy_circle_radius = 64 - 5; - public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : this(skin, new LegacySkinResourceStore(skin, storage), audioManager, "skin.ini") { @@ -48,8 +38,6 @@ namespace osu.Game.Skinning if (!Configuration.CustomColours.ContainsKey("SliderBall")) Configuration.CustomColours["SliderBall"] = new Color4(2, 170, 255, 255); } - private readonly bool hasHitCircle; - protected LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager, string filename) : base(skin) { @@ -62,14 +50,6 @@ namespace osu.Game.Skinning Samples = audioManager.GetSampleStore(storage); Textures = new TextureStore(new TextureLoaderStore(storage)); - - using (var testStream = storage.GetStream("hitcircle@2x") ?? storage.GetStream("hitcircle")) - hasHitCircle |= testStream != null; - - if (hasHitCircle) - { - Configuration.SliderPathRadius = legacy_circle_radius; - } } protected override void Dispose(bool isDisposing) @@ -94,30 +74,6 @@ namespace osu.Game.Skinning return null; - case "Play/osu/sliderball": - var sliderBallContent = getAnimation("sliderb", true, true, ""); - - if (sliderBallContent != null) - { - var size = sliderBallContent.Size; - - sliderBallContent.RelativeSizeAxes = Axes.Both; - sliderBallContent.Size = Vector2.One; - - return new LegacySliderBall(sliderBallContent) - { - Size = size - }; - } - - return null; - - case "Play/osu/hitcircle": - if (hasHitCircle) - return new LegacyMainCirclePiece(); - - return null; - case "Play/osu/sliderfollowcircle": animatable = true; break; @@ -355,99 +311,6 @@ namespace osu.Game.Skinning } } - public class LegacySliderBall : CompositeDrawable - { - private readonly Drawable animationContent; - - public LegacySliderBall(Drawable animationContent) - { - this.animationContent = animationContent; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, DrawableHitObject drawableObject) - { - animationContent.Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; - - InternalChildren = new[] - { - new Sprite - { - Texture = skin.GetTexture("sliderb-nd"), - Colour = new Color4(5, 5, 5, 255), - }, - animationContent, - new Sprite - { - Texture = skin.GetTexture("sliderb-spec"), - Blending = BlendingParameters.Additive, - }, - }; - } - } - - public class LegacyMainCirclePiece : CompositeDrawable - { - public LegacyMainCirclePiece() - { - Size = new Vector2(128); - } - - private readonly IBindable state = new Bindable(); - - private readonly Bindable accentColour = new Bindable(); - - [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableObject, ISkinSource skin) - { - Sprite hitCircleSprite; - - InternalChildren = new Drawable[] - { - hitCircleSprite = new Sprite - { - Texture = skin.GetTexture("hitcircle"), - Colour = drawableObject.AccentColour.Value, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText - { - Font = OsuFont.Numeric.With(size: 40), - UseFullGlyphHeight = false, - }, confineMode: ConfineMode.NoScaling) - { - Text = (((IHasComboInformation)drawableObject.HitObject).IndexInCurrentCombo + 1).ToString() - }, - new Sprite - { - Texture = skin.GetTexture("hitcircleoverlay"), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - }; - - state.BindTo(drawableObject.State); - state.BindValueChanged(updateState, true); - - accentColour.BindTo(drawableObject.AccentColour); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); - } - - private void updateState(ValueChangedEvent state) - { - const double legacy_fade_duration = 240; - - switch (state.NewValue) - { - case ArmedState.Hit: - this.FadeOut(legacy_fade_duration, Easing.Out); - this.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - break; - } - } - } - /// /// A sprite which is displayed within the playfield, but historically was not considered part of the playfield. /// Performs scale adjustment to undo the scale applied by (osu! ruleset specifically). From 6e3a63dae8a9dbc59d47993d884b97b2414de7df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 12:31:51 +0900 Subject: [PATCH 433/645] Update tests --- .../SkinnableTestScene.cs | 20 +++++++++++++++---- .../Gameplay/TestSceneSkinnableDrawable.cs | 8 ++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs index 02716dc1d5..c3a64f8b54 100644 --- a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs +++ b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs @@ -37,10 +37,22 @@ namespace osu.Game.Rulesets.Osu.Tests public void SetContents(Func creationFunction) { - Cell(0).Child = new LocalSkinOverrideContainer(null) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction()); - Cell(1).Child = new LocalSkinOverrideContainer(metricsSkin) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction()); - Cell(2).Child = new LocalSkinOverrideContainer(defaultSkin) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction()); - Cell(3).Child = new LocalSkinOverrideContainer(specialSkin) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction()); + Cell(0).Child = createProvider(null, creationFunction); + Cell(1).Child = createProvider(metricsSkin, creationFunction); + Cell(2).Child = createProvider(defaultSkin, creationFunction); + Cell(3).Child = createProvider(specialSkin, creationFunction); + } + + private Drawable createProvider(Skin skin, Func creationFunction) + { + var mainProvider = new SkinProvidingContainer(skin) { RelativeSizeAxes = Axes.Both }; + + return mainProvider + .WithChild(new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider)) + { + RelativeSizeAxes = Axes.Both, + Child = creationFunction() + }); } private class TestLegacySkin : LegacySkin diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index 0b5978e3eb..b18eca0600 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("setup layout larger source", () => { - Child = new LocalSkinOverrideContainer(new SizedSource(50)) + Child = new SkinProvidingContainer(new SizedSource(50)) { RelativeSizeAxes = Axes.Both, Child = fill = new FillFlowContainer @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("setup layout larger source", () => { - Child = new LocalSkinOverrideContainer(new SizedSource(30)) + Child = new SkinProvidingContainer(new SizedSource(30)) { RelativeSizeAxes = Axes.Both, Child = fill = new FillFlowContainer @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = new LocalSkinOverrideContainer(secondarySource) + Child = new SkinProvidingContainer(secondarySource) { RelativeSizeAxes = Axes.Both, Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true) @@ -120,7 +120,7 @@ namespace osu.Game.Tests.Visual.Gameplay Child = new SkinSourceContainer { RelativeSizeAxes = Axes.Both, - Child = target = new LocalSkinOverrideContainer(secondarySource) + Child = target = new SkinProvidingContainer(secondarySource) { RelativeSizeAxes = Axes.Both, } From d99c60adc7cf97d11de29631ec46c1c652a1b62e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 12:51:13 +0900 Subject: [PATCH 434/645] Provide a way to scale beat lengths relative to each other --- .../Rulesets/Timing/MultiplierControlPoint.cs | 8 +++- .../UI/Scrolling/DrawableScrollingRuleset.cs | 38 +++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs index 9bab065d1e..ffa35c24cd 100644 --- a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs +++ b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs @@ -20,7 +20,13 @@ namespace osu.Game.Rulesets.Timing /// /// The aggregate multiplier which this provides. /// - public double Multiplier => Velocity * DifficultyPoint.SpeedMultiplier * 1000 / TimingPoint.BeatLength; + public double Multiplier => Velocity * DifficultyPoint.SpeedMultiplier * BaseBeatLength / TimingPoint.BeatLength; + + /// + /// The base beat length to scale the provided multiplier relative to. + /// + /// For a of 1000, a with a beat length of 500 will increase the multiplier by 2. + public double BaseBeatLength = 1000; /// /// The velocity multiplier. diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 42ec0b79b9..385f824ef5 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -69,6 +69,11 @@ namespace osu.Game.Rulesets.UI.Scrolling /// protected virtual bool UserScrollSpeedAdjustment => true; + /// + /// Whether beat lengths should scale relative to the most common beat length in the . + /// + protected virtual bool RelativeScaleBeatLengths => false; + /// /// Provides the default s that adjust the scrolling rate of s /// inside this . @@ -107,16 +112,35 @@ namespace osu.Game.Rulesets.UI.Scrolling [BackgroundDependencyLoader] private void load() { - // Calculate default multiplier control points + double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue; + double baseBeatLength = 1000; + + if (RelativeScaleBeatLengths) + { + IReadOnlyList timingPoints = Beatmap.ControlPointInfo.TimingPoints; + double maxDuration = 0; + + for (int i = 0; i < timingPoints.Count; i++) + { + double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time : lastObjectTime; + double duration = endTime - timingPoints[i].Time; + + if (duration > maxDuration) + { + maxDuration = duration; + baseBeatLength = timingPoints[i].BeatLength; + } + } + } + + // Merge sequences of timing and difficulty control points to create the aggregate "multiplier" control point var lastTimingPoint = new TimingControlPoint(); var lastDifficultyPoint = new DifficultyControlPoint(); - - // Merge timing + difficulty points var allPoints = new SortedList(Comparer.Default); allPoints.AddRange(Beatmap.ControlPointInfo.TimingPoints); allPoints.AddRange(Beatmap.ControlPointInfo.DifficultyPoints); - // Generate the timing points, making non-timing changes use the previous timing change + // Generate the timing points, making non-timing changes use the previous timing change and vice-versa var timingChanges = allPoints.Select(c => { var timingPoint = c as TimingControlPoint; @@ -131,14 +155,13 @@ namespace osu.Game.Rulesets.UI.Scrolling return new MultiplierControlPoint(c.Time) { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier, + BaseBeatLength = baseBeatLength, TimingPoint = lastTimingPoint, DifficultyPoint = lastDifficultyPoint }; }); - double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue; - - // Perform some post processing of the timing changes + // Trim unwanted sequences of timing changes timingChanges = timingChanges // Collapse sections after the last hit object .Where(s => s.StartTime <= lastObjectTime) @@ -147,7 +170,6 @@ namespace osu.Game.Rulesets.UI.Scrolling controlPoints.AddRange(timingChanges); - // If we have no control points, add a default one if (controlPoints.Count == 0) controlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier }); } From e30ae57ea66325491eb1f94c7314d6270da5d3c8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 12:51:23 +0900 Subject: [PATCH 435/645] Scale mania beat lengths relative to each other --- osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index c8aeda8fe4..0718de2c7d 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -36,6 +36,8 @@ namespace osu.Game.Rulesets.Mania.UI public IEnumerable BarLines; + protected override bool RelativeScaleBeatLengths => true; + protected new ManiaRulesetConfigManager Config => (ManiaRulesetConfigManager)base.Config; private readonly Bindable configDirection = new Bindable(); From 7b82121b8503f81de85013e9c82435d4b584d34c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 13:03:00 +0900 Subject: [PATCH 436/645] Add comment about lazy usage --- osu.Game.Rulesets.Osu/OsuLegacySkin.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs index 0085d64353..988eb6a439 100644 --- a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs @@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Osu private void sourceChanged() { + // these need to be lazy in order to ensure they aren't called before the dependencies have been loaded into our source. configuration = new Lazy(() => { var config = new SkinConfiguration(); From 289bd8e6b0c9367ae4cb9bbb15a4f3be7c424213 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 14:25:35 +0900 Subject: [PATCH 437/645] Don't return DefaultSkin on beatmap skin parsing failure --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 5657b8fb8a..2d8a0b1249 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -138,19 +138,15 @@ namespace osu.Game.Beatmaps protected override Skin GetSkin() { - Skin skin; - try { - skin = new LegacyBeatmapSkin(BeatmapInfo, store, AudioManager); + return new LegacyBeatmapSkin(BeatmapInfo, store, AudioManager); } catch (Exception e) { Logger.Error(e, "Skin failed to load"); - skin = new DefaultSkin(); + return null; } - - return skin; } } } From db987c6077153102848ffe9f16c79de8480c39e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 14:24:48 +0900 Subject: [PATCH 438/645] Move SliderBall colour logic to OsuLegacySkinProvider --- osu.Game.Rulesets.Osu/OsuLegacySkin.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs index 988eb6a439..1957156918 100644 --- a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs @@ -51,6 +51,12 @@ namespace osu.Game.Rulesets.Osu var config = new SkinConfiguration(); if (hasHitCircle.Value) config.SliderPathRadius = legacy_circle_radius; + + // defaults should only be applied for non-beatmap skins (which are parsed via this constructor). + config.CustomColours["SliderBall"] = + source.GetValue(s => s.CustomColours.TryGetValue("SliderBall", out var val) ? val : (Color4?)null) + ?? new Color4(2, 170, 255, 255); + return config; }); From 1cfe2b7de8388ade173269519e7947400ef18778 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 16:25:23 +0900 Subject: [PATCH 439/645] Fix timing points beyond the end time potentially becoming dominant --- osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 385f824ef5..65a22b10b7 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -122,6 +122,9 @@ namespace osu.Game.Rulesets.UI.Scrolling for (int i = 0; i < timingPoints.Count; i++) { + if (timingPoints[i].Time > lastObjectTime) + break; + double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time : lastObjectTime; double duration = endTime - timingPoints[i].Time; From fb8b5ee1060dfd0ec8467ed15ddcc4c84806603f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 16:31:46 +0900 Subject: [PATCH 440/645] Add test --- .../TestSceneDrawableScrollingRuleset.cs | 305 ++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs new file mode 100644 index 0000000000..ee11fc0d06 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -0,0 +1,305 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Framework.MathUtils; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.UI.Scrolling; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public class TestSceneDrawableScrollingRuleset : OsuTestScene + { + /// + /// The amount of time visible by the "view window" of the playfield. + /// All hitobjects added through are spaced apart by this value, such that for a beat length of 1000, + /// there will be at most 2 hitobjects visible in the "view window". + /// + private const double time_range = 1000; + + private readonly ManualClock testClock = new ManualClock(); + private TestDrawableScrollingRuleset drawableRuleset; + + [SetUp] + public void Setup() => Schedule(() => testClock.CurrentTime = 0); + + [Test] + public void TestRelativeBeatLengthScaleSingleTimingPoint() + { + var beatmap = createBeatmap(new TimingControlPoint { BeatLength = time_range / 2 }); + + createTest(beatmap, d => d.RelativeScaleBeatLengthsOverride = true); + + assertPosition(0, 0f); + + // The single timing point is 1x speed relative to itself, such that the hitobject occurring time_range milliseconds later should appear + // at the bottom of the view window regardless of the timing point's beat length + assertPosition(1, 1f); + } + + [Test] + public void TestRelativeBeatLengthScaleTimingPointBeyondEndDoesNotBecomeDominant() + { + var beatmap = createBeatmap( + new TimingControlPoint { BeatLength = time_range / 2 }, + new TimingControlPoint { Time = 12000, BeatLength = time_range }, + new TimingControlPoint { Time = 100000, BeatLength = time_range }); + + createTest(beatmap, d => d.RelativeScaleBeatLengthsOverride = true); + + assertPosition(0, 0f); + assertPosition(1, 1f); + } + + [Test] + public void TestRelativeBeatLengthScaleFromSecondTimingPoint() + { + var beatmap = createBeatmap( + new TimingControlPoint { BeatLength = time_range }, + new TimingControlPoint { Time = 3 * time_range, BeatLength = time_range / 2 }); + + createTest(beatmap, d => d.RelativeScaleBeatLengthsOverride = true); + + // The first timing point should have a relative velocity of 2 + assertPosition(0, 0f); + assertPosition(1, 0.5f); + assertPosition(2, 1f); + + // Move to the second timing point + setTime(3 * time_range); + assertPosition(3, 0f); + + // As above, this is the timing point that is 1x speed relative to itself, so the hitobject occurring time_range milliseconds later should be at the bottom of the view window + assertPosition(4, 1f); + } + + [Test] + public void TestNonRelativeScale() + { + var beatmap = createBeatmap( + new TimingControlPoint { BeatLength = time_range }, + new TimingControlPoint { Time = 3 * time_range, BeatLength = time_range / 2 }); + + createTest(beatmap); + + assertPosition(0, 0f); + assertPosition(1, 1); + + // Move to the second timing point + setTime(3 * time_range); + assertPosition(3, 0f); + + // For a beat length of 500, the view window of this timing point is elongated 2x (1000 / 500), such that the second hitobject is two TimeRanges away (offscreen) + // To bring it on-screen, half TimeRange is added to the current time, bringing the second half of the view window into view, and the hitobject should appear at the bottom + setTime(3 * time_range + time_range / 2); + assertPosition(4, 1f); + } + + private void assertPosition(int index, float relativeY) => AddAssert($"hitobject {index} at {relativeY}", + () => Precision.AlmostEquals(drawableRuleset.Playfield.AllHitObjects.ElementAt(index).DrawPosition.Y, drawableRuleset.Playfield.HitObjectContainer.DrawHeight * relativeY)); + + private void setTime(double time) + { + AddStep($"set time = {time}", () => testClock.CurrentTime = time); + } + + /// + /// Creates an , containing 10 hitobjects and user-provided timing points. + /// The hitobjects are spaced milliseconds apart. + /// + /// The timing points to add to the beatmap. + /// The . + private IBeatmap createBeatmap(params TimingControlPoint[] timingControlPoints) + { + var beatmap = new Beatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo } }; + + beatmap.ControlPointInfo.TimingPoints.AddRange(timingControlPoints); + + for (int i = 0; i < 10; i++) + beatmap.HitObjects.Add(new HitObject { StartTime = i * time_range }); + + return beatmap; + } + + private void createTest(IBeatmap beatmap, Action overrideAction = null) => AddStep("create test", () => + { + var ruleset = new TestScrollingRuleset(); + + drawableRuleset = (TestDrawableScrollingRuleset)ruleset.CreateDrawableRulesetWith(CreateWorkingBeatmap(beatmap), Array.Empty()); + drawableRuleset.FrameStablePlayback = false; + + overrideAction?.Invoke(drawableRuleset); + + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Height = 0.75f, + Width = 400, + Masking = true, + Clock = new FramedClock(testClock), + Child = drawableRuleset + }; + }); + + #region Ruleset + + private class TestScrollingRuleset : Ruleset + { + public TestScrollingRuleset(RulesetInfo rulesetInfo = null) + : base(rulesetInfo) + { + } + + public override IEnumerable GetModsFor(ModType type) => throw new NotImplementedException(); + + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new TestDrawableScrollingRuleset(this, beatmap, mods); + + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap); + + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new NotImplementedException(); + + public override string Description { get; } = string.Empty; + + public override string ShortName { get; } = string.Empty; + } + + private class TestDrawableScrollingRuleset : DrawableScrollingRuleset + { + public bool RelativeScaleBeatLengthsOverride { get; set; } + + protected override bool RelativeScaleBeatLengths => RelativeScaleBeatLengthsOverride; + + protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping; + + public TestDrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + : base(ruleset, beatmap, mods) + { + TimeRange.Value = time_range; + } + + public override DrawableHitObject CreateDrawableRepresentation(TestHitObject h) => new DrawableTestHitObject(h); + + protected override PassThroughInputManager CreateInputManager() => new PassThroughInputManager(); + + protected override Playfield CreatePlayfield() => new TestPlayfield(); + } + + private class TestPlayfield : ScrollingPlayfield + { + public TestPlayfield() + { + AddInternal(new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.2f, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 150 }, + Children = new Drawable[] + { + new Box + { + Anchor = Anchor.TopCentre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = Color4.Green + }, + HitObjectContainer + } + } + } + }); + } + } + + private class TestBeatmapConverter : BeatmapConverter + { + public TestBeatmapConverter(IBeatmap beatmap) + : base(beatmap) + { + } + + protected override IEnumerable ValidConversionTypes => new[] { typeof(HitObject) }; + + protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap) + { + yield return new TestHitObject + { + StartTime = original.StartTime, + EndTime = (original as IHasEndTime)?.EndTime ?? (original.StartTime + 100) + }; + } + } + + #endregion + + #region HitObject + + private class TestHitObject : HitObject, IHasEndTime + { + public double EndTime { get; set; } + + public double Duration => EndTime - StartTime; + } + + private class DrawableTestHitObject : DrawableHitObject + { + public DrawableTestHitObject(TestHitObject hitObject) + : base(hitObject) + { + Anchor = Anchor.TopCentre; + Origin = Anchor.TopCentre; + + Size = new Vector2(100, 25); + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.LightPink + }, + new Box + { + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = Color4.Red + } + }); + } + } + + #endregion + } +} From 6596d7fc463d3a73cbf5605d1074135db9c230f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 16:33:24 +0900 Subject: [PATCH 441/645] Add nullref safety to FrameStablePlayback boolean --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index eb14bd1f24..ccfd89adca 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -62,13 +62,20 @@ namespace osu.Game.Rulesets.UI public override GameplayClock FrameStableClock => frameStabilityContainer.GameplayClock; + private bool frameStablePlayback = true; + /// /// Whether to enable frame-stable playback. /// internal bool FrameStablePlayback { - get => frameStabilityContainer.FrameStablePlayback; - set => frameStabilityContainer.FrameStablePlayback = value; + get => frameStablePlayback; + set + { + frameStablePlayback = false; + if (frameStabilityContainer != null) + frameStabilityContainer.FrameStablePlayback = value; + } } /// @@ -156,6 +163,7 @@ namespace osu.Game.Rulesets.UI { frameStabilityContainer = new FrameStabilityContainer(GameplayStartTime) { + FrameStablePlayback = FrameStablePlayback, Child = KeyBindingInputManager .WithChild(CreatePlayfieldAdjustmentContainer() .WithChild(Playfield) From 6dfe95db74b6d12d1ed5b9567a0652eb6303d589 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 16:34:12 +0900 Subject: [PATCH 442/645] Allow RulesetConfigCache to return null configs --- osu.Game/Rulesets/RulesetConfigCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/RulesetConfigCache.cs b/osu.Game/Rulesets/RulesetConfigCache.cs index 9a5a4d4acd..8c9e3c94e2 100644 --- a/osu.Game/Rulesets/RulesetConfigCache.cs +++ b/osu.Game/Rulesets/RulesetConfigCache.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets public IRulesetConfigManager GetConfigFor(Ruleset ruleset) { if (ruleset.RulesetInfo.ID == null) - throw new InvalidOperationException("The provided ruleset doesn't have a valid id."); + return null; return configCache.GetOrAdd(ruleset.RulesetInfo.ID.Value, _ => ruleset.CreateConfig(settingsStore)); } From fb1cd9e5e7a9050a8b2af1882ecf342f4928baf8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 16:47:23 +0900 Subject: [PATCH 443/645] Add a sane default lifetime end for scrolling hitobjects --- .../UI/Scrolling/ScrollingHitObjectContainer.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 19247d8a37..14a4869a98 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -12,8 +12,13 @@ namespace osu.Game.Rulesets.UI.Scrolling { public class ScrollingHitObjectContainer : HitObjectContainer { - private readonly IBindable timeRange = new BindableDouble(); + /// + /// A multiplier applied to the length of the scrolling area to determine a safe default lifetime end for hitobjects. + /// This is only used to limit the lifetime end within reason, as proper lifetime management should be implemented on hitobjects themselves. + /// + private const float safe_lifetime_end_multiplier = 2; + private readonly IBindable timeRange = new BindableDouble(); private readonly IBindable direction = new Bindable(); [Resolved] @@ -92,6 +97,8 @@ namespace osu.Game.Rulesets.UI.Scrolling if (hitObject.HitObject is IHasEndTime endTime) { + hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime.EndTime, timeRange.Value, scrollLength); + switch (direction.Value) { case ScrollingDirection.Up: @@ -105,6 +112,8 @@ namespace osu.Game.Rulesets.UI.Scrolling break; } } + else + hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, hitObject.HitObject.StartTime, timeRange.Value, scrollLength); foreach (var obj in hitObject.NestedHitObjects) { From d4a296f9116fc9ce35695e9f2c89bfebd3cd8041 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Aug 2019 17:45:12 +0900 Subject: [PATCH 444/645] Slight refactoring --- .../Replays/ManiaAutoGenerator.cs | 8 ++++---- .../Replays/TaikoAutoGenerator.cs | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index fd0a876775..7b8bbc2095 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -98,12 +98,12 @@ namespace osu.Game.Rulesets.Mania.Replays protected override HitObject GetNextObject(int currentIndex) { - int desiredColumn = Beatmap.HitObjects[currentIndex++].Column; + int desiredColumn = Beatmap.HitObjects[currentIndex].Column; - for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) + for (int i = currentIndex + 1; i < Beatmap.HitObjects.Count; i++) { - if (Beatmap.HitObjects[currentIndex].Column == desiredColumn) - return Beatmap.HitObjects[currentIndex]; + if (Beatmap.HitObjects[i].Column == desiredColumn) + return Beatmap.HitObjects[i]; } return null; diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 6720d8b8bf..299679b2c1 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -137,14 +137,18 @@ namespace osu.Game.Rulesets.Taiko.Replays protected override HitObject GetNextObject(int currentIndex) { - Type desiredType = Beatmap.HitObjects[currentIndex++].GetType(); + Type desiredType = Beatmap.HitObjects[currentIndex].GetType(); - for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) + for (int i = currentIndex + 1; i < Beatmap.HitObjects.Count; i++) { - var currentObj = Beatmap.HitObjects[currentIndex]; + var currentObj = Beatmap.HitObjects[i]; + if (currentObj.GetType() == desiredType || - currentObj is DrumRoll || currentObj is Swell) // Unpress all keys before DrumRoll or Swell - return Beatmap.HitObjects[currentIndex]; + // Un-press all keys before a DrumRoll or Swell + currentObj is DrumRoll || currentObj is Swell) + { + return Beatmap.HitObjects[i]; + } } return null; From 62641c149d96d33ec56542764b3d2a8ddd7258cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 18:18:14 +0900 Subject: [PATCH 445/645] Fx component lookups being incorrect for non-databased legacy skins --- .../metrics-skin/approachcircle@2x.png | Bin 0 -> 13816 bytes osu.Game/Skinning/LegacySkin.cs | 10 ++++++---- 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/approachcircle@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/approachcircle@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/approachcircle@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..72ef665478b758c364197aa79f238230e229b3c4 GIT binary patch literal 13816 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 X;|*6ltxe$d|7PiG>1$T1+eQB$HM;D+ literal 0 HcmV?d00001 diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 48310cf027..7bffe5d321 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -155,6 +155,11 @@ namespace osu.Game.Skinning // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size Spacing = new Vector2(-Configuration.HitCircleOverlap * 0.89f, 0) }; + + default: + string lastPiece = componentName.Split('/').Last(); + componentName = componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; + break; } return getAnimation(componentName, animatable, looping); @@ -226,11 +231,8 @@ namespace osu.Game.Skinning { bool hasExtension = filename.Contains('.'); - string lastPiece = filename.Split('/').Last(); - var legacyName = filename.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; - var file = source.Files.Find(f => - string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), legacyName, StringComparison.InvariantCultureIgnoreCase)); + string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), filename, StringComparison.InvariantCultureIgnoreCase)); return file?.FileInfo.StoragePath; } From 0422c19c2fc524d03f1d159f780f01ae6457365a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Aug 2019 19:06:23 +0900 Subject: [PATCH 446/645] Group lifetime setters together --- .../UI/Scrolling/ScrollingHitObjectContainer.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 14a4869a98..1df8c8218f 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -93,27 +93,28 @@ namespace osu.Game.Rulesets.UI.Scrolling private void computeInitialStateRecursive(DrawableHitObject hitObject) { - hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value); + double endTime = hitObject.HitObject.StartTime; - if (hitObject.HitObject is IHasEndTime endTime) + if (hitObject.HitObject is IHasEndTime e) { - hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime.EndTime, timeRange.Value, scrollLength); + endTime = e.EndTime; switch (direction.Value) { case ScrollingDirection.Up: case ScrollingDirection.Down: - hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, timeRange.Value, scrollLength); + hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime, timeRange.Value, scrollLength); break; case ScrollingDirection.Left: case ScrollingDirection.Right: - hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, timeRange.Value, scrollLength); + hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime, timeRange.Value, scrollLength); break; } } - else - hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, hitObject.HitObject.StartTime, timeRange.Value, scrollLength); + + hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value); + hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime, timeRange.Value, scrollLength); foreach (var obj in hitObject.NestedHitObjects) { From fd0f42eee4ffd88e1b65e69e8187d906b596b25e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 26 Aug 2019 14:11:24 +0300 Subject: [PATCH 447/645] Fix filtered grouped difficulty items in DrawableCarouselBeatmapSet aren't hidden on first load --- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 0a8c61e3d2..137fce7acf 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -223,11 +223,9 @@ namespace osu.Game.Screens.Select.Carousel public FilterableGroupedDifficultyIcon(List items, RulesetInfo ruleset) : base(items.Select(i => i.Beatmap).ToList(), ruleset, Color4.White) { - items.ForEach(item => item.Filtered.ValueChanged += _ => - { - // for now, fade the whole group based on the ratio of hidden items. - this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100); - }); + // for now, fade the whole group based on the ratio of hidden items. + items.ForEach(item => item.Filtered.BindValueChanged(_ + => this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100), true)); } } } From 9321f208841a9b66a8f7a1441f9812a5f7d4c157 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 26 Aug 2019 14:32:27 +0300 Subject: [PATCH 448/645] Move arrow to the first line --- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 137fce7acf..5ef20bd0f2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -224,8 +224,8 @@ namespace osu.Game.Screens.Select.Carousel : base(items.Select(i => i.Beatmap).ToList(), ruleset, Color4.White) { // for now, fade the whole group based on the ratio of hidden items. - items.ForEach(item => item.Filtered.BindValueChanged(_ - => this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100), true)); + items.ForEach(item => item.Filtered.BindValueChanged(_ => + this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100), true)); } } } From fb69755869775abfbbb7ae79c4ca8087696c6aa8 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 26 Aug 2019 15:15:23 +0300 Subject: [PATCH 449/645] Use transform management for catch hit objects --- .../Objects/Drawable/DrawableCatchHitObject.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index a1279e8443..f4218061d4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -58,14 +58,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable ApplyResult(r => r.Type = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss); } - protected override bool UseTransformStateManagement => false; + protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt; - protected override void UpdateState(ArmedState state) + protected override void UpdateInitialTransforms() => this.FadeIn(200); + + protected override void UpdateStateTransforms(ArmedState state) { - // TODO: update to use new state management. - using (BeginAbsoluteSequence(HitObject.StartTime - HitObject.TimePreempt)) - this.FadeIn(200); - var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; using (BeginAbsoluteSequence(endTime, true)) From 3f93780306769c6a6bee07c57065052178f41bef Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 26 Aug 2019 15:15:48 +0300 Subject: [PATCH 450/645] Override transform update functions in bar line --- .../Objects/Drawables/DrawableBarLine.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs index 9c3197504f..dee7bddcb3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs @@ -69,7 +69,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Alpha = 0.2f; } - protected override void UpdateState(ArmedState state) + protected override void UpdateInitialTransforms() + { + } + + protected override void UpdateStateTransforms(ArmedState state) { } } From 62edfe7327672f2b56de7bfaf797555a3676927f Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 26 Aug 2019 15:16:01 +0300 Subject: [PATCH 451/645] Correct comment --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 62abe53559..ceda643335 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.UI if (lastPlateableFruit == null) return; - // this is required to make this run after the last caught fruit runs UpdateState at least once. + // this is required to make this run after the last caught fruit runs updateState() at least once. // TODO: find a better alternative if (lastPlateableFruit.IsLoaded) action(); From 24e7146a976297fabe3d56093cda75d16e412a4c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 26 Aug 2019 15:26:19 +0300 Subject: [PATCH 452/645] Revert unintended change --- .../Objects/Drawables/DrawableBarLine.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs index dee7bddcb3..9c3197504f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs @@ -69,11 +69,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Alpha = 0.2f; } - protected override void UpdateInitialTransforms() - { - } - - protected override void UpdateStateTransforms(ArmedState state) + protected override void UpdateState(ArmedState state) { } } From c11f5084004520256a56663d7fdb5d7c3e80869b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 26 Aug 2019 22:06:30 +0300 Subject: [PATCH 453/645] Use transform management for mania hit objects --- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Drawables/DrawableManiaHitObject.cs | 29 +++++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs index 9c3197504f..e9c352c97e 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Alpha = 0.2f; } - protected override void UpdateState(ArmedState state) + protected override void UpdateStateTransforms(ArmedState state) { } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index db6b53e76d..e5b114ca81 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -45,24 +45,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; } - } - public abstract class DrawableManiaHitObject : DrawableManiaHitObject - where TObject : ManiaHitObject - { - public new readonly TObject HitObject; - - protected DrawableManiaHitObject(TObject hitObject) - : base(hitObject) + protected override void UpdateStateTransforms(ArmedState state) { - HitObject = hitObject; - } - - protected override bool UseTransformStateManagement => false; - - protected override void UpdateState(ArmedState state) - { - // TODO: update to use new state management. switch (state) { case ArmedState.Miss: @@ -75,4 +60,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } } + + public abstract class DrawableManiaHitObject : DrawableManiaHitObject + where TObject : ManiaHitObject + { + public new readonly TObject HitObject; + + protected DrawableManiaHitObject(TObject hitObject) + : base(hitObject) + { + HitObject = hitObject; + } + } } From 843da26dbafc7c1605981bcf15f9c3006d5b5361 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 27 Aug 2019 05:03:56 +0300 Subject: [PATCH 454/645] Use transform management for taiko hit objects --- .../Objects/Drawables/DrawableDrumRoll.cs | 4 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 64 ++++++++----------- .../Objects/Drawables/DrawableSwell.cs | 21 +++--- .../Drawables/DrawableTaikoHitObject.cs | 2 - 5 files changed, 41 insertions(+), 52 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 9b4df74a61..f4407a7b54 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -88,13 +88,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables ApplyResult(r => r.Type = HitResult.Miss); } - protected override void UpdateState(ArmedState state) + protected override void UpdateStateTransforms(ArmedState state) { switch (state) { case ArmedState.Hit: case ArmedState.Miss: - this.FadeOut(100).Expire(); + this.Delay(HitObject.Duration).FadeOut(100).Expire(); break; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 9259c693d9..cef9a53deb 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables ApplyResult(r => r.Type = HitResult.Great); } - protected override void UpdateState(ArmedState state) + protected override void UpdateStateTransforms(ArmedState state) { switch (state) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 34ae7db984..fa45067210 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -92,56 +92,42 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Size = BaseSize * Parent.RelativeChildSize; } - protected override void UpdateState(ArmedState state) + protected override void UpdateStateTransforms(ArmedState state) { - // TODO: update to use new state management. - var circlePiece = MainPiece as CirclePiece; - circlePiece?.FlashBox.FinishTransforms(); - - var offset = !AllJudged ? 0 : Time.Current - HitObject.StartTime; - - using (BeginDelayedSequence(HitObject.StartTime - Time.Current + offset, true)) + switch (state) { - switch (State.Value) - { - case ArmedState.Idle: - validActionPressed = false; + case ArmedState.Idle: + validActionPressed = false; - UnproxyContent(); - this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire(); - break; + UnproxyContent(); + this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire(); + break; - case ArmedState.Miss: - this.FadeOut(100) - .Expire(); - break; + case ArmedState.Miss: + this.FadeOut(100) + .Expire(); + break; - case ArmedState.Hit: - // If we're far enough away from the left stage, we should bring outselves in front of it - ProxyContent(); + case ArmedState.Hit: + // If we're far enough away from the left stage, we should bring outselves in front of it + ProxyContent(); - var flash = circlePiece?.FlashBox; + var flash = (MainPiece as CirclePiece)?.FlashBox; + flash?.FadeTo(0.9f).FadeOut(300); - if (flash != null) - { - flash.FadeTo(0.9f); - flash.FadeOut(300); - } + const float gravity_time = 300; + const float gravity_travel_height = 200; - const float gravity_time = 300; - const float gravity_travel_height = 200; + this.ScaleTo(0.8f, gravity_time * 2, Easing.OutQuad); - this.ScaleTo(0.8f, gravity_time * 2, Easing.OutQuad); + this.MoveToY(-gravity_travel_height, gravity_time, Easing.Out) + .Then() + .MoveToY(gravity_travel_height * 2, gravity_time * 2, Easing.In); - this.MoveToY(-gravity_travel_height, gravity_time, Easing.Out) - .Then() - .MoveToY(gravity_travel_height * 2, gravity_time * 2, Easing.In); + this.FadeOut(800) + .Expire(); - this.FadeOut(800) - .Expire(); - - break; - } + break; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 82448ec7d5..88769bfff6 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -179,26 +179,31 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected override void UpdateState(ArmedState state) + protected override double InitialLifetimeOffset => 100; + + protected override void UpdateInitialTransforms() => targetRing.ScaleTo(target_ring_scale, InitialLifetimeOffset * 4, Easing.OutQuint); + + protected override void UpdateStateTransforms(ArmedState state) { - const float preempt = 100; - const float out_transition_time = 300; + const double transition_duration = 300; switch (state) { case ArmedState.Idle: UnproxyContent(); expandingRing.FadeTo(0); - using (BeginAbsoluteSequence(HitObject.StartTime - preempt, true)) - targetRing.ScaleTo(target_ring_scale, preempt * 4, Easing.OutQuint); break; case ArmedState.Miss: case ArmedState.Hit: - this.FadeOut(out_transition_time, Easing.Out); - bodyContainer.ScaleTo(1.4f, out_transition_time); + using (BeginAbsoluteSequence(Time.Current, true)) + { + this.FadeOut(transition_duration, Easing.Out); + bodyContainer.ScaleTo(1.4f, transition_duration); + + Expire(); + } - Expire(); break; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index b46738c69a..bd45b52d7b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -121,8 +121,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected override bool UseTransformStateManagement => false; - // Normal and clap samples are handled by the drum protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP); From cd68d030bd186fe3e9ef98489d876f258b76a4e1 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 27 Aug 2019 05:04:34 +0300 Subject: [PATCH 455/645] Remove unnecessary UpdateState overrides --- osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs | 4 ---- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs | 4 ---- .../Objects/Drawables/DrawableStrongNestedHit.cs | 4 ---- .../Objects/Drawables/DrawableSwellTick.cs | 4 ---- 4 files changed, 16 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index 6f9856df83..3c84d900a6 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -247,10 +247,6 @@ namespace osu.Game.Rulesets.Taiko.Tests : base(hitObject) { } - - protected override void UpdateState(ArmedState state) - { - } } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index f8909fb98c..bf89f7e15b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -53,9 +53,5 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Alpha = 0.75f }); } - - protected override void UpdateState(ArmedState state) - { - } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs index 98a2e8a721..108e42eea5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs @@ -18,9 +18,5 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { MainObject = mainObject; } - - protected override void UpdateState(ArmedState state) - { - } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 41a8fd9a75..fb80a9a5b4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -21,10 +21,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { } - protected override void UpdateState(ArmedState state) - { - } - public override bool OnPressed(TaikoAction action) => false; } } From 0eef398ca74ebf8d860ae81b86eab3ee0f0d9636 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 27 Aug 2019 05:19:21 +0300 Subject: [PATCH 456/645] Remove redundant using directive --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index fb80a9a5b4..8b27d78101 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Taiko.Objects.Drawables From 6368189d4660c188ae2360c856268d029ea5de91 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 11:59:25 +0900 Subject: [PATCH 457/645] Refactor --- .../Select/Carousel/DrawableCarouselBeatmapSet.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 5ef20bd0f2..97b6a78804 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -220,12 +220,23 @@ namespace osu.Game.Screens.Select.Carousel public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon { + private readonly List items; + public FilterableGroupedDifficultyIcon(List items, RulesetInfo ruleset) : base(items.Select(i => i.Beatmap).ToList(), ruleset, Color4.White) + { + this.items = items; + + foreach (var item in items) + item.Filtered.BindValueChanged(_ => Scheduler.AddOnce(updateFilteredDisplay)); + + updateFilteredDisplay(); + } + + private void updateFilteredDisplay() { // for now, fade the whole group based on the ratio of hidden items. - items.ForEach(item => item.Filtered.BindValueChanged(_ => - this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100), true)); + this.FadeTo(1 - 0.9f * ((float)items.Count(i => i.Filtered.Value) / items.Count), 100); } } } From 6014a6680411e2d553a8b09ef2beb86d2f0ee928 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 12:22:31 +0900 Subject: [PATCH 458/645] Add initial fade transform to fix rewind --- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index e5b114ca81..ce1484d460 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -46,6 +46,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; } + protected override void UpdateInitialTransforms() => this.FadeIn(); + protected override void UpdateStateTransforms(ArmedState state) { switch (state) From fff2da728926758c7ce6502ab0558b888289f979 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 12:59:57 +0900 Subject: [PATCH 459/645] Fix hold notes disappearing instantaneously --- .../Objects/Drawables/DrawableHoldNote.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 952c6e128e..fc3b6885d7 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI.Scrolling; @@ -104,6 +105,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; } + protected override void UpdateStateTransforms(ArmedState state) + { + using (BeginDelayedSequence(HitObject.Duration, true)) + base.UpdateStateTransforms(state); + } + protected void BeginHold() { holdStartTime = Time.Current; From 7885c79467aa732110d1cc6be57daf5a7521336a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 27 Aug 2019 14:31:34 +0900 Subject: [PATCH 460/645] Make bindables private --- .../SongSelect/TestScenePlaySongSelect.cs | 21 ++++++++++------ osu.Game/Screens/Select/FilterControl.cs | 24 +++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 2dbe53709b..263eada07c 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -15,6 +15,7 @@ using osu.Framework.MathUtils; using osu.Framework.Platform; using osu.Framework.Screens; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; @@ -79,8 +80,12 @@ namespace osu.Game.Tests.Visual.SongSelect Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, defaultBeatmap = Beatmap.Default)); Beatmap.SetDefault(); + + Dependencies.Cache(config = new OsuConfigManager(LocalStorage)); } + private OsuConfigManager config; + [SetUp] public virtual void SetUp() => Schedule(() => { @@ -111,13 +116,15 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); - AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Artist; }); - AddStep(@"Sort by Title", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Title; }); - AddStep(@"Sort by Author", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Author; }); - AddStep(@"Sort by DateAdded", delegate { songSelect.FilterControl.SortMode.Value = SortMode.DateAdded; }); - AddStep(@"Sort by BPM", delegate { songSelect.FilterControl.SortMode.Value = SortMode.BPM; }); - AddStep(@"Sort by Length", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Length; }); - AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.SortMode.Value = SortMode.Difficulty; }); + var sortMode = config.GetBindable(OsuSetting.SongSelectSortingMode); + + AddStep(@"Sort by Artist", delegate { sortMode.Value = SortMode.Artist; }); + AddStep(@"Sort by Title", delegate { sortMode.Value = SortMode.Title; }); + AddStep(@"Sort by Author", delegate { sortMode.Value = SortMode.Author; }); + AddStep(@"Sort by DateAdded", delegate { sortMode.Value = SortMode.DateAdded; }); + AddStep(@"Sort by BPM", delegate { sortMode.Value = SortMode.BPM; }); + AddStep(@"Sort by Length", delegate { sortMode.Value = SortMode.Length; }); + AddStep(@"Sort by Difficulty", delegate { sortMode.Value = SortMode.Difficulty; }); } [Test] diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 06b6cccf96..ed74b01fc9 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -29,14 +29,14 @@ namespace osu.Game.Screens.Select private readonly TabControl groupTabs; - public Bindable SortMode; + private Bindable sortMode; - public Bindable GroupMode; + private Bindable groupMode; public FilterCriteria CreateCriteria() => new FilterCriteria { - Group = GroupMode.Value, - Sort = SortMode.Value, + Group = groupMode.Value, + Sort = sortMode.Value, SearchText = searchTextBox.Text, AllowConvertedBeatmaps = showConverted.Value, Ruleset = ruleset.Value @@ -123,8 +123,8 @@ namespace osu.Game.Screens.Select searchTextBox.Current.ValueChanged += _ => FilterChanged?.Invoke(CreateCriteria()); - groupTabs.PinItem(Filter.GroupMode.All); - groupTabs.PinItem(Filter.GroupMode.RecentlyPlayed); + groupTabs.PinItem(GroupMode.All); + groupTabs.PinItem(GroupMode.RecentlyPlayed); } public void Deactivate() @@ -156,14 +156,14 @@ namespace osu.Game.Screens.Select ruleset.BindTo(parentRuleset); ruleset.BindValueChanged(_ => updateCriteria()); - SortMode = config.GetBindable(OsuSetting.SongSelectSortingMode); - GroupMode = config.GetBindable(OsuSetting.SongSelectGroupingMode); + sortMode = config.GetBindable(OsuSetting.SongSelectSortingMode); + groupMode = config.GetBindable(OsuSetting.SongSelectGroupingMode); - sortTabs.Current.BindTo(SortMode); - groupTabs.Current.BindTo(GroupMode); + sortTabs.Current.BindTo(sortMode); + groupTabs.Current.BindTo(groupMode); - GroupMode.BindValueChanged(_ => updateCriteria()); - SortMode.BindValueChanged(_ => updateCriteria()); + groupMode.BindValueChanged(_ => updateCriteria()); + sortMode.BindValueChanged(_ => updateCriteria()); updateCriteria(); } From b85e62a6e2da4f861788a67da8ae64495f30038b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 14:19:55 +0900 Subject: [PATCH 461/645] Fix taiko proxies being removed on rewind --- .../Drawables/DrawableTaikoHitObject.cs | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index b46738c69a..ea3ea4a9ad 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -78,10 +78,29 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public abstract bool OnPressed(TaikoAction action); public virtual bool OnReleased(TaikoAction action) => false; + public override double LifetimeStart + { + get => base.LifetimeStart; + set + { + base.LifetimeStart = value; + proxiedContent.LifetimeStart = value; + } + } + + public override double LifetimeEnd + { + get => base.LifetimeEnd; + set + { + base.LifetimeEnd = value; + proxiedContent.LifetimeEnd = value; + } + } + private class ProxiedContentContainer : Container { - public override double LifetimeStart => Parent?.LifetimeStart ?? base.LifetimeStart; - public override double LifetimeEnd => Parent?.LifetimeEnd ?? base.LifetimeEnd; + public override bool RemoveWhenNotAlive => false; } } From dba367981759de0db52b7b54bfc2046bfc15a154 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 15:19:16 +0900 Subject: [PATCH 462/645] Fix DrawableSwell not proxying its content in time/correctly --- .../Objects/Drawables/DrawableSwell.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 88769bfff6..7d5b928b4f 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -179,9 +179,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected override double InitialLifetimeOffset => 100; + protected override void UpdateInitialTransforms() + { + base.UpdateInitialTransforms(); - protected override void UpdateInitialTransforms() => targetRing.ScaleTo(target_ring_scale, InitialLifetimeOffset * 4, Easing.OutQuint); + using (BeginAbsoluteSequence(HitObject.StartTime - 100, true)) + targetRing.ScaleTo(target_ring_scale, 400, Easing.OutQuint); + } protected override void UpdateStateTransforms(ArmedState state) { @@ -190,7 +194,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (state) { case ArmedState.Idle: - UnproxyContent(); expandingRing.FadeTo(0); break; @@ -217,9 +220,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // Make the swell stop at the hit target X = Math.Max(0, X); - double t = Math.Min(HitObject.StartTime, Time.Current); - if (t == HitObject.StartTime) + if (Time.Current >= HitObject.StartTime - 100) ProxyContent(); + else + UnproxyContent(); } private bool? lastWasCentre; From bc7a81e733c21adb600120065e78eff7f65ac5da Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 15:19:29 +0900 Subject: [PATCH 463/645] Add initial fade transform --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index bd45b52d7b..a0a71a4c42 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -78,6 +78,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public abstract bool OnPressed(TaikoAction action); public virtual bool OnReleased(TaikoAction action) => false; + protected override void UpdateInitialTransforms() => this.FadeIn(); + private class ProxiedContentContainer : Container { public override double LifetimeStart => Parent?.LifetimeStart ?? base.LifetimeStart; From 2b22fd799dd4f16393f746aa9ea39819025ac9c0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 15:21:54 +0900 Subject: [PATCH 464/645] Use constant value for offset --- .../Objects/Drawables/DrawableSwell.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 7d5b928b4f..094ad1230f 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -25,6 +25,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private const float target_ring_scale = 5f; private const float inner_ring_alpha = 0.65f; + /// + /// Offset away from the start time of the swell at which the ring starts appearing. + /// + private const double ring_appear_offset = 100; + private readonly List ticks = new List(); private readonly Container bodyContainer; @@ -183,7 +188,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { base.UpdateInitialTransforms(); - using (BeginAbsoluteSequence(HitObject.StartTime - 100, true)) + using (BeginAbsoluteSequence(HitObject.StartTime - ring_appear_offset, true)) targetRing.ScaleTo(target_ring_scale, 400, Easing.OutQuint); } @@ -220,7 +225,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // Make the swell stop at the hit target X = Math.Max(0, X); - if (Time.Current >= HitObject.StartTime - 100) + if (Time.Current >= HitObject.StartTime - ring_appear_offset) ProxyContent(); else UnproxyContent(); From 9e926d44c0b68c86dadc031940a440ae86ccbabd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 27 Aug 2019 16:09:47 +0900 Subject: [PATCH 465/645] Obsolete legacy UpdateState() method --- .../Visual/Gameplay/TestSceneScrollingHitObjects.cs | 8 -------- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index 0a9cdc6a8e..aa80819694 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -200,10 +200,6 @@ namespace osu.Game.Tests.Visual.Gameplay break; } } - - protected override void UpdateState(ArmedState state) - { - } } private class TestDrawableHitObject : DrawableHitObject @@ -216,10 +212,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddInternal(new Box { Size = new Vector2(75) }); } - - protected override void UpdateState(ArmedState state) - { - } } } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index b72a55b9ed..80e70589bd 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -132,6 +132,8 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public event Action ApplyCustomUpdateState; +#pragma warning disable 618 // (legacy state management) - can be removed 20200227 + /// /// Enables automatic transform management of this hitobject. Implementation of transforms should be done in and only. Rewinding and removing previous states is done automatically. /// @@ -139,6 +141,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// Going forward, this is the preferred way of implementing s. Previous functionality /// is offered as a compatibility layer until all rulesets have been migrated across. /// + [Obsolete("Use UpdateInitialTransforms()/UpdateStateTransforms() instead")] // can be removed 20200227 protected virtual bool UseTransformStateManagement => true; protected override void ClearInternal(bool disposeChildren = true) => throw new InvalidOperationException($"Should never clear a {nameof(DrawableHitObject)}"); @@ -219,10 +222,13 @@ namespace osu.Game.Rulesets.Objects.Drawables /// Should generally not be used when is true; use instead. /// /// The new armed state. + [Obsolete("Use UpdateInitialTransforms()/UpdateStateTransforms() instead")] // can be removed 20200227 protected virtual void UpdateState(ArmedState state) { } +#pragma warning restore 618 + #endregion protected override void SkinChanged(ISkinSource skin, bool allowFallback) From 0ea10a49223ab178cd4fb520ffd7fc2ad87c1464 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 27 Aug 2019 17:18:32 +0900 Subject: [PATCH 466/645] Fix skin sample reading failing --- osu.Game/Skinning/LegacySkin.cs | 55 +++++++++++++++++---------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 7bffe5d321..37a3059160 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -155,16 +155,40 @@ namespace osu.Game.Skinning // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size Spacing = new Vector2(-Configuration.HitCircleOverlap * 0.89f, 0) }; - - default: - string lastPiece = componentName.Split('/').Last(); - componentName = componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; - break; } return getAnimation(componentName, animatable, looping); } + public override Texture GetTexture(string componentName) + { + componentName = getFallbackName(componentName); + + float ratio = 2; + var texture = Textures.Get($"{componentName}@2x"); + + if (texture == null) + { + ratio = 1; + texture = Textures.Get(componentName); + } + + if (texture != null) + texture.ScaleAdjust = ratio; + + return texture; + } + + public override SampleChannel GetSample(string sampleName) => Samples.Get(getFallbackName(sampleName)); + + private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; + + private string getFallbackName(string componentName) + { + string lastPiece = componentName.Split('/').Last(); + return componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; + } + private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-") { Texture texture; @@ -200,27 +224,6 @@ namespace osu.Game.Skinning return null; } - public override Texture GetTexture(string componentName) - { - float ratio = 2; - var texture = Textures.Get($"{componentName}@2x"); - - if (texture == null) - { - ratio = 1; - texture = Textures.Get(componentName); - } - - if (texture != null) - texture.ScaleAdjust = ratio; - - return texture; - } - - public override SampleChannel GetSample(string sampleName) => Samples.Get(sampleName); - - private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; - protected class LegacySkinResourceStore : IResourceStore where T : INamedFileInfo { From 7aeeb65ae7fe6df164155f31414997c8c64629ab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 27 Aug 2019 18:27:21 +0900 Subject: [PATCH 467/645] Tidy up Player's container loading logic Fixes drawable ruleset being loaded before skin sources are finished, by loading them as a separate operation (to avoid children being loaded first). --- .../SkinnableTestScene.cs | 3 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 1 - osu.Game/Screens/Play/Player.cs | 81 +++++++++++-------- osu.Game/Skinning/SkinProvidingContainer.cs | 2 + 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs index c3a64f8b54..29e5146ff1 100644 --- a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs +++ b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs @@ -45,12 +45,11 @@ namespace osu.Game.Rulesets.Osu.Tests private Drawable createProvider(Skin skin, Func creationFunction) { - var mainProvider = new SkinProvidingContainer(skin) { RelativeSizeAxes = Axes.Both }; + var mainProvider = new SkinProvidingContainer(skin); return mainProvider .WithChild(new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider)) { - RelativeSizeAxes = Axes.Both, Child = creationFunction() }); } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 178183bd22..ea7eee8bb8 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -44,7 +44,6 @@ namespace osu.Game.Rulesets.Osu.UI // Todo: Remove when hitobjects are properly pooled new SkinProvidingContainer(null) { - RelativeSizeAxes = Axes.Both, Child = HitObjectContainer, }, approachCircles = new ApproachCircleProxyContainer diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index deed17a049..b487f3e61b 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -123,30 +123,53 @@ namespace osu.Game.Screens.Play InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime); - SkinProvidingContainer skinProvidingContainer = new BeatmapSkinProvidingContainer(working.Skin) - { - RelativeSizeAxes = Axes.Both, - }; + addUnderlayComponents(GameplayClockContainer); + addGameplayComponents(GameplayClockContainer, working); + addOverlayComponents(GameplayClockContainer, working); - GameplayClockContainer.Children = new[] + DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true); + + // bind clock into components that require it + DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); + + // Bind ScoreProcessor to ourselves + ScoreProcessor.AllJudged += onCompletion; + ScoreProcessor.Failed += onFail; + + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToScoreProcessor(ScoreProcessor); + } + + private void addUnderlayComponents(Container target) + { + target.Add(DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both }); + } + + private void addGameplayComponents(Container target, WorkingBeatmap working) + { + var beatmapSkinProvider = new BeatmapSkinProvidingContainer(working.Skin); + + // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation + // full access to all skin sources. + var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider)); + + // load the skinning hierarchy first. + // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources. + target.Add(new ScalingContainer(ScalingMode.Gameplay) + .WithChild(beatmapSkinProvider + .WithChild(target = rulesetSkinProvider))); + + target.AddRange(new Drawable[] + { + DrawableRuleset, + new ComboEffects(ScoreProcessor) + }); + } + + private void addOverlayComponents(Container target, WorkingBeatmap working) + { + target.AddRange(new[] { - DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both }, - new ScalingContainer(ScalingMode.Gameplay) - { - Child = skinProvidingContainer.WithChild( - // the skinProvidingContainer is used as the fallback source here to allow the ruleset-specific skin implementation - // full access to all skin sources. - new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(skinProvidingContainer)) - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - DrawableRuleset, - new ComboEffects(ScoreProcessor) - } - } - ) - }, breakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) { Anchor = Anchor.Centre, @@ -205,19 +228,7 @@ namespace osu.Game.Screens.Play }, }, failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, } - }; - - DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true); - - // bind clock into components that require it - DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); - - // Bind ScoreProcessor to ourselves - ScoreProcessor.AllJudged += onCompletion; - ScoreProcessor.Failed += onFail; - - foreach (var mod in Mods.Value.OfType()) - mod.ApplyToScoreProcessor(ScoreProcessor); + }); } private WorkingBeatmap loadBeatmap() diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index a92a0ae0d1..9d6fbfdc74 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -32,6 +32,8 @@ namespace osu.Game.Skinning public SkinProvidingContainer(ISkin skin) { this.skin = skin; + + RelativeSizeAxes = Axes.Both; } public Drawable GetDrawableComponent(string componentName) From b59973c712a6213b103ad2cb4ecda79b267d610e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 27 Aug 2019 18:42:49 +0900 Subject: [PATCH 468/645] Update in line with framework changes --- osu.Game/Graphics/ScreenshotManager.cs | 2 +- osu.Game/Input/Bindings/GlobalActionContainer.cs | 2 +- osu.Game/Input/IdleTracker.cs | 2 +- osu.Game/Overlays/Volume/VolumeControlReceptor.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 524a4742c0..f532302de2 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -22,7 +22,7 @@ using SixLabors.ImageSharp; namespace osu.Game.Graphics { - public class ScreenshotManager : Container, IKeyBindingHandler, IHandleGlobalInput + public class ScreenshotManager : Container, IKeyBindingHandler, IHandleGlobalKeyboardInput { private readonly BindableBool cursorVisibility = new BindableBool(true); diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index b70072a222..bf758e21d9 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -10,7 +10,7 @@ using osu.Framework.Input.Bindings; namespace osu.Game.Input.Bindings { - public class GlobalActionContainer : DatabasedKeyBindingContainer, IHandleGlobalInput + public class GlobalActionContainer : DatabasedKeyBindingContainer, IHandleGlobalKeyboardInput { private readonly Drawable handler; diff --git a/osu.Game/Input/IdleTracker.cs b/osu.Game/Input/IdleTracker.cs index cbc446a126..39ccf9fe1c 100644 --- a/osu.Game/Input/IdleTracker.cs +++ b/osu.Game/Input/IdleTracker.cs @@ -12,7 +12,7 @@ namespace osu.Game.Input /// /// Track whether the end-user is in an idle state, based on their last interaction with the game. /// - public class IdleTracker : Component, IKeyBindingHandler, IHandleGlobalInput + public class IdleTracker : Component, IKeyBindingHandler, IHandleGlobalKeyboardInput { private readonly double timeToIdle; diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 26235fa280..9cd3aac2cb 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -9,7 +9,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Volume { - public class VolumeControlReceptor : Container, IScrollBindingHandler, IHandleGlobalInput + public class VolumeControlReceptor : Container, IScrollBindingHandler, IHandleGlobalKeyboardInput { public Func ActionRequested; public Func ScrollActionRequested; From f49b58c102e641ada62971df2413b8e83e1aefb6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 15:30:41 +0300 Subject: [PATCH 469/645] Simplify text building --- .../Kudosu/DrawableKudosuHistoryItem.cs | 46 ++++++------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 3cc39f0e73..4dba07713f 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -55,83 +55,67 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu switch (historyItem.Action) { case KudosuAction.VoteGive: - linkFlowContainer.AddText(@"Received "); - addKudosuPart(); + addKudosuPart(@"Received"); addMainPart(@" from obtaining votes in modding post of "); - addPostPart(); break; case KudosuAction.Give: - linkFlowContainer.AddText(@"Received "); - addKudosuPart(); + addKudosuPart(@"Received"); addMainPart($@" from {userLinkTemplate()} for a post at "); - addPostPart(); break; case KudosuAction.Reset: addMainPart($@"Kudosu reset by {userLinkTemplate()} for the post "); - addPostPart(); break; case KudosuAction.VoteReset: - linkFlowContainer.AddText(@"Lost "); - addKudosuPart(); + addKudosuPart(@"Lost"); addMainPart(@" from losing votes in modding post of "); - addPostPart(); break; case KudosuAction.DenyKudosuReset: - linkFlowContainer.AddText(@"Denied "); - addKudosuPart(); + addKudosuPart(@"Denied"); addMainPart(@" from modding post "); - addPostPart(); break; case KudosuAction.Revoke: addMainPart($@"Denied kudosu by {userLinkTemplate()} for the post "); - addPostPart(); break; case KudosuAction.AllowKudosuGive: - linkFlowContainer.AddText(@"Received "); - addKudosuPart(); + addKudosuPart(@"Received"); addMainPart(@" from kudosu deny repeal of modding post "); - addPostPart(); break; case KudosuAction.DeleteReset: - linkFlowContainer.AddText(@"Lost "); - addKudosuPart(); + addKudosuPart(@"Lost"); addMainPart(@" from modding post deletion of "); - addPostPart(); break; case KudosuAction.RestoreGive: - linkFlowContainer.AddText(@"Received "); - addKudosuPart(); + addKudosuPart(@"Received"); addMainPart(@" from modding post restoration of "); - addPostPart(); break; case KudosuAction.RecalculateGive: - linkFlowContainer.AddText(@"Received "); - addKudosuPart(); + addKudosuPart(@"Received"); addMainPart(@" from votes recalculation in modding post of "); - addPostPart(); break; case KudosuAction.RecalculateReset: - linkFlowContainer.AddText(@"Lost "); - addKudosuPart(); + addKudosuPart(@"Lost"); addMainPart(@" from votes recalculation in modding post of "); - addPostPart(); break; } + + addPostPart(); } - private void addKudosuPart() + private void addKudosuPart(string prefix) { - linkFlowContainer.AddText($@"{historyItem.Amount} kudosu", t => + linkFlowContainer.AddText(prefix); + + linkFlowContainer.AddText($@" {historyItem.Amount} kudosu", t => { t.Font = t.Font.With(italics: true); t.Colour = colours.Blue; From ed827d514f42d2d774f9b592dfee85c962036b94 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 15:36:08 +0300 Subject: [PATCH 470/645] Add comments --- osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index d02f71c339..19ce11aa13 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -15,6 +15,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("amount")] private int amount { + //We can receive negative values. However "action" is enough to build needed items set => Amount = Math.Abs(value); } @@ -49,6 +50,7 @@ namespace osu.Game.Online.API.Requests.Responses { set { + //We will receive something like "foo.bar" or just "foo" string parsed = value.Contains(".") ? value.Split('.')[0].Pascalize() + value.Split('.')[1].Pascalize() : value.Pascalize(); Action = (KudosuAction)Enum.Parse(typeof(KudosuAction), parsed); From 22ee7db805c1be3876c6d625d6107e98d4425cbf Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 15:47:37 +0300 Subject: [PATCH 471/645] Refactor PaginatedContainer to avoid code duplication --- .../Beatmaps/PaginatedBeatmapContainer.cs | 48 +++--------- .../PaginatedMostPlayedBeatmapContainer.cs | 41 ++-------- .../Profile/Sections/PaginatedContainer.cs | 76 +++++++++++++++---- .../Sections/Ranks/PaginatedScoreContainer.cs | 65 +++++----------- .../PaginatedRecentActivityContainer.cs | 39 ++-------- 5 files changed, 107 insertions(+), 162 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 8a6b52b7ee..d0ba3e6ba5 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -1,21 +1,22 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; +using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Direct; using osu.Game.Users; using osuTK; namespace osu.Game.Overlays.Profile.Sections.Beatmaps { - public class PaginatedBeatmapContainer : PaginatedContainer + public class PaginatedBeatmapContainer : PaginatedContainer { private const float panel_padding = 10f; private readonly BeatmapSetType type; - private GetUserBeatmapsRequest request; public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, string header, string missing = "None... yet.") : base(user, header, missing) @@ -27,40 +28,13 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps ItemsContainer.Spacing = new Vector2(panel_padding); } - protected override void ShowMore() + protected override APIRequest> CreateRequest() => + new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); + + protected override Drawable CreateDrawableItem(APIBeatmapSet item) => new DirectGridPanel(item.ToBeatmapSet(Rulesets)) { - request = new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - request.Success += sets => Schedule(() => - { - MoreButton.FadeTo(sets.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; - - if (!sets.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - foreach (var s in sets) - { - if (!s.OnlineBeatmapSetID.HasValue) - continue; - - ItemsContainer.Add(new DirectGridPanel(s.ToBeatmapSet(Rulesets)) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }); - } - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 23072f8d90..10aa31225f 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -1,19 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; +using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Users; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer + public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer { - private GetUserMostPlayedBeatmapsRequest request; - public PaginatedMostPlayedBeatmapContainer(Bindable user) : base(user, "Most Played Beatmaps", "No records. :(") { @@ -22,35 +22,10 @@ namespace osu.Game.Overlays.Profile.Sections.Historical ItemsContainer.Direction = FillDirection.Vertical; } - protected override void ShowMore() - { - request = new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - request.Success += beatmaps => Schedule(() => - { - MoreButton.FadeTo(beatmaps.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; + protected override APIRequest> CreateRequest() => + new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - if (!beatmaps.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - MissingText.Hide(); - - foreach (var beatmap in beatmaps) - { - ItemsContainer.Add(new DrawableMostPlayedBeatmap(beatmap.GetBeatmapInfo(Rulesets), beatmap.PlayCount)); - } - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap item) => + new DrawableMostPlayedBeatmap(item.GetBeatmapInfo(Rulesets), item.PlayCount); } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index b459afcb49..75601041e8 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -11,22 +11,27 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Rulesets; using osu.Game.Users; +using System.Collections.Generic; +using System.Linq; +using System.Threading; namespace osu.Game.Overlays.Profile.Sections { - public abstract class PaginatedContainer : FillFlowContainer + public abstract class PaginatedContainer : FillFlowContainer { - protected readonly FillFlowContainer ItemsContainer; - protected readonly ShowMoreButton MoreButton; - protected readonly OsuSpriteText MissingText; + private readonly ShowMoreButton moreButton; + private readonly OsuSpriteText missingText; + private APIRequest> retrievalRequest; + private CancellationTokenSource loadCancellation; + + [Resolved] + private IAPIProvider api { get; set; } protected int VisiblePages; protected int ItemsPerPage; protected readonly Bindable User = new Bindable(); - - protected IAPIProvider Api; - protected APIRequest RetrievalRequest; + protected readonly FillFlowContainer ItemsContainer; protected RulesetStore Rulesets; protected PaginatedContainer(Bindable user, string header, string missing) @@ -51,15 +56,15 @@ namespace osu.Game.Overlays.Profile.Sections RelativeSizeAxes = Axes.X, Spacing = new Vector2(0, 2), }, - MoreButton = new ShowMoreButton + moreButton = new ShowMoreButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Alpha = 0, Margin = new MarginPadding { Top = 10 }, - Action = ShowMore, + Action = showMore, }, - MissingText = new OsuSpriteText + missingText = new OsuSpriteText { Font = OsuFont.GetFont(size: 15), Text = missing, @@ -69,9 +74,8 @@ namespace osu.Game.Overlays.Profile.Sections } [BackgroundDependencyLoader] - private void load(IAPIProvider api, RulesetStore rulesets) + private void load(RulesetStore rulesets) { - Api = api; Rulesets = rulesets; User.ValueChanged += onUserChanged; @@ -80,13 +84,57 @@ namespace osu.Game.Overlays.Profile.Sections private void onUserChanged(ValueChangedEvent e) { + loadCancellation?.Cancel(); + retrievalRequest?.Cancel(); + VisiblePages = 0; ItemsContainer.Clear(); if (e.NewValue != null) - ShowMore(); + showMore(); } - protected abstract void ShowMore(); + private void showMore() + { + loadCancellation = new CancellationTokenSource(); + + retrievalRequest = CreateRequest(); + retrievalRequest.Success += UpdateItems; + + api.Queue(retrievalRequest); + } + + protected virtual void UpdateItems(List items) + { + Schedule(() => + { + if (!items.Any() && VisiblePages == 1) + { + moreButton.Hide(); + moreButton.IsLoading = false; + missingText.Show(); + return; + } + + LoadComponentsAsync(items.Select(CreateDrawableItem), drawables => + { + missingText.Hide(); + moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); + moreButton.IsLoading = false; + + ItemsContainer.AddRange(drawables); + }, loadCancellation.Token); + }); + } + + protected abstract APIRequest> CreateRequest(); + + protected abstract Drawable CreateDrawableItem(T item); + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + retrievalRequest?.Cancel(); + } } } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 4a9ac6e5c7..96291f5a32 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -5,18 +5,18 @@ using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Users; using System; -using System.Collections.Generic; -using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Online.API.Requests.Responses; +using System.Collections.Generic; +using osu.Game.Online.API; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class PaginatedScoreContainer : PaginatedContainer + public class PaginatedScoreContainer : PaginatedContainer { private readonly bool includeWeight; private readonly ScoreType type; - private GetUserScoresRequest request; public PaginatedScoreContainer(ScoreType type, Bindable user, string header, string missing, bool includeWeight = false) : base(user, header, missing) @@ -29,52 +29,27 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks ItemsContainer.Direction = FillDirection.Vertical; } - protected override void ShowMore() + protected override void UpdateItems(List items) { - request = new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - request.Success += scores => Schedule(() => - { - foreach (var s in scores) - s.Ruleset = Rulesets.GetRuleset(s.RulesetID); + foreach (var item in items) + item.Ruleset = Rulesets.GetRuleset(item.RulesetID); - if (!scores.Any() && VisiblePages == 1) - { - MoreButton.Hide(); - MoreButton.IsLoading = false; - MissingText.Show(); - return; - } - - IEnumerable drawableScores; - - switch (type) - { - default: - drawableScores = scores.Select(score => new DrawablePerformanceScore(score, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null)); - break; - - case ScoreType.Recent: - drawableScores = scores.Select(score => new DrawableTotalScore(score)); - break; - } - - LoadComponentsAsync(drawableScores, s => - { - MissingText.Hide(); - MoreButton.FadeTo(scores.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; - - ItemsContainer.AddRange(s); - }); - }); - - Api.Queue(request); + base.UpdateItems(items); } - protected override void Dispose(bool isDisposing) + protected override APIRequest> CreateRequest() => + new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); + + protected override Drawable CreateDrawableItem(APILegacyScoreInfo item) { - base.Dispose(isDisposing); - request?.Cancel(); + switch (type) + { + default: + return new DrawablePerformanceScore(item, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + + case ScoreType.Recent: + return new DrawableTotalScore(item); + } } } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index f2a778a874..8cc762e3a7 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -4,51 +4,24 @@ using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Game.Users; -using System.Linq; using osu.Framework.Bindables; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.API; +using System.Collections.Generic; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class PaginatedRecentActivityContainer : PaginatedContainer + public class PaginatedRecentActivityContainer : PaginatedContainer { - private GetUserRecentActivitiesRequest request; - public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) { ItemsPerPage = 5; } - protected override void ShowMore() - { - request = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - request.Success += activities => Schedule(() => - { - MoreButton.FadeTo(activities.Count == ItemsPerPage ? 1 : 0); - MoreButton.IsLoading = false; + protected override APIRequest> CreateRequest() => + new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - if (!activities.Any() && VisiblePages == 1) - { - MissingText.Show(); - return; - } - - MissingText.Hide(); - - foreach (APIRecentActivity activity in activities) - { - ItemsContainer.Add(new DrawableRecentActivity(activity)); - } - }); - - Api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - request?.Cancel(); - } + protected override Drawable CreateDrawableItem(APIRecentActivity item) => new DrawableRecentActivity(item); } } From 9a383eee1a802f85819504e31da54852816df45d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 15:58:57 +0300 Subject: [PATCH 472/645] Add AllowCreate function --- .../Sections/Beatmaps/PaginatedBeatmapContainer.cs | 2 ++ osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index d0ba3e6ba5..0b424057ae 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -31,6 +31,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override APIRequest> CreateRequest() => new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); + protected override bool AllowCreate(APIBeatmapSet item) => item.OnlineBeatmapSetID.HasValue; + protected override Drawable CreateDrawableItem(APIBeatmapSet item) => new DirectGridPanel(item.ToBeatmapSet(Rulesets)) { Anchor = Anchor.TopCentre, diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index 75601041e8..adc1107b32 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Sections return; } - LoadComponentsAsync(items.Select(CreateDrawableItem), drawables => + LoadComponentsAsync(items.Where(item => AllowCreate(item)).Select(CreateDrawableItem), drawables => { missingText.Hide(); moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); @@ -127,6 +127,13 @@ namespace osu.Game.Overlays.Profile.Sections }); } + /// + /// Used to check whether the item is suitable for drawable creation. + /// + /// An item to check + /// + protected virtual bool AllowCreate(T item) => true; + protected abstract APIRequest> CreateRequest(); protected abstract Drawable CreateDrawableItem(T item); From 5fd43d42f441c54787ba132012297f8e6de9e956 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 27 Aug 2019 16:09:37 +0300 Subject: [PATCH 473/645] CI fixes --- osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs | 2 +- .../Profile/Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index adc1107b32..a3a22d6248 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Sections return; } - LoadComponentsAsync(items.Where(item => AllowCreate(item)).Select(CreateDrawableItem), drawables => + LoadComponentsAsync(items.Where(AllowCreate).Select(CreateDrawableItem), drawables => { missingText.Hide(); moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 96291f5a32..5f023cfa4b 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -45,10 +45,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks switch (type) { default: - return new DrawablePerformanceScore(item, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + return new DrawablePerformanceScore(item, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); case ScoreType.Recent: - return new DrawableTotalScore(item); + return new DrawableTotalScore(item); } } } From 4ef991b97309868a507a63097caa9de1611da9be Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 27 Aug 2019 19:42:17 +0300 Subject: [PATCH 474/645] Loop over lookup names on default-samples retrieval --- osu.Game/Skinning/SkinnableSound.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 23093d9bd9..0c20241c4c 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -45,10 +45,9 @@ namespace osu.Game.Skinning var ch = skin.GetSample(s); if (ch == null && allowFallback) - if (s is HitSampleInfo hsi) - ch = audio.Samples.Get(string.IsNullOrEmpty(hsi.Namespace) - ? $"Gameplay/{hsi.Namespace}/{hsi.Bank}-{hsi.Name}" - : $"Gameplay/{hsi.Bank}-{hsi.Name}"); + foreach (var lookup in s.LookupNames) + if ((ch = audio.Samples.Get($"Gameplay/{lookup}")) != null) + break; if (ch != null) ch.Volume.Value = s.Volume / 100.0; From 4add1727b7458b9e36584fafdb753793c41ee447 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 03:25:57 +0900 Subject: [PATCH 475/645] Fix hitsounds not updating immediately after switching skins --- osu.Game/Skinning/SkinnableSound.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8e2b5cec98..aa1c596a51 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -37,7 +37,7 @@ namespace osu.Game.Skinning public void Play() => channels?.ForEach(c => c.Play()); - public override bool IsPresent => false; // We don't need to receive updates. + public override bool IsPresent => Scheduler.HasPendingTasks; protected override void SkinChanged(ISkinSource skin, bool allowFallback) { From 7cc92e2fad4cdfbeefd12d718d73e3cf0ad27af8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 28 Aug 2019 13:20:28 +0900 Subject: [PATCH 476/645] Make taiko proxy containers use LifetimeManagementContainer --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index e62dc45cab..a10f70a344 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -44,9 +44,8 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly JudgementContainer judgementContainer; internal readonly HitTarget HitTarget; - private readonly Container topLevelHitContainer; - - private readonly Container barlineContainer; + private readonly ProxyContainer topLevelHitContainer; + private readonly ProxyContainer barlineContainer; private readonly Container overlayBackgroundContainer; private readonly Container backgroundContainer; @@ -108,7 +107,7 @@ namespace osu.Game.Rulesets.Taiko.UI } } }, - barlineContainer = new Container + barlineContainer = new ProxyContainer { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = HIT_TARGET_OFFSET } @@ -183,7 +182,7 @@ namespace osu.Game.Rulesets.Taiko.UI } } }, - topLevelHitContainer = new Container + topLevelHitContainer = new ProxyContainer { Name = "Top level hit objects", RelativeSizeAxes = Axes.Both, @@ -256,5 +255,15 @@ namespace osu.Game.Rulesets.Taiko.UI break; } } + + private class ProxyContainer : LifetimeManagementContainer + { + public new MarginPadding Padding + { + set => base.Padding = value; + } + + public void Add(Drawable proxy) => AddInternal(proxy); + } } } From f18b5a3c02ff44dd78db54fc9eae2f2c4979fac0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 13:27:44 +0900 Subject: [PATCH 477/645] Remove "AllowCreate" function by instead handling nulls --- .../Sections/Beatmaps/PaginatedBeatmapContainer.cs | 14 +++++++------- .../Profile/Sections/PaginatedContainer.cs | 9 +-------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 0b424057ae..fe6822440f 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -31,12 +31,12 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override APIRequest> CreateRequest() => new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - protected override bool AllowCreate(APIBeatmapSet item) => item.OnlineBeatmapSetID.HasValue; - - protected override Drawable CreateDrawableItem(APIBeatmapSet item) => new DirectGridPanel(item.ToBeatmapSet(Rulesets)) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }; + protected override Drawable CreateDrawableItem(APIBeatmapSet item) => !item.OnlineBeatmapSetID.HasValue + ? null + : new DirectGridPanel(item.ToBeatmapSet(Rulesets)) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index a3a22d6248..4a10946ec2 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Sections return; } - LoadComponentsAsync(items.Where(AllowCreate).Select(CreateDrawableItem), drawables => + LoadComponentsAsync(items.Select(CreateDrawableItem).Where(d => d != null), drawables => { missingText.Hide(); moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); @@ -127,13 +127,6 @@ namespace osu.Game.Overlays.Profile.Sections }); } - /// - /// Used to check whether the item is suitable for drawable creation. - /// - /// An item to check - /// - protected virtual bool AllowCreate(T item) => true; - protected abstract APIRequest> CreateRequest(); protected abstract Drawable CreateDrawableItem(T item); From 27633c8dbd28b50a9f7796617d426c563d4dd5e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 13:28:21 +0900 Subject: [PATCH 478/645] T -> TModel --- .../Overlays/Profile/Sections/PaginatedContainer.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index 4a10946ec2..b91f22d1e7 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -17,11 +17,11 @@ using System.Threading; namespace osu.Game.Overlays.Profile.Sections { - public abstract class PaginatedContainer : FillFlowContainer + public abstract class PaginatedContainer : FillFlowContainer { private readonly ShowMoreButton moreButton; private readonly OsuSpriteText missingText; - private APIRequest> retrievalRequest; + private APIRequest> retrievalRequest; private CancellationTokenSource loadCancellation; [Resolved] @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Sections api.Queue(retrievalRequest); } - protected virtual void UpdateItems(List items) + protected virtual void UpdateItems(List items) { Schedule(() => { @@ -127,9 +127,9 @@ namespace osu.Game.Overlays.Profile.Sections }); } - protected abstract APIRequest> CreateRequest(); + protected abstract APIRequest> CreateRequest(); - protected abstract Drawable CreateDrawableItem(T item); + protected abstract Drawable CreateDrawableItem(TModel item); protected override void Dispose(bool isDisposing) { From 3942c83c187034750131d527e5b839106e973160 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 13:28:57 +0900 Subject: [PATCH 479/645] Simplify schedule layout --- .../Profile/Sections/PaginatedContainer.cs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index b91f22d1e7..e26f7f3601 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -104,28 +104,25 @@ namespace osu.Game.Overlays.Profile.Sections api.Queue(retrievalRequest); } - protected virtual void UpdateItems(List items) + protected virtual void UpdateItems(List items) => Schedule(() => { - Schedule(() => + if (!items.Any() && VisiblePages == 1) { - if (!items.Any() && VisiblePages == 1) - { - moreButton.Hide(); - moreButton.IsLoading = false; - missingText.Show(); - return; - } + moreButton.Hide(); + moreButton.IsLoading = false; + missingText.Show(); + return; + } - LoadComponentsAsync(items.Select(CreateDrawableItem).Where(d => d != null), drawables => - { - missingText.Hide(); - moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); - moreButton.IsLoading = false; + LoadComponentsAsync(items.Select(CreateDrawableItem).Where(d => d != null), drawables => + { + missingText.Hide(); + moreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); + moreButton.IsLoading = false; - ItemsContainer.AddRange(drawables); - }, loadCancellation.Token); - }); - } + ItemsContainer.AddRange(drawables); + }, loadCancellation.Token); + }); protected abstract APIRequest> CreateRequest(); From bef44b8e58581a6e5d51871c8ef5acd13aca2502 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 13:31:12 +0900 Subject: [PATCH 480/645] item -> model --- .../Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Historical/PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs | 2 +- .../Profile/Sections/Ranks/PaginatedScoreContainer.cs | 6 +++--- .../Sections/Recent/PaginatedRecentActivityContainer.cs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index fe6822440f..919f8a2fa0 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -31,9 +31,9 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override APIRequest> CreateRequest() => new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - protected override Drawable CreateDrawableItem(APIBeatmapSet item) => !item.OnlineBeatmapSetID.HasValue + protected override Drawable CreateDrawableItem(APIBeatmapSet model) => !model.OnlineBeatmapSetID.HasValue ? null - : new DirectGridPanel(item.ToBeatmapSet(Rulesets)) + : new DirectGridPanel(model.ToBeatmapSet(Rulesets)) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 10aa31225f..6e6d6272c7 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override APIRequest> CreateRequest() => new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap item) => - new DrawableMostPlayedBeatmap(item.GetBeatmapInfo(Rulesets), item.PlayCount); + protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap model) => + new DrawableMostPlayedBeatmap(model.GetBeatmapInfo(Rulesets), model.PlayCount); } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index e26f7f3601..bb221bd43a 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Profile.Sections protected abstract APIRequest> CreateRequest(); - protected abstract Drawable CreateDrawableItem(TModel item); + protected abstract Drawable CreateDrawableItem(TModel model); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 5f023cfa4b..853b9db0a7 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -40,15 +40,15 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks protected override APIRequest> CreateRequest() => new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage); - protected override Drawable CreateDrawableItem(APILegacyScoreInfo item) + protected override Drawable CreateDrawableItem(APILegacyScoreInfo model) { switch (type) { default: - return new DrawablePerformanceScore(item, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + return new DrawablePerformanceScore(model, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); case ScoreType.Recent: - return new DrawableTotalScore(item); + return new DrawableTotalScore(model); } } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 8cc762e3a7..3f9d4dc93e 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -22,6 +22,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent protected override APIRequest> CreateRequest() => new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - protected override Drawable CreateDrawableItem(APIRecentActivity item) => new DrawableRecentActivity(item); + protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model); } } From 70da25cfca5664965951c27bbd41600cb13898eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 17:03:54 +0900 Subject: [PATCH 481/645] 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 215a9a8090..0f6e32d664 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4fe9119cef..d791909372 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 82301549d7..9fc472bf40 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,8 +118,8 @@ - - + + From bb22c2d6e48b8039b967bd7c7320f84e382af794 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 17:29:18 +0900 Subject: [PATCH 482/645] Tidy up text construction --- .../Kudosu/DrawableKudosuHistoryItem.cs | 116 ++++++++++-------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 4dba07713f..fb7d597012 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -50,85 +50,101 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { date.Colour = colours.GreySeafoamLighter; - string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; + string prefix = getPrefix(historyItem); + var formattedSource = MessageFormatter.FormatText(getSource(historyItem)); + + if (!string.IsNullOrEmpty(prefix)) + { + linkFlowContainer.AddText(prefix); + linkFlowContainer.AddText($@" {historyItem.Amount} kudosu", t => + { + t.Font = t.Font.With(italics: true); + t.Colour = colours.Blue; + }); + } + + linkFlowContainer.AddLinks(formattedSource.Text + " ", formattedSource.Links); + linkFlowContainer.AddLink(historyItem.Post.Title, historyItem.Post.Url); + } + + private string getSource(APIKudosuHistory historyItem) + { + string userLink() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; switch (historyItem.Action) { case KudosuAction.VoteGive: - addKudosuPart(@"Received"); - addMainPart(@" from obtaining votes in modding post of "); - break; + return @" from obtaining votes in modding post of"; case KudosuAction.Give: - addKudosuPart(@"Received"); - addMainPart($@" from {userLinkTemplate()} for a post at "); - break; + return $@" from {userLink()} for a post at"; case KudosuAction.Reset: - addMainPart($@"Kudosu reset by {userLinkTemplate()} for the post "); - break; + return $@"Kudosu reset by {userLink()} for the post"; case KudosuAction.VoteReset: - addKudosuPart(@"Lost"); - addMainPart(@" from losing votes in modding post of "); - break; + return @" from losing votes in modding post of"; case KudosuAction.DenyKudosuReset: - addKudosuPart(@"Denied"); - addMainPart(@" from modding post "); - break; + return @" from modding post"; case KudosuAction.Revoke: - addMainPart($@"Denied kudosu by {userLinkTemplate()} for the post "); - break; + return $@"Denied kudosu by {userLink()} for the post"; case KudosuAction.AllowKudosuGive: - addKudosuPart(@"Received"); - addMainPart(@" from kudosu deny repeal of modding post "); - break; + return @" from kudosu deny repeal of modding post"; case KudosuAction.DeleteReset: - addKudosuPart(@"Lost"); - addMainPart(@" from modding post deletion of "); - break; + return @" from modding post deletion of"; case KudosuAction.RestoreGive: - addKudosuPart(@"Received"); - addMainPart(@" from modding post restoration of "); - break; + return @" from modding post restoration of"; case KudosuAction.RecalculateGive: - addKudosuPart(@"Received"); - addMainPart(@" from votes recalculation in modding post of "); - break; + return @" from votes recalculation in modding post of"; case KudosuAction.RecalculateReset: - addKudosuPart(@"Lost"); - addMainPart(@" from votes recalculation in modding post of "); - break; + return @" from votes recalculation in modding post of"; + + default: + return @" from unknown event "; } - - addPostPart(); } - private void addKudosuPart(string prefix) + private string getPrefix(APIKudosuHistory historyItem) { - linkFlowContainer.AddText(prefix); - - linkFlowContainer.AddText($@" {historyItem.Amount} kudosu", t => + switch (historyItem.Action) { - t.Font = t.Font.With(italics: true); - t.Colour = colours.Blue; - }); + case KudosuAction.VoteGive: + return @"Received"; + + case KudosuAction.Give: + return @"Received"; + + case KudosuAction.VoteReset: + return @"Lost"; + + case KudosuAction.DenyKudosuReset: + return @"Denied"; + + case KudosuAction.AllowKudosuGive: + return @"Received"; + + case KudosuAction.DeleteReset: + return @"Lost"; + + case KudosuAction.RestoreGive: + return @"Received"; + + case KudosuAction.RecalculateGive: + return @"Received"; + + case KudosuAction.RecalculateReset: + return @"Lost"; + + default: + return null; + } } - - private void addMainPart(string text) - { - var formatted = MessageFormatter.FormatText(text); - - linkFlowContainer.AddLinks(formatted.Text, formatted.Links); - } - - private void addPostPart() => linkFlowContainer.AddLink(historyItem.Post.Title, historyItem.Post.Url); } } From 9752dbf9505ba614d6609c42fa874aeb73aad026 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 18:10:58 +0900 Subject: [PATCH 483/645] Fix osu! approach circles fading in too late --- .../Objects/Drawables/DrawableHitCircle.cs | 6 +++++- .../Objects/Drawables/DrawableOsuHitObject.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index ca124e9214..0af278f6a4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -29,6 +29,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly HitArea hitArea; + private readonly SkinnableDrawable mainContent; + public DrawableHitCircle(HitCircle h) : base(h) { @@ -56,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables return true; }, }, - new SkinnableDrawable("Play/osu/hitcircle", _ => new MainCirclePiece(HitObject.IndexInCurrentCombo)), + mainContent = new SkinnableDrawable("Play/osu/hitcircle", _ => new MainCirclePiece(HitObject.IndexInCurrentCombo)), ApproachCircle = new ApproachCircle { Alpha = 0, @@ -108,6 +110,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdateInitialTransforms(); + mainContent.FadeInFromZero(HitObject.TimeFadeIn); + ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt)); ApproachCircle.ScaleTo(1f, HitObject.TimePreempt); ApproachCircle.Expire(true); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index a89fb8b682..17efefa959 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt; - protected override void UpdateInitialTransforms() => this.FadeIn(HitObject.TimeFadeIn); + protected override void UpdateInitialTransforms() => this.FadeInFromZero(); private OsuInputManager osuActionInputManager; internal OsuInputManager OsuActionInputManager => osuActionInputManager ?? (osuActionInputManager = GetContainingInputManager() as OsuInputManager); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index a0626707af..1749ea1f60 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -93,6 +93,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } + protected override void UpdateInitialTransforms() + { + base.UpdateInitialTransforms(); + + Body.FadeInFromZero(HitObject.TimeFadeIn); + } + [BackgroundDependencyLoader] private void load() { From 9a98f39f06623a181bf4298e8ffb1c8f80e238a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 18:12:47 +0900 Subject: [PATCH 484/645] Share logic with other rulesets (and make default) --- .../Objects/Drawable/DrawableCatchHitObject.cs | 2 +- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 -- .../Objects/Drawables/DrawableOsuHitObject.cs | 2 -- .../Objects/Drawables/DrawableTaikoHitObject.cs | 2 -- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ++++ 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index f4218061d4..00734810b3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt; - protected override void UpdateInitialTransforms() => this.FadeIn(200); + protected override void UpdateInitialTransforms() => this.FadeInFromZero(200); protected override void UpdateStateTransforms(ArmedState state) { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index ce1484d460..e5b114ca81 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -46,8 +46,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; } - protected override void UpdateInitialTransforms() => this.FadeIn(); - protected override void UpdateStateTransforms(ArmedState state) { switch (state) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 17efefa959..b4f5642f45 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -36,8 +36,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt; - protected override void UpdateInitialTransforms() => this.FadeInFromZero(); - private OsuInputManager osuActionInputManager; internal OsuInputManager OsuActionInputManager => osuActionInputManager ?? (osuActionInputManager = GetContainingInputManager() as OsuInputManager); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 5f3bab5b28..5424ccb4de 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -78,8 +78,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public abstract bool OnPressed(TaikoAction action); public virtual bool OnReleased(TaikoAction action) => false; - protected override void UpdateInitialTransforms() => this.FadeIn(); - public override double LifetimeStart { get => base.LifetimeStart; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 80e70589bd..4a6f261905 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Graphics; using osu.Framework.Graphics.Primitives; using osu.Game.Audio; using osu.Game.Rulesets.Judgements; @@ -186,6 +187,8 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Apply (generally fade-in) transforms leading into the start time. /// The local drawable hierarchy is recursively delayed to for convenience. + /// + /// By default this will fade in the object from zero with no duration. /// /// /// This is called once before every . This is to ensure a good state in the case @@ -193,6 +196,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// protected virtual void UpdateInitialTransforms() { + this.FadeInFromZero(); } /// From cb8fe89b8bf9d82008db4853cbd6ba680a194de7 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 28 Aug 2019 13:09:53 +0300 Subject: [PATCH 485/645] Allow setting looping to existing channels --- osu.Game/Skinning/SkinnableSound.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index ac2cb16a6a..1491f2a989 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -35,7 +35,18 @@ namespace osu.Game.Skinning this.audio = audio; } - public bool Looping; + private bool looping; + + public bool Looping + { + get => looping; + set + { + looping = value; + + channels.ForEach(c => c.Looping = looping); + } + } public void Play() => channels?.ForEach(c => c.Play()); From 2f3fb8cf88823e906df851d9da5d5ca9c1eb3f9a Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 28 Aug 2019 13:10:11 +0300 Subject: [PATCH 486/645] Add Stop + RemoveAdjustment functions --- osu.Game/Skinning/SkinnableSound.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 1491f2a989..74804d5a06 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -49,8 +49,10 @@ namespace osu.Game.Skinning } public void Play() => channels?.ForEach(c => c.Play()); + public void Stop() => channels?.ForEach(c => c.Stop()); public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) => channels?.ForEach(c => c.AddAdjustment(type, adjustBindable)); + public void RemoveAdjustment(AdjustableProperty type, BindableDouble adjustBindable) => channels?.ForEach(c => c.RemoveAdjustment(type, adjustBindable)); public override bool IsPresent => Scheduler.HasPendingTasks; From 01aede3e299f53f0fd2c86f00a5c5087559ace88 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 19:57:17 +0900 Subject: [PATCH 487/645] Add comprehensive skin fallback integration testing --- .../TestSceneOsuPlayer.cs | 140 ++++++++++++++++++ .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 8 +- osu.Game/Skinning/SkinnableDrawable.cs | 2 +- osu.Game/Tests/Visual/PlayerTestScene.cs | 7 +- osu.Game/Tests/Visual/TestPlayer.cs | 3 + 6 files changed, 153 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs index 0a33b09ba8..7c84ae80c8 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs @@ -1,7 +1,23 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Timing; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Screens.Play; +using osu.Game.Skinning; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests @@ -9,9 +25,133 @@ namespace osu.Game.Rulesets.Osu.Tests [TestFixture] public class TestSceneOsuPlayer : PlayerTestScene { + private readonly TestSource testUserSkin; + private readonly TestSource testBeatmapSkin; + public TestSceneOsuPlayer() : base(new OsuRuleset()) { + testUserSkin = new TestSource("user"); + testBeatmapSkin = new TestSource("beatmap"); + } + + [Test] + public void TestBeatmapSkinDefault() + { + AddStep("enable user provider", () => testUserSkin.Enabled = true); + + AddStep("enable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, true)); + checkNextHitObject("beatmap"); + + AddStep("disable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, false)); + checkNextHitObject("user"); + + AddStep("disable user provider", () => testUserSkin.Enabled = false); + checkNextHitObject(null); + } + + private void checkNextHitObject(string skin) => + AddUntilStep($"check skin from {skin}", () => + { + var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.OfType().FirstOrDefault(); + + if (firstObject == null) + return false; + + var skinnable = firstObject?.ApproachCircle.Child as SkinnableDrawable; + + if (skin == null && skinnable?.Drawable is Sprite) + // check for default skin provider + return true; + + var text = skinnable?.Drawable as SpriteText; + + return text?.Text == skin; + }); + + [Resolved] + private AudioManager audio { get; set; } + + protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin); + + protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap) => new CustomSkinWorkingBeatmap(beatmap, Clock, audio, testBeatmapSkin); + + public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + { + private readonly ISkinSource skin; + + public CustomSkinWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) + : base(beatmap, frameBasedClock, audio) + { + this.skin = skin; + } + + protected override ISkin GetSkin() => skin; + } + + public class SkinProvidingPlayer : TestPlayer + { + private readonly TestSource userSkin; + + public SkinProvidingPlayer(TestSource userSkin) + { + this.userSkin = userSkin; + } + + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + + dependencies.CacheAs(userSkin); + + return dependencies; + } + } + + public class TestSource : ISkinSource + { + private readonly string identifier; + + public TestSource(string identifier) + { + this.identifier = identifier; + } + + public Drawable GetDrawableComponent(string componentName) + { + if (!enabled) return null; + + return new SpriteText + { + Text = identifier, + Font = OsuFont.Default.With(size: 30), + }; + } + + public Texture GetTexture(string componentName) => null; + + public SampleChannel GetSample(ISampleInfo sampleInfo) => null; + + public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => default; + + public event Action SourceChanged; + + private bool enabled = true; + + public bool Enabled + { + get => enabled; + set + { + if (value == enabled) + return; + + enabled = value; + SourceChanged?.Invoke(); + } + } } } } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 2d8a0b1249..5bbffc2f77 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -136,7 +136,7 @@ namespace osu.Game.Beatmaps return storyboard; } - protected override Skin GetSkin() + protected override ISkin GetSkin() { try { diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 8605caa5fe..9addcfbdd7 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -46,7 +46,7 @@ namespace osu.Game.Beatmaps background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); - skin = new RecyclableLazy(GetSkin); + skin = new RecyclableLazy(GetSkin); total_count.Value++; } @@ -214,10 +214,10 @@ namespace osu.Game.Beatmaps private readonly RecyclableLazy storyboard; public bool SkinLoaded => skin.IsResultAvailable; - public Skin Skin => skin.Value; + public ISkin Skin => skin.Value; - protected virtual Skin GetSkin() => new DefaultSkin(); - private readonly RecyclableLazy skin; + protected virtual ISkin GetSkin() => new DefaultSkin(); + private readonly RecyclableLazy skin; /// /// Transfer pieces of a beatmap to a new one, where possible, to save on loading. diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 0c635a3d2f..07f802944b 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -16,7 +16,7 @@ namespace osu.Game.Skinning /// /// The displayed component. /// - protected Drawable Drawable { get; private set; } + public Drawable Drawable { get; private set; } private readonly string componentName; diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 03e17a819c..1ab20ecd48 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -22,12 +22,13 @@ namespace osu.Game.Tests.Visual this.ruleset = ruleset; } + protected OsuConfigManager LocalConfig; + [BackgroundDependencyLoader] private void load() { - OsuConfigManager manager; - Dependencies.Cache(manager = new OsuConfigManager(LocalStorage)); - manager.GetBindable(OsuSetting.DimLevel).Value = 1.0; + Dependencies.Cache(LocalConfig = new OsuConfigManager(LocalStorage)); + LocalConfig.GetBindable(OsuSetting.DimLevel).Value = 1.0; } [SetUpSteps] diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs index b93a1466e0..31f6edadec 100644 --- a/osu.Game/Tests/Visual/TestPlayer.cs +++ b/osu.Game/Tests/Visual/TestPlayer.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 osu.Game.Rulesets.UI; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual @@ -9,6 +10,8 @@ namespace osu.Game.Tests.Visual { protected override bool PauseOnFocusLost => false; + public new DrawableRuleset DrawableRuleset => base.DrawableRuleset; + public TestPlayer(bool allowPause = true, bool showResults = true) : base(allowPause, showResults) { From c7e20b34bae62458749b973acb1e0cd54f1e8c7b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 20:15:28 +0900 Subject: [PATCH 488/645] Cleanup --- osu.Game/Utils/HumanizerUtils.cs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Utils/HumanizerUtils.cs b/osu.Game/Utils/HumanizerUtils.cs index 398c76a09f..5b7c3630d9 100644 --- a/osu.Game/Utils/HumanizerUtils.cs +++ b/osu.Game/Utils/HumanizerUtils.cs @@ -10,27 +10,21 @@ namespace osu.Game.Utils public static class HumanizerUtils { /// - /// Humanizes a string using the system culture, then falls back if one cannot be found. - /// - /// A localization lookup failure will throw an exception of type - /// + /// Turns the current or provided date into a human readable sentence /// - /// The time to humanize. - /// A humanized string of the given time. - public static string Humanize(DateTimeOffset dateTimeOffset) + /// The date to be humanized + /// distance of time in words + public static string Humanize(DateTimeOffset input) { - string offset; - + // this works around https://github.com/xamarin/xamarin-android/issues/2012 and https://github.com/Humanizr/Humanizer/issues/690#issuecomment-368536282 try { - offset = dateTimeOffset.Humanize(); + return input.Humanize(); } catch (ArgumentException) { - offset = dateTimeOffset.Humanize(culture: new CultureInfo("en-US")); + return input.Humanize(culture: new CultureInfo("en-US")); } - - return offset; } } } From 8b42890644d503b32e663e028bd711434b1969c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 20:19:19 +0900 Subject: [PATCH 489/645] Fix unnecessary null check --- osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs index 7c84ae80c8..d61378f4f8 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Tests if (firstObject == null) return false; - var skinnable = firstObject?.ApproachCircle.Child as SkinnableDrawable; + var skinnable = firstObject.ApproachCircle.Child as SkinnableDrawable; if (skin == null && skinnable?.Drawable is Sprite) // check for default skin provider From 348d88846da7d530b992a651512843d123f07bb7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 28 Aug 2019 20:19:22 +0900 Subject: [PATCH 490/645] Add IBeatmap interface for typed hitobject retrieval --- osu.Game/Beatmaps/Beatmap.cs | 12 ++++-------- osu.Game/Beatmaps/IBeatmap.cs | 9 +++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index a09a1bb9cb..5435e86dfd 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps /// /// A Beatmap containing converted HitObjects. /// - public class Beatmap : IBeatmap + public class Beatmap : IBeatmap where T : HitObject { public BeatmapInfo BeatmapInfo { get; set; } = new BeatmapInfo @@ -36,17 +36,13 @@ namespace osu.Game.Beatmaps public List Breaks { get; set; } = new List(); - /// - /// Total amount of break time in the beatmap. - /// [JsonIgnore] public double TotalBreakTime => Breaks.Sum(b => b.Duration); - /// - /// The HitObjects this Beatmap contains. - /// [JsonConverter(typeof(TypedListConverter))] - public List HitObjects = new List(); + public List HitObjects { get; set; } = new List(); + + IReadOnlyList IBeatmap.HitObjects => HitObjects; IReadOnlyList IBeatmap.HitObjects => HitObjects; diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 512fe25809..8f27e0b0e9 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -53,4 +53,13 @@ namespace osu.Game.Beatmaps /// The shallow-cloned beatmap. IBeatmap Clone(); } + + public interface IBeatmap : IBeatmap + where T : HitObject + { + /// + /// The hitobjects contained by this beatmap. + /// + new IReadOnlyList HitObjects { get; } + } } From f6ad95018adda03061931a74039c8a375ae887df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 20:22:16 +0900 Subject: [PATCH 491/645] Centralise default beat length specification --- osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs | 4 +++- .../Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs | 2 +- osu.Game/Rulesets/Timing/MultiplierControlPoint.cs | 2 +- osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs index e5815a3f3b..ccb8a92b3a 100644 --- a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs @@ -14,6 +14,8 @@ namespace osu.Game.Beatmaps.ControlPoints /// public TimeSignatures TimeSignature = TimeSignatures.SimpleQuadruple; + public const double DEFAULT_BEAT_LENGTH = 1000; + /// /// The beat length at this control point. /// @@ -23,7 +25,7 @@ namespace osu.Game.Beatmaps.ControlPoints set => beatLength = MathHelper.Clamp(value, 6, 60000); } - private double beatLength = 1000; + private double beatLength = DEFAULT_BEAT_LENGTH; public bool Equals(TimingControlPoint other) => base.Equals(other) diff --git a/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs index 540f616ea9..8775c15f17 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs @@ -31,7 +31,7 @@ namespace osu.Game.Beatmaps.Formats private class LegacyDifficultyCalculatorControlPoint : TimingControlPoint { - public override double BeatLength { get; set; } = 1000; + public override double BeatLength { get; set; } = TimingControlPoint.DEFAULT_BEAT_LENGTH; } } } diff --git a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs index ffa35c24cd..4b3c3f90f0 100644 --- a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs +++ b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Timing /// The base beat length to scale the provided multiplier relative to. /// /// For a of 1000, a with a beat length of 500 will increase the multiplier by 2. - public double BaseBeatLength = 1000; + public double BaseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH; /// /// The velocity multiplier. diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 65a22b10b7..c1a4c9520e 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.UI.Scrolling private void load() { double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue; - double baseBeatLength = 1000; + double baseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH; if (RelativeScaleBeatLengths) { From 3d6200338263bdaca6e39410bd52df1a0dab7e79 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 28 Aug 2019 15:39:45 +0300 Subject: [PATCH 492/645] Add null check --- osu.Game/Skinning/SkinnableSound.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 74804d5a06..cb511fc775 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -44,7 +44,7 @@ namespace osu.Game.Skinning { looping = value; - channels.ForEach(c => c.Looping = looping); + channels?.ForEach(c => c.Looping = looping); } } From c6e757fdae6c89b70927a26a83db61ed2cb8e572 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Aug 2019 22:11:23 +0900 Subject: [PATCH 493/645] Remove redundant qualifier --- .../Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs index 8775c15f17..2c493254e0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDifficultyCalculatorBeatmapDecoder.cs @@ -31,7 +31,7 @@ namespace osu.Game.Beatmaps.Formats private class LegacyDifficultyCalculatorControlPoint : TimingControlPoint { - public override double BeatLength { get; set; } = TimingControlPoint.DEFAULT_BEAT_LENGTH; + public override double BeatLength { get; set; } = DEFAULT_BEAT_LENGTH; } } } From 73fd3cf03ca93a0a73b9ae4d55e726d3e3c8089f Mon Sep 17 00:00:00 2001 From: Joehu Date: Wed, 28 Aug 2019 19:00:01 -0700 Subject: [PATCH 494/645] Fix gameplay menu button initial hover animation --- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index c7e762714c..f93d5d8b02 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -304,8 +304,6 @@ namespace osu.Game.Screens.Play private class Button : DialogButton { - protected override bool OnHover(HoverEvent e) => true; - protected override bool OnMouseMove(MouseMoveEvent e) { Selected.Value = true; From 03a4acaf4ca0071c9885e5176e67296bb7b68073 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 29 Aug 2019 12:07:58 +0900 Subject: [PATCH 495/645] Fix drags outside of overlay container bounds not hiding overlay --- .../Containers/OsuFocusedOverlayContainer.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 0f7b26835b..9c948d6f90 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -62,15 +62,23 @@ namespace osu.Game.Graphics.Containers protected override bool OnClick(ClickEvent e) { - if (!base.ReceivePositionalInputAt(e.ScreenSpaceMousePosition)) - { - Hide(); - return true; - } + closeIfOutside(e); return base.OnClick(e); } + protected override bool OnDragEnd(DragEndEvent e) + { + closeIfOutside(e); + return base.OnDragEnd(e); + } + + private void closeIfOutside(MouseEvent e) + { + if (!base.ReceivePositionalInputAt(e.ScreenSpaceMousePosition)) + Hide(); + } + public virtual bool OnPressed(GlobalAction action) { switch (action) From 6949c96aaa51952258a335de43b73fc0ba7a793f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 12:43:43 +0900 Subject: [PATCH 496/645] Add initial EditorBeatmap structure --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 14 ++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 79 +++++++++++++++++++++ osu.Game/Screens/Edit/IEditorBeatmap.cs | 17 +++++ 3 files changed, 110 insertions(+) create mode 100644 osu.Game/Screens/Edit/EditorBeatmap.cs create mode 100644 osu.Game/Screens/Edit/IEditorBeatmap.cs diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 38ec09535d..6d98f45187 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -18,6 +18,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Components.RadioButtons; using osu.Game.Screens.Edit.Compose.Components; @@ -185,6 +186,19 @@ namespace osu.Game.Rulesets.Edit { } + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var workingBeatmap = parent.Get>(); + var playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); + var editorBeatmap = new EditorBeatmap(playableBeatmap); + + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + dependencies.CacheAs(editorBeatmap); + dependencies.CacheAs(editorBeatmap); + + return dependencies; + } + internal override DrawableEditRuleset CreateDrawableRuleset() => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value, Array.Empty())); diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs new file mode 100644 index 0000000000..99dd441578 --- /dev/null +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -0,0 +1,79 @@ +// 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.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Screens.Edit +{ + public class EditorBeatmap : IBeatmap, IEditorBeatmap + where T : HitObject + { + public event Action HitObjectRemoved; + public event Action HitObjectAdded; + + event Action IEditorBeatmap.HitObjectAdded + { + add => HitObjectAdded += value; + remove => HitObjectAdded -= value; + } + + event Action IEditorBeatmap.HitObjectRemoved + { + add => HitObjectRemoved += value; + remove => HitObjectRemoved -= value; + } + + private readonly Beatmap beatmap; + + public EditorBeatmap(Beatmap beatmap) + { + this.beatmap = beatmap; + } + + public BeatmapInfo BeatmapInfo + { + get => beatmap.BeatmapInfo; + set => beatmap.BeatmapInfo = value; + } + + public BeatmapMetadata Metadata => beatmap.Metadata; + + public ControlPointInfo ControlPointInfo => beatmap.ControlPointInfo; + + public List Breaks => beatmap.Breaks; + + public double TotalBreakTime => beatmap.TotalBreakTime; + + IReadOnlyList IBeatmap.HitObjects => beatmap.HitObjects; + + IReadOnlyList IBeatmap.HitObjects => beatmap.HitObjects; + + public IEnumerable GetStatistics() => beatmap.GetStatistics(); + + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); + + public void Add(T hitObject) + { + // Preserve existing sorting order in the beatmap + var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime); + beatmap.HitObjects.Insert(insertionIndex + 1, hitObject); + + HitObjectAdded?.Invoke(hitObject); + } + + public void Remove(T hitObject) + { + if (beatmap.HitObjects.Remove(hitObject)) + HitObjectRemoved?.Invoke(hitObject); + } + + public void Add(HitObject hitObject) => Add((T)hitObject); + + public void Remove(HitObject hitObject) => Remove((T)hitObject); + } +} diff --git a/osu.Game/Screens/Edit/IEditorBeatmap.cs b/osu.Game/Screens/Edit/IEditorBeatmap.cs new file mode 100644 index 0000000000..602a096d65 --- /dev/null +++ b/osu.Game/Screens/Edit/IEditorBeatmap.cs @@ -0,0 +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 System; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Screens.Edit +{ + public interface IEditorBeatmap + { + event Action HitObjectAdded; + event Action HitObjectRemoved; + + void Add(HitObject hitObject); + void Remove(HitObject hitObject); + } +} From 840f2246199d7818dc29771de2dd81628f689294 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 16:05:44 +0900 Subject: [PATCH 497/645] Remove typed events to reduce complexity --- osu.Game/Screens/Edit/EditorBeatmap.cs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 99dd441578..d9f17abfa5 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -13,20 +13,8 @@ namespace osu.Game.Screens.Edit public class EditorBeatmap : IBeatmap, IEditorBeatmap where T : HitObject { - public event Action HitObjectRemoved; - public event Action HitObjectAdded; - - event Action IEditorBeatmap.HitObjectAdded - { - add => HitObjectAdded += value; - remove => HitObjectAdded -= value; - } - - event Action IEditorBeatmap.HitObjectRemoved - { - add => HitObjectRemoved += value; - remove => HitObjectRemoved -= value; - } + public event Action HitObjectAdded; + public event Action HitObjectRemoved; private readonly Beatmap beatmap; From 7927b684d3c0ace143ae033f20b944c37c9f1f41 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 16:06:40 +0900 Subject: [PATCH 498/645] Hook up + use editor beatmap --- .../Editor/TestSceneHitObjectComposer.cs | 16 +--- osu.Game/Rulesets/Edit/DrawableEditRuleset.cs | 63 ++++----------- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 66 ++++++++++++---- .../Compose/Components/BlueprintContainer.cs | 76 +++++++++++++------ .../Screens/Edit/Compose/ComposeScreen.cs | 12 +-- 5 files changed, 118 insertions(+), 115 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs index 7accbe2fa8..0ea73fb3de 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs @@ -16,15 +16,13 @@ using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; using osuTK; namespace osu.Game.Tests.Visual.Editor { [TestFixture] - [Cached(Type = typeof(IPlacementHandler))] - public class TestSceneHitObjectComposer : OsuTestScene, IPlacementHandler + public class TestSceneHitObjectComposer : OsuTestScene { public override IReadOnlyList RequiredTypes => new[] { @@ -39,8 +37,6 @@ namespace osu.Game.Tests.Visual.Editor typeof(HitCirclePlacementBlueprint), }; - private HitObjectComposer composer; - [BackgroundDependencyLoader] private void load() { @@ -67,15 +63,7 @@ namespace osu.Game.Tests.Visual.Editor Dependencies.CacheAs(clock); Dependencies.CacheAs(clock); - Child = composer = new OsuHitObjectComposer(new OsuRuleset()); + Child = new OsuHitObjectComposer(new OsuRuleset()); } - - public void BeginPlacement(HitObject hitObject) - { - } - - public void EndPlacement(HitObject hitObject) => composer.Add(hitObject); - - public void Delete(HitObject hitObject) => composer.Remove(hitObject); } } diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs index e85ebb5f3a..c9d7b2cd81 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs @@ -5,10 +5,9 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit; namespace osu.Game.Rulesets.Edit { @@ -25,20 +24,6 @@ namespace osu.Game.Rulesets.Edit { RelativeSizeAxes = Axes.Both; } - - /// - /// Adds a to the and displays a visual representation of it. - /// - /// The to add. - /// The visual representation of . - internal abstract DrawableHitObject Add(HitObject hitObject); - - /// - /// Removes a from the and the display. - /// - /// The to remove. - /// The visual representation of the removed . - internal abstract DrawableHitObject Remove(HitObject hitObject); } public class DrawableEditRuleset : DrawableEditRuleset @@ -48,11 +33,11 @@ namespace osu.Game.Rulesets.Edit public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => drawableRuleset.CreatePlayfieldAdjustmentContainer(); - private Ruleset ruleset => drawableRuleset.Ruleset; - private Beatmap beatmap => drawableRuleset.Beatmap; - private readonly DrawableRuleset drawableRuleset; + [Resolved] + private EditorBeatmap beatmap { get; set; } + public DrawableEditRuleset(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; @@ -67,50 +52,28 @@ namespace osu.Game.Rulesets.Edit Playfield.DisplayJudgements.Value = false; } - internal override DrawableHitObject Add(HitObject hitObject) + protected override void LoadComplete() { - var tObject = (TObject)hitObject; + base.LoadComplete(); - // Add to beatmap, preserving sorting order - var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime); - beatmap.HitObjects.Insert(insertionIndex + 1, tObject); + beatmap.HitObjectAdded += addHitObject; + beatmap.HitObjectRemoved += removeHitObject; + } - // Process object - var processor = ruleset.CreateBeatmapProcessor(beatmap); - - processor?.PreProcess(); - tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty); - processor?.PostProcess(); - - // Add visual representation - var drawableObject = drawableRuleset.CreateDrawableRepresentation(tObject); + private void addHitObject(HitObject hitObject) + { + var drawableObject = drawableRuleset.CreateDrawableRepresentation((TObject)hitObject); drawableRuleset.Playfield.Add(drawableObject); drawableRuleset.Playfield.PostProcess(); - - return drawableObject; } - internal override DrawableHitObject Remove(HitObject hitObject) + private void removeHitObject(HitObject hitObject) { - var tObject = (TObject)hitObject; - - // Remove from beatmap - beatmap.HitObjects.Remove(tObject); - - // Process the beatmap - var processor = ruleset.CreateBeatmapProcessor(beatmap); - - processor?.PreProcess(); - processor?.PostProcess(); - - // Remove visual representation var drawableObject = Playfield.AllHitObjects.Single(d => d.HitObject == hitObject); drawableRuleset.Playfield.Remove(drawableObject); drawableRuleset.Playfield.PostProcess(); - - return drawableObject; } } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 6d98f45187..fe81f6747d 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -20,6 +20,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Components.RadioButtons; +using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Edit @@ -154,14 +155,6 @@ namespace osu.Game.Rulesets.Edit /// public virtual bool CursorInPlacementArea => DrawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); - /// - /// Adds a to the and visualises it. - /// - /// The to add. - public void Add(HitObject hitObject) => blueprintContainer.AddBlueprintFor(DrawableRuleset.Add(hitObject)); - - public void Remove(HitObject hitObject) => blueprintContainer.RemoveBlueprintFor(DrawableRuleset.Remove(hitObject)); - internal abstract DrawableEditRuleset CreateDrawableRuleset(); protected abstract IReadOnlyList CompositionTools { get; } @@ -178,9 +171,16 @@ namespace osu.Game.Rulesets.Edit public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); } - public abstract class HitObjectComposer : HitObjectComposer + [Cached(Type = typeof(IPlacementHandler))] + public abstract class HitObjectComposer : HitObjectComposer, IPlacementHandler where TObject : HitObject { + private Beatmap playableBeatmap; + + [Cached] + [Cached(typeof(IEditorBeatmap))] + private EditorBeatmap editorBeatmap; + protected HitObjectComposer(Ruleset ruleset) : base(ruleset) { @@ -189,19 +189,55 @@ namespace osu.Game.Rulesets.Edit protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { var workingBeatmap = parent.Get>(); - var playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); - var editorBeatmap = new EditorBeatmap(playableBeatmap); + playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(editorBeatmap); - dependencies.CacheAs(editorBeatmap); + editorBeatmap = new EditorBeatmap(playableBeatmap); + editorBeatmap.HitObjectAdded += addHitObject; + editorBeatmap.HitObjectRemoved += removeHitObject; - return dependencies; + return base.CreateChildDependencies(parent); + } + + private void addHitObject(HitObject hitObject) + { + // Process object + var processor = Ruleset.CreateBeatmapProcessor(playableBeatmap); + + processor?.PreProcess(); + hitObject.ApplyDefaults(playableBeatmap.ControlPointInfo, playableBeatmap.BeatmapInfo.BaseDifficulty); + processor?.PostProcess(); + } + + private void removeHitObject(HitObject hitObject) + { + var processor = Ruleset.CreateBeatmapProcessor(playableBeatmap); + + processor?.PreProcess(); + processor?.PostProcess(); } internal override DrawableEditRuleset CreateDrawableRuleset() => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value, Array.Empty())); protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods); + + public void BeginPlacement(HitObject hitObject) + { + } + + public void EndPlacement(HitObject hitObject) => editorBeatmap.Add(hitObject); + + public void Delete(HitObject hitObject) => editorBeatmap.Remove(hitObject); + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (editorBeatmap != null) + { + editorBeatmap.HitObjectAdded -= addHitObject; + editorBeatmap.HitObjectRemoved -= removeHitObject; + } + } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index a1e62cd38b..7d25fd5283 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -11,6 +11,7 @@ using osu.Framework.Input.Events; using osu.Framework.Input.States; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Screens.Edit.Compose.Components @@ -29,6 +30,9 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private HitObjectComposer composer { get; set; } + [Resolved] + private IEditorBeatmap beatmap { get; set; } + public BlueprintContainer() { RelativeSizeAxes = Axes.Both; @@ -53,7 +57,15 @@ namespace osu.Game.Screens.Edit.Compose.Components }; foreach (var obj in composer.HitObjects) - AddBlueprintFor(obj); + addBlueprintFor(obj); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + beatmap.HitObjectAdded += addBlueprintFor; + beatmap.HitObjectRemoved += removeBlueprintFor; } private HitObjectCompositionTool currentTool; @@ -75,11 +87,32 @@ namespace osu.Game.Screens.Edit.Compose.Components } } - /// - /// Adds a blueprint for a which adds movement support. - /// - /// The to create a blueprint for. - public void AddBlueprintFor(DrawableHitObject hitObject) + private void addBlueprintFor(HitObject hitObject) + { + var drawable = composer.HitObjects.FirstOrDefault(d => d.HitObject == hitObject); + if (drawable == null) + return; + + addBlueprintFor(drawable); + } + + private void removeBlueprintFor(HitObject hitObject) + { + var blueprint = selectionBlueprints.Single(m => m.HitObject.HitObject == hitObject); + if (blueprint == null) + return; + + blueprint.Deselect(); + + blueprint.Selected -= onBlueprintSelected; + blueprint.Deselected -= onBlueprintDeselected; + blueprint.SelectionRequested -= onSelectionRequested; + blueprint.DragRequested -= onDragRequested; + + selectionBlueprints.Remove(blueprint); + } + + private void addBlueprintFor(DrawableHitObject hitObject) { refreshTool(); @@ -95,25 +128,7 @@ namespace osu.Game.Screens.Edit.Compose.Components selectionBlueprints.Add(blueprint); } - /// - /// Removes a blueprint for a . - /// - /// The for which to remove the blueprint. - public void RemoveBlueprintFor(DrawableHitObject hitObject) - { - var blueprint = selectionBlueprints.Single(m => m.HitObject == hitObject); - if (blueprint == null) - return; - - blueprint.Deselect(); - - blueprint.Selected -= onBlueprintSelected; - blueprint.Deselected -= onBlueprintDeselected; - blueprint.SelectionRequested -= onSelectionRequested; - blueprint.DragRequested -= onDragRequested; - - selectionBlueprints.Remove(blueprint); - } + private void removeBlueprintFor(DrawableHitObject hitObject) => removeBlueprintFor(hitObject.HitObject); protected override bool OnClick(ClickEvent e) { @@ -183,6 +198,17 @@ namespace osu.Game.Screens.Edit.Compose.Components private void onDragRequested(SelectionBlueprint blueprint, DragEvent dragEvent) => selectionHandler.HandleDrag(blueprint, dragEvent); + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (beatmap != null) + { + beatmap.HitObjectAdded -= addBlueprintFor; + beatmap.HitObjectRemoved -= removeBlueprintFor; + } + } + private class SelectionBlueprintContainer : Container { protected override int Compare(Drawable x, Drawable y) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 5699ef0a84..ec4dda5c23 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -9,15 +9,13 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Logging; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components.Timeline; using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose { - [Cached(Type = typeof(IPlacementHandler))] - public class ComposeScreen : EditorScreen, IPlacementHandler + public class ComposeScreen : EditorScreen { private const float vertical_margins = 10; private const float horizontal_margins = 20; @@ -119,13 +117,5 @@ namespace osu.Game.Screens.Edit.Compose composerContainer.Child = composer; } - - public void BeginPlacement(HitObject hitObject) - { - } - - public void EndPlacement(HitObject hitObject) => composer.Add(hitObject); - - public void Delete(HitObject hitObject) => composer.Remove(hitObject); } } From 5db813b7a411b94d61676cb325e883f929861755 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 16:26:39 +0900 Subject: [PATCH 499/645] Add secondary interface for further abstraction --- osu.Game/Rulesets/Edit/DrawableEditRuleset.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 9 ++++--- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 +- osu.Game/Screens/Edit/IEditorBeatmap.cs | 27 ++++++++++++++++--- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs index c9d7b2cd81..95a1492a45 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Edit private readonly DrawableRuleset drawableRuleset; [Resolved] - private EditorBeatmap beatmap { get; set; } + private IEditorBeatmap beatmap { get; set; } public DrawableEditRuleset(DrawableRuleset drawableRuleset) { diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index fe81f6747d..fb7021bfa8 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -176,9 +176,6 @@ namespace osu.Game.Rulesets.Edit where TObject : HitObject { private Beatmap playableBeatmap; - - [Cached] - [Cached(typeof(IEditorBeatmap))] private EditorBeatmap editorBeatmap; protected HitObjectComposer(Ruleset ruleset) @@ -195,7 +192,11 @@ namespace osu.Game.Rulesets.Edit editorBeatmap.HitObjectAdded += addHitObject; editorBeatmap.HitObjectRemoved += removeHitObject; - return base.CreateChildDependencies(parent); + var dependencies = new DependencyContainer(parent); + dependencies.CacheAs(editorBeatmap); + dependencies.CacheAs>(editorBeatmap); + + return base.CreateChildDependencies(dependencies); } private void addHitObject(HitObject hitObject) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index d9f17abfa5..2261f6f45c 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Edit { - public class EditorBeatmap : IBeatmap, IEditorBeatmap + public class EditorBeatmap : IEditorBeatmap where T : HitObject { public event Action HitObjectAdded; diff --git a/osu.Game/Screens/Edit/IEditorBeatmap.cs b/osu.Game/Screens/Edit/IEditorBeatmap.cs index 602a096d65..2f250ba446 100644 --- a/osu.Game/Screens/Edit/IEditorBeatmap.cs +++ b/osu.Game/Screens/Edit/IEditorBeatmap.cs @@ -2,16 +2,35 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Edit { - public interface IEditorBeatmap + /// + /// Interface for the contained by the see . + /// Children of may resolve the beatmap via or . + /// + public interface IEditorBeatmap : IBeatmap { + /// + /// Invoked when a is added to this . + /// event Action HitObjectAdded; - event Action HitObjectRemoved; - void Add(HitObject hitObject); - void Remove(HitObject hitObject); + /// + /// Invoked when a is removed from this . + /// + event Action HitObjectRemoved; + } + + /// + /// Interface for the contained by the see . + /// Children of may resolve the beatmap via or . + /// + public interface IEditorBeatmap : IEditorBeatmap, IBeatmap + where T : HitObject + { } } From dad0fa2dca16f672569e1a59bf4d16c54456346b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 16:31:40 +0900 Subject: [PATCH 500/645] Bind disposal --- osu.Game/Rulesets/Edit/DrawableEditRuleset.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs index 95a1492a45..a12e4ba3ab 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs @@ -75,5 +75,16 @@ namespace osu.Game.Rulesets.Edit drawableRuleset.Playfield.Remove(drawableObject); drawableRuleset.Playfield.PostProcess(); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (beatmap != null) + { + beatmap.HitObjectAdded -= addHitObject; + beatmap.HitObjectRemoved -= removeHitObject; + } + } } } From b04a8ae8560e467ca8f3172e0261b9f3f4b05591 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 16:31:43 +0900 Subject: [PATCH 501/645] Add xmldocs --- osu.Game/Screens/Edit/EditorBeatmap.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 2261f6f45c..f0b6c62154 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -45,6 +45,10 @@ namespace osu.Game.Screens.Edit public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); + /// + /// Adds a to this . + /// + /// The to add. public void Add(T hitObject) { // Preserve existing sorting order in the beatmap @@ -54,14 +58,26 @@ namespace osu.Game.Screens.Edit HitObjectAdded?.Invoke(hitObject); } + /// + /// Removes a from this . + /// + /// The to add. public void Remove(T hitObject) { if (beatmap.HitObjects.Remove(hitObject)) HitObjectRemoved?.Invoke(hitObject); } + /// + /// Adds a to this . + /// + /// The to add. public void Add(HitObject hitObject) => Add((T)hitObject); + /// + /// Removes a from this . + /// + /// The to add. public void Remove(HitObject hitObject) => Remove((T)hitObject); } } From 40c1c6072ed587b0f9f3c8ec6d720117788fd62b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 29 Aug 2019 16:38:39 +0900 Subject: [PATCH 502/645] Add "osu!classic" as a bundled skin choice --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/OsuGame.cs | 21 +++++++++++++++++++- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Skinning/DefaultLegacySkin.cs | 23 ++++++++++++++++++++++ osu.Game/Skinning/LegacySkin.cs | 3 +++ osu.Game/Skinning/SkinInfo.cs | 6 +++++- osu.Game/Skinning/SkinManager.cs | 18 +++++++++++++++-- 7 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Skinning/DefaultLegacySkin.cs diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b13e115387..fb472f3f89 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -18,7 +18,7 @@ namespace osu.Game.Configuration { // UI/selection defaults Set(OsuSetting.Ruleset, 0, 0, int.MaxValue); - Set(OsuSetting.Skin, 0, 0, int.MaxValue); + Set(OsuSetting.Skin, 0, -1, int.MaxValue); Set(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Details); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0e804ecbaf..8fa8ffaf9b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -182,7 +182,26 @@ namespace osu.Game // bind config int to database SkinInfo configSkin = LocalConfig.GetBindable(OsuSetting.Skin); SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID; - configSkin.ValueChanged += skinId => SkinManager.CurrentSkinInfo.Value = SkinManager.Query(s => s.ID == skinId.NewValue) ?? SkinInfo.Default; + configSkin.ValueChanged += skinId => + { + var skinInfo = SkinManager.Query(s => s.ID == skinId.NewValue); + + if (skinInfo == null) + { + switch (skinId.NewValue) + { + case -1: + skinInfo = DefaultLegacySkin.Info; + break; + + default: + skinInfo = SkinInfo.Default; + break; + } + } + + SkinManager.CurrentSkinInfo.Value = skinInfo; + }; configSkin.TriggerChange(); IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 076c9ada78..de8f316b06 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -158,7 +158,7 @@ namespace osu.Game runMigrations(); - dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host, Audio)); + dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host, Audio, new NamespacedResourceStore(Resources, "Skins/Legacy"))); dependencies.CacheAs(SkinManager); API = new APIAccess(LocalConfig); diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs new file mode 100644 index 0000000000..b35c9c7b97 --- /dev/null +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -0,0 +1,23 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Audio; +using osu.Framework.IO.Stores; + +namespace osu.Game.Skinning +{ + public class DefaultLegacySkin : LegacySkin + { + public DefaultLegacySkin(IResourceStore storage, AudioManager audioManager) + : base(Info, storage, audioManager, string.Empty) + { + } + + public static SkinInfo Info { get; } = new SkinInfo + { + ID = -1, // this is temporary until database storage is decided upon. + Name = "osu!classic", + Creator = "team osu!" + }; + } +} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 570ba1ced7..0cc5e9c9b6 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -248,6 +248,9 @@ namespace osu.Game.Skinning private string getPathForFile(string filename) { + if (source.Files == null) + return null; + bool hasExtension = filename.Contains('.'); var file = source.Files.Find(f => diff --git a/osu.Game/Skinning/SkinInfo.cs b/osu.Game/Skinning/SkinInfo.cs index 187ea910a7..6b9627188e 100644 --- a/osu.Game/Skinning/SkinInfo.cs +++ b/osu.Game/Skinning/SkinInfo.cs @@ -26,7 +26,11 @@ namespace osu.Game.Skinning public string FullName => $"\"{Name}\" by {Creator}"; - public static SkinInfo Default { get; } = new SkinInfo { Name = "osu!lazer", Creator = "team osu!" }; + public static SkinInfo Default { get; } = new SkinInfo + { + Name = "osu!lazer", + Creator = "team osu!" + }; public bool Equals(SkinInfo other) => other != null && ID == other.ID; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index e747a8b1ce..0e40eb5376 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -14,6 +14,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; +using osu.Framework.IO.Stores; using osu.Framework.Platform; using osu.Game.Audio; using osu.Game.Database; @@ -25,6 +26,8 @@ namespace osu.Game.Skinning { private readonly AudioManager audio; + private readonly IResourceStore legacyDefaultResources; + public readonly Bindable CurrentSkin = new Bindable(new DefaultSkin()); public readonly Bindable CurrentSkinInfo = new Bindable(SkinInfo.Default) { Default = SkinInfo.Default }; @@ -34,10 +37,11 @@ namespace osu.Game.Skinning protected override string ImportFromStablePath => "Skins"; - public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost, AudioManager audio) + public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost, AudioManager audio, IResourceStore legacyDefaultResources) : base(storage, contextFactory, new SkinStore(contextFactory, storage), importHost) { this.audio = audio; + this.legacyDefaultResources = legacyDefaultResources; ItemRemoved += removedInfo => { @@ -56,6 +60,9 @@ namespace osu.Game.Skinning }; } + private Skin createIfNotExisting(SkinInfo skinInfo) => + GetSkin(Query(s => s.Name == skinInfo.Name) ?? Import(skinInfo).Result); + protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osk"; /// @@ -66,6 +73,7 @@ namespace osu.Game.Skinning { var userSkins = GetAllUserSkins(); userSkins.Insert(0, SkinInfo.Default); + userSkins.Insert(1, DefaultLegacySkin.Info); return userSkins; } @@ -91,7 +99,7 @@ namespace osu.Game.Skinning else { model.Name = model.Name.Replace(".osk", ""); - model.Creator = "Unknown"; + model.Creator = model.Creator ?? "Unknown"; } } @@ -102,9 +110,15 @@ namespace osu.Game.Skinning /// A instance correlating to the provided . public Skin GetSkin(SkinInfo skinInfo) { + if (skinInfo == null) + return null; + if (skinInfo == SkinInfo.Default) return new DefaultSkin(); + if (skinInfo == DefaultLegacySkin.Info) + return new DefaultLegacySkin(legacyDefaultResources, audio); + return new LegacySkin(skinInfo, Files.Store, audio); } From b40143cb73d8d5b8a0eaf8605b81b40ee30c05e7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 17:18:34 +0900 Subject: [PATCH 503/645] Remove unnecessary comment --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index fb7021bfa8..d5a0e052a5 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -201,7 +201,6 @@ namespace osu.Game.Rulesets.Edit private void addHitObject(HitObject hitObject) { - // Process object var processor = Ruleset.CreateBeatmapProcessor(playableBeatmap); processor?.PreProcess(); From 0fbdcabb6faa374e20fd43f1a762c839b73d4ced Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 17:21:52 +0900 Subject: [PATCH 504/645] Re-use a single beatmap processor --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index d5a0e052a5..ed2ef5d9f8 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -177,6 +177,7 @@ namespace osu.Game.Rulesets.Edit { private Beatmap playableBeatmap; private EditorBeatmap editorBeatmap; + private IBeatmapProcessor beatmapProcessor; protected HitObjectComposer(Ruleset ruleset) : base(ruleset) @@ -188,6 +189,8 @@ namespace osu.Game.Rulesets.Edit var workingBeatmap = parent.Get>(); playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); + beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap); + editorBeatmap = new EditorBeatmap(playableBeatmap); editorBeatmap.HitObjectAdded += addHitObject; editorBeatmap.HitObjectRemoved += removeHitObject; @@ -201,19 +204,15 @@ namespace osu.Game.Rulesets.Edit private void addHitObject(HitObject hitObject) { - var processor = Ruleset.CreateBeatmapProcessor(playableBeatmap); - - processor?.PreProcess(); + beatmapProcessor?.PreProcess(); hitObject.ApplyDefaults(playableBeatmap.ControlPointInfo, playableBeatmap.BeatmapInfo.BaseDifficulty); - processor?.PostProcess(); + beatmapProcessor?.PostProcess(); } private void removeHitObject(HitObject hitObject) { - var processor = Ruleset.CreateBeatmapProcessor(playableBeatmap); - - processor?.PreProcess(); - processor?.PostProcess(); + beatmapProcessor?.PreProcess(); + beatmapProcessor?.PostProcess(); } internal override DrawableEditRuleset CreateDrawableRuleset() From 59296d12f3af1e2d107c0b0c3206e47cd1feab08 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 18:02:50 +0900 Subject: [PATCH 505/645] Refactor HitObjectComposer --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 150 +++++++++----------- 1 file changed, 70 insertions(+), 80 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index ed2ef5d9f8..239ec572b2 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -25,40 +25,40 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Edit { - public abstract class HitObjectComposer : CompositeDrawable + [Cached(Type = typeof(IPlacementHandler))] + public abstract class HitObjectComposer : HitObjectComposer, IPlacementHandler + where TObject : HitObject { - public IEnumerable HitObjects => DrawableRuleset.Playfield.AllHitObjects; + protected IRulesetConfigManager Config { get; private set; } + protected DrawableEditRuleset DrawableRuleset { get; private set; } protected readonly Ruleset Ruleset; - protected readonly IBindable Beatmap = new Bindable(); - - protected IRulesetConfigManager Config { get; private set; } - - private readonly List layerContainers = new List(); - - protected DrawableEditRuleset DrawableRuleset { get; private set; } + private IBindable workingBeatmap; + private Beatmap playableBeatmap; + private EditorBeatmap editorBeatmap; + private IBeatmapProcessor beatmapProcessor; private BlueprintContainer blueprintContainer; + private readonly List layerContainers = new List(); private InputManager inputManager; - internal HitObjectComposer(Ruleset ruleset) + protected HitObjectComposer(Ruleset ruleset) { Ruleset = ruleset; - RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] - private void load(IBindable beatmap, IFrameBasedClock framedClock) + private void load(IFrameBasedClock framedClock) { - Beatmap.BindTo(beatmap); - try { - DrawableRuleset = CreateDrawableRuleset(); - DrawableRuleset.Clock = framedClock; + DrawableRuleset = new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, workingBeatmap.Value, Array.Empty())) + { + Clock = framedClock + }; } catch (Exception e) { @@ -120,6 +120,26 @@ namespace osu.Game.Rulesets.Edit toolboxCollection.Items[0].Select(); } + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + workingBeatmap = parent.Get>().GetBoundCopy(); + playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); + + beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap); + + editorBeatmap = new EditorBeatmap(playableBeatmap); + editorBeatmap.HitObjectAdded += addHitObject; + editorBeatmap.HitObjectRemoved += removeHitObject; + + var dependencies = new DependencyContainer(parent); + dependencies.CacheAs(editorBeatmap); + dependencies.CacheAs>(editorBeatmap); + + Config = dependencies.Get().GetConfigFor(Ruleset); + + return base.CreateChildDependencies(dependencies); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -127,16 +147,6 @@ namespace osu.Game.Rulesets.Edit inputManager = GetContainingInputManager(); } - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - - dependencies.CacheAs(this); - Config = dependencies.Get().GetConfigFor(Ruleset); - - return dependencies; - } - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -150,58 +160,6 @@ namespace osu.Game.Rulesets.Edit }); } - /// - /// Whether the user's cursor is currently in an area of the that is valid for placement. - /// - public virtual bool CursorInPlacementArea => DrawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); - - internal abstract DrawableEditRuleset CreateDrawableRuleset(); - - protected abstract IReadOnlyList CompositionTools { get; } - - /// - /// Creates a for a specific . - /// - /// The to create the overlay for. - public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; - - /// - /// Creates a which outlines s and handles movement of selections. - /// - public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); - } - - [Cached(Type = typeof(IPlacementHandler))] - public abstract class HitObjectComposer : HitObjectComposer, IPlacementHandler - where TObject : HitObject - { - private Beatmap playableBeatmap; - private EditorBeatmap editorBeatmap; - private IBeatmapProcessor beatmapProcessor; - - protected HitObjectComposer(Ruleset ruleset) - : base(ruleset) - { - } - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var workingBeatmap = parent.Get>(); - playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); - - beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap); - - editorBeatmap = new EditorBeatmap(playableBeatmap); - editorBeatmap.HitObjectAdded += addHitObject; - editorBeatmap.HitObjectRemoved += removeHitObject; - - var dependencies = new DependencyContainer(parent); - dependencies.CacheAs(editorBeatmap); - dependencies.CacheAs>(editorBeatmap); - - return base.CreateChildDependencies(dependencies); - } - private void addHitObject(HitObject hitObject) { beatmapProcessor?.PreProcess(); @@ -215,8 +173,10 @@ namespace osu.Game.Rulesets.Edit beatmapProcessor?.PostProcess(); } - internal override DrawableEditRuleset CreateDrawableRuleset() - => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value, Array.Empty())); + public override IEnumerable HitObjects => DrawableRuleset.Playfield.AllHitObjects; + public override bool CursorInPlacementArea => DrawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); + + protected abstract IReadOnlyList CompositionTools { get; } protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods); @@ -239,4 +199,34 @@ namespace osu.Game.Rulesets.Edit } } } + + [Cached(typeof(HitObjectComposer))] + public abstract class HitObjectComposer : CompositeDrawable + { + internal HitObjectComposer() + { + RelativeSizeAxes = Axes.Both; + } + + /// + /// All the s. + /// + public abstract IEnumerable HitObjects { get; } + + /// + /// Whether the user's cursor is currently in an area of the that is valid for placement. + /// + public abstract bool CursorInPlacementArea { get; } + + /// + /// Creates a for a specific . + /// + /// The to create the overlay for. + public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; + + /// + /// Creates a which outlines s and handles movement of selections. + /// + public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); + } } From 87e28ab1f97869de9fef85deac8ec2be1072f0e0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 18:12:29 +0900 Subject: [PATCH 506/645] Remove non-generic DrawableEditRuleset --- .../Edit/ManiaHitObjectComposer.cs | 12 ++++----- osu.Game/Rulesets/Edit/DrawableEditRuleset.cs | 25 +++++-------------- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 22 ++++++++-------- 3 files changed, 23 insertions(+), 36 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 2729621ab3..3a28149946 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Edit [Cached(Type = typeof(IManiaHitObjectComposer))] public class ManiaHitObjectComposer : HitObjectComposer, IManiaHitObjectComposer { - protected new DrawableManiaEditRuleset DrawableRuleset { get; private set; } + private DrawableManiaEditRuleset drawableRuleset; public ManiaHitObjectComposer(Ruleset ruleset) : base(ruleset) @@ -33,23 +33,23 @@ namespace osu.Game.Rulesets.Mania.Edit /// /// The screen-space position. /// The column which intersects with . - public Column ColumnAt(Vector2 screenSpacePosition) => DrawableRuleset.GetColumnByPosition(screenSpacePosition); + public Column ColumnAt(Vector2 screenSpacePosition) => drawableRuleset.GetColumnByPosition(screenSpacePosition); private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns; + public int TotalColumns => ((ManiaPlayfield)drawableRuleset.Playfield).TotalColumns; protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) { - DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods); + drawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods); // This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it - dependencies.CacheAs(DrawableRuleset.ScrollingInfo); + dependencies.CacheAs(drawableRuleset.ScrollingInfo); - return DrawableRuleset; + return drawableRuleset; } protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs index a12e4ba3ab..a9f0dd4197 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs @@ -11,27 +11,10 @@ using osu.Game.Screens.Edit; namespace osu.Game.Rulesets.Edit { - public abstract class DrawableEditRuleset : CompositeDrawable - { - /// - /// The contained by this . - /// - public abstract Playfield Playfield { get; } - - public abstract PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer(); - - internal DrawableEditRuleset() - { - RelativeSizeAxes = Axes.Both; - } - } - - public class DrawableEditRuleset : DrawableEditRuleset + public class DrawableEditRuleset : CompositeDrawable where TObject : HitObject { - public override Playfield Playfield => drawableRuleset.Playfield; - - public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => drawableRuleset.CreatePlayfieldAdjustmentContainer(); + public Playfield Playfield => drawableRuleset.Playfield; private readonly DrawableRuleset drawableRuleset; @@ -42,6 +25,8 @@ namespace osu.Game.Rulesets.Edit { this.drawableRuleset = drawableRuleset; + RelativeSizeAxes = Axes.Both; + InternalChild = drawableRuleset; } @@ -76,6 +61,8 @@ namespace osu.Game.Rulesets.Edit drawableRuleset.Playfield.PostProcess(); } + public PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => drawableRuleset.CreatePlayfieldAdjustmentContainer(); + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 239ec572b2..35c5a63ef1 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -30,7 +30,6 @@ namespace osu.Game.Rulesets.Edit where TObject : HitObject { protected IRulesetConfigManager Config { get; private set; } - protected DrawableEditRuleset DrawableRuleset { get; private set; } protected readonly Ruleset Ruleset; @@ -39,6 +38,7 @@ namespace osu.Game.Rulesets.Edit private EditorBeatmap editorBeatmap; private IBeatmapProcessor beatmapProcessor; + private DrawableEditRuleset drawableRuleset; private BlueprintContainer blueprintContainer; private readonly List layerContainers = new List(); @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Edit { try { - DrawableRuleset = new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, workingBeatmap.Value, Array.Empty())) + drawableRuleset = new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, workingBeatmap.Value, Array.Empty())) { Clock = framedClock }; @@ -66,10 +66,10 @@ namespace osu.Game.Rulesets.Edit return; } - var layerBelowRuleset = DrawableRuleset.CreatePlayfieldAdjustmentContainer(); + var layerBelowRuleset = drawableRuleset.CreatePlayfieldAdjustmentContainer(); layerBelowRuleset.Child = new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }; - var layerAboveRuleset = DrawableRuleset.CreatePlayfieldAdjustmentContainer(); + var layerAboveRuleset = drawableRuleset.CreatePlayfieldAdjustmentContainer(); layerAboveRuleset.Child = blueprintContainer = new BlueprintContainer(); layerContainers.Add(layerBelowRuleset); @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Edit Children = new Drawable[] { layerBelowRuleset, - DrawableRuleset, + drawableRuleset, layerAboveRuleset } } @@ -153,10 +153,10 @@ namespace osu.Game.Rulesets.Edit layerContainers.ForEach(l => { - l.Anchor = DrawableRuleset.Playfield.Anchor; - l.Origin = DrawableRuleset.Playfield.Origin; - l.Position = DrawableRuleset.Playfield.Position; - l.Size = DrawableRuleset.Playfield.Size; + l.Anchor = drawableRuleset.Playfield.Anchor; + l.Origin = drawableRuleset.Playfield.Origin; + l.Position = drawableRuleset.Playfield.Position; + l.Size = drawableRuleset.Playfield.Size; }); } @@ -173,8 +173,8 @@ namespace osu.Game.Rulesets.Edit beatmapProcessor?.PostProcess(); } - public override IEnumerable HitObjects => DrawableRuleset.Playfield.AllHitObjects; - public override bool CursorInPlacementArea => DrawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); + public override IEnumerable HitObjects => drawableRuleset.Playfield.AllHitObjects; + public override bool CursorInPlacementArea => drawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); protected abstract IReadOnlyList CompositionTools { get; } From 714ee312da0338bb768ac543ad5ffb4cf43328f0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 18:20:43 +0900 Subject: [PATCH 507/645] Rename DrawableEditRuleset -> DrawableEditRulesetWrapper --- ...leset.cs => DrawableEditRulesetWrapper.cs} | 7 ++++-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 22 +++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) rename osu.Game/Rulesets/Edit/{DrawableEditRuleset.cs => DrawableEditRulesetWrapper.cs} (85%) diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs similarity index 85% rename from osu.Game/Rulesets/Edit/DrawableEditRuleset.cs rename to osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs index a9f0dd4197..af565f8896 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs @@ -11,7 +11,10 @@ using osu.Game.Screens.Edit; namespace osu.Game.Rulesets.Edit { - public class DrawableEditRuleset : CompositeDrawable + /// + /// A wrapper for a . Handles adding visual representations of s to the underlying . + /// + internal class DrawableEditRulesetWrapper : CompositeDrawable where TObject : HitObject { public Playfield Playfield => drawableRuleset.Playfield; @@ -21,7 +24,7 @@ namespace osu.Game.Rulesets.Edit [Resolved] private IEditorBeatmap beatmap { get; set; } - public DrawableEditRuleset(DrawableRuleset drawableRuleset) + public DrawableEditRulesetWrapper(DrawableRuleset drawableRuleset) { this.drawableRuleset = drawableRuleset; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 35c5a63ef1..d7ee63d4a4 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Edit private EditorBeatmap editorBeatmap; private IBeatmapProcessor beatmapProcessor; - private DrawableEditRuleset drawableRuleset; + private DrawableEditRulesetWrapper drawableRulesetWrapper; private BlueprintContainer blueprintContainer; private readonly List layerContainers = new List(); @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Edit { try { - drawableRuleset = new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, workingBeatmap.Value, Array.Empty())) + drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, workingBeatmap.Value, Array.Empty())) { Clock = framedClock }; @@ -66,10 +66,10 @@ namespace osu.Game.Rulesets.Edit return; } - var layerBelowRuleset = drawableRuleset.CreatePlayfieldAdjustmentContainer(); + var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer(); layerBelowRuleset.Child = new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }; - var layerAboveRuleset = drawableRuleset.CreatePlayfieldAdjustmentContainer(); + var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer(); layerAboveRuleset.Child = blueprintContainer = new BlueprintContainer(); layerContainers.Add(layerBelowRuleset); @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Edit Children = new Drawable[] { layerBelowRuleset, - drawableRuleset, + drawableRulesetWrapper, layerAboveRuleset } } @@ -153,10 +153,10 @@ namespace osu.Game.Rulesets.Edit layerContainers.ForEach(l => { - l.Anchor = drawableRuleset.Playfield.Anchor; - l.Origin = drawableRuleset.Playfield.Origin; - l.Position = drawableRuleset.Playfield.Position; - l.Size = drawableRuleset.Playfield.Size; + l.Anchor = drawableRulesetWrapper.Playfield.Anchor; + l.Origin = drawableRulesetWrapper.Playfield.Origin; + l.Position = drawableRulesetWrapper.Playfield.Position; + l.Size = drawableRulesetWrapper.Playfield.Size; }); } @@ -173,8 +173,8 @@ namespace osu.Game.Rulesets.Edit beatmapProcessor?.PostProcess(); } - public override IEnumerable HitObjects => drawableRuleset.Playfield.AllHitObjects; - public override bool CursorInPlacementArea => drawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); + public override IEnumerable HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects; + public override bool CursorInPlacementArea => drawableRulesetWrapper.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); protected abstract IReadOnlyList CompositionTools { get; } From d3030831793dc68f7d8e04fce2d05209e6fab796 Mon Sep 17 00:00:00 2001 From: StanR Date: Thu, 29 Aug 2019 12:29:31 +0300 Subject: [PATCH 508/645] Update to match api --- .../Online/TestSceneBeatmapSetOverlay.cs | 4 +- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 51 +++---------------- .../API/Requests/Responses/APIBeatmapSet.cs | 4 +- osu.Game/Overlays/BeatmapSet/Info.cs | 4 +- 4 files changed, 12 insertions(+), 51 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 2d918442eb..ee9e088dcc 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -176,8 +176,8 @@ namespace osu.Game.Tests.Visual.Online HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), - Language = BeatmapSetOnlineLanguage.English, - Genre = BeatmapSetOnlineGenre.Rock, + Language = new BeatmapSetOnlineLanguage { Id = 3, Name = "English" }, + Genre = new BeatmapSetOnlineGenre { Id = 4, Name = "Rock" }, }, Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index decf2d10db..500e42096c 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -88,55 +88,16 @@ namespace osu.Game.Beatmaps public BeatmapSetOnlineLanguage Language { get; set; } } - public enum BeatmapSetOnlineGenre + public class BeatmapSetOnlineGenre { - [Description("Any")] - Any = 0, - - [Description("Unspecified")] - Unspecified = 1, - - [Description("Video Game")] - VideoGame = 2, - - [Description("Anime")] - Anime = 3, - - [Description("Rock")] - Rock = 4, - - [Description("Pop")] - Pop = 5, - - [Description("Other")] - Other = 6, - - [Description("Novelty")] - Novelty = 7, - - // genre_id 8 doesn't exist - - [Description("Hip-Hop")] - HipHop = 9, - - [Description("Electronic")] - Electronic = 10 + public int Id { get; set; } + public string Name { get; set; } } - public enum BeatmapSetOnlineLanguage + public class BeatmapSetOnlineLanguage { - Any, - Other, - English, - Japanese, - Chinese, - Instrumental, - Korean, - French, - German, - Swedish, - Spanish, - Italian + public int Id { get; set; } + public string Name { get; set; } } public class BeatmapSetOnlineCovers diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 1526cccf31..1ca14256e5 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -69,10 +69,10 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"availability")] private BeatmapSetOnlineAvailability availability { get; set; } - [JsonProperty(@"genre_id")] + [JsonProperty(@"genre")] private BeatmapSetOnlineGenre genre { get; set; } - [JsonProperty(@"language_id")] + [JsonProperty(@"language")] private BeatmapSetOnlineLanguage language { get; set; } [JsonProperty(@"beatmaps")] diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 0e4e9db948..9c5cce89f9 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -133,8 +133,8 @@ namespace osu.Game.Overlays.BeatmapSet { source.Text = b.NewValue?.Metadata.Source ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; - genre.Text = (b.NewValue?.OnlineInfo.Genre ?? BeatmapSetOnlineGenre.Unspecified).GetDescription(); - language.Text = (b.NewValue?.OnlineInfo.Language ?? BeatmapSetOnlineLanguage.Other).ToString(); + genre.Text = b.NewValue?.OnlineInfo.Genre.Name ?? "Unspecified"; + language.Text = b.NewValue?.OnlineInfo.Language.Name ?? "Other"; }; } From 68ee7346b213b099e6eceed2cd8478181e15b484 Mon Sep 17 00:00:00 2001 From: StanR Date: Thu, 29 Aug 2019 12:49:44 +0300 Subject: [PATCH 509/645] Remove usings --- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 1 - osu.Game/Overlays/BeatmapSet/Info.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 500e42096c..06dee4d3f5 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.ComponentModel; using Newtonsoft.Json; namespace osu.Game.Beatmaps diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 9c5cce89f9..f17b44c8f7 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -3,7 +3,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; From c1c1c7874bab0786ffeaa6f3a99e63c9b2317853 Mon Sep 17 00:00:00 2001 From: StanR Date: Thu, 29 Aug 2019 13:25:05 +0300 Subject: [PATCH 510/645] Nullcheck --- osu.Game/Overlays/BeatmapSet/Info.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index f17b44c8f7..72db03a5a6 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -132,8 +132,8 @@ namespace osu.Game.Overlays.BeatmapSet { source.Text = b.NewValue?.Metadata.Source ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; - genre.Text = b.NewValue?.OnlineInfo.Genre.Name ?? "Unspecified"; - language.Text = b.NewValue?.OnlineInfo.Language.Name ?? "Other"; + genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? "Unspecified"; + language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? "Other"; }; } From 6ab2b20c70dcea4dd98ec7c7ebc9f477170ea95d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 19:38:44 +0900 Subject: [PATCH 511/645] Add an interface for working beatmaps --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../UI/DrawableCatchRuleset.cs | 4 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../UI/DrawableManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../UI/DrawableOsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../UI/DrawableTaikoRuleset.cs | 2 +- .../TestSceneDrawableScrollingRuleset.cs | 4 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 61 +++++++++++++++++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 16 +---- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 12 ++-- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- .../UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- 16 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 osu.Game/Beatmaps/IWorkingBeatmap.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 6f1a7873ec..71e05083be 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch { public class CatchRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableCatchRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableCatchRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index f48b84e344..6b7f00c5d0 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -25,11 +25,11 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableCatchRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Down; - TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450); + TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450); } public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8966b5058f..0de86c2149 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania { public class ManiaRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableManiaRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableManiaRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index 0718de2c7d..f26526fe70 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly Bindable configDirection = new Bindable(); - public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableManiaRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { // Generate the bar lines diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index d50d4f401c..3bbfc25d22 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu { public class OsuRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableOsuRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableOsuRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index d185d7d4c9..aa61fb6922 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.UI { protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config; - public DrawableOsuRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableOsuRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 83356b77c2..6d0a5eb1e1 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko { public class TaikoRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableTaikoRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableTaikoRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index ec3a56e9c7..b03bea578e 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableTaikoRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableTaikoRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Left; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index ee11fc0d06..60ace8ea69 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -174,7 +174,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override IEnumerable GetModsFor(ModType type) => throw new NotImplementedException(); - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new TestDrawableScrollingRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new TestDrawableScrollingRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap); @@ -193,7 +193,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping; - public TestDrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public TestDrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { TimeRange.Value = time_range; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 3a4c677bd1..29ade24328 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) + public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) { throw new NotImplementedException(); } diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs new file mode 100644 index 0000000000..aea3751bb5 --- /dev/null +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -0,0 +1,61 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Textures; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.UI; +using osu.Game.Skinning; +using osu.Game.Storyboards; + +namespace osu.Game.Beatmaps +{ + public interface IWorkingBeatmap + { + /// + /// Retrieves the which this represents. + /// + IBeatmap Beatmap { get; } + + /// + /// Retrieves the background for this . + /// + Texture Background { get; } + + /// + /// Retrieves the audio track for this . + /// + Track Track { get; } + + /// + /// Retrieves the for the of this . + /// + Waveform Waveform { get; } + + /// + /// Retrieves the which this provides. + /// + Storyboard Storyboard { get; } + + /// + /// Retrieves the which this provides. + /// + Skin Skin { get; } + + /// + /// Constructs a playable from using the applicable converters for a specific . + /// + /// The returned is in a playable state - all and s + /// have been applied, and s have been fully constructed. + /// + /// + /// The to create a playable for. + /// The s to apply to the . + /// The converted . + /// If could not be converted to . + IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods); + } +} diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 8605caa5fe..1cce3dc5fe 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -16,14 +16,13 @@ using osu.Framework.Audio; using osu.Framework.Statistics; using osu.Game.IO.Serialization; using osu.Game.Rulesets; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.UI; using osu.Game.Skinning; namespace osu.Game.Beatmaps { - public abstract class WorkingBeatmap : IDisposable + public abstract class WorkingBeatmap : IWorkingBeatmap, IDisposable { public readonly BeatmapInfo BeatmapInfo; @@ -97,18 +96,7 @@ namespace osu.Game.Beatmaps /// The applicable . protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); - /// - /// Constructs a playable from using the applicable converters for a specific . - /// - /// The returned is in a playable state - all and s - /// have been applied, and s have been fully constructed. - /// - /// - /// The to create a playable for. - /// The s to apply to the . - /// The converted . - /// If could not be converted to . - public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) + public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) { var rulesetInstance = ruleset.CreateInstance(); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index d7ee63d4a4..fc324d7021 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Edit protected readonly Ruleset Ruleset; - private IBindable workingBeatmap; + private IWorkingBeatmap workingBeatmap; private Beatmap playableBeatmap; private EditorBeatmap editorBeatmap; private IBeatmapProcessor beatmapProcessor; @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Edit { try { - drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, workingBeatmap.Value, Array.Empty())) + drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, workingBeatmap, Array.Empty())) { Clock = framedClock }; @@ -122,8 +122,10 @@ namespace osu.Game.Rulesets.Edit protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - workingBeatmap = parent.Get>().GetBoundCopy(); - playableBeatmap = (Beatmap)workingBeatmap.Value.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); + var parentWorkingBeatmap = parent.Get>().Value; + + playableBeatmap = (Beatmap)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty()); + workingBeatmap = new EditorWorkingBeatmap(playableBeatmap, parentWorkingBeatmap); beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap); @@ -178,7 +180,7 @@ namespace osu.Game.Rulesets.Edit protected abstract IReadOnlyList CompositionTools { get; } - protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods); + protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods); public void BeginPlacement(HitObject hitObject) { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 42b1322cae..b089840f1e 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets /// The s to apply. /// Unable to successfully load the beatmap to be usable with this ruleset. /// - public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods); + public abstract DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods); /// /// Creates a to convert a to one that is applicable for this . diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index ccfd89adca..021bd515b5 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.UI /// The ruleset being represented. /// The beatmap to create the hit renderer for. /// The s to apply. - protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap, IReadOnlyList mods) + protected DrawableRuleset(Ruleset ruleset, IWorkingBeatmap workingBeatmap, IReadOnlyList mods) : base(ruleset) { if (workingBeatmap == null) diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index c1a4c9520e..64e491858b 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.UI.Scrolling [Cached(Type = typeof(IScrollingInfo))] private readonly LocalScrollingInfo scrollingInfo; - protected DrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + protected DrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { scrollingInfo = new LocalScrollingInfo(); From 6641811125b938aa1511325938504f4be4e876a0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 19:40:56 +0900 Subject: [PATCH 512/645] Add EditorWorkingBeatmap for reuse of the playable beatmap --- .../Edit/DrawableManiaEditRuleset.cs | 2 +- .../Edit/ManiaHitObjectComposer.cs | 2 +- .../Edit/DrawableOsuEditRuleset.cs | 2 +- .../Edit/OsuHitObjectComposer.cs | 2 +- osu.Game/Screens/Edit/EditorWorkingBeatmap.cs | 42 +++++++++++++++++++ 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Screens/Edit/EditorWorkingBeatmap.cs diff --git a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs index e5f379f608..97d8aaa052 100644 --- a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs +++ b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Edit { public new IScrollingInfo ScrollingInfo => base.ScrollingInfo; - public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableManiaEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 3a28149946..0bfe6f9517 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Edit public int TotalColumns => ((ManiaPlayfield)drawableRuleset.Playfield).TotalColumns; - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) { drawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods); diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs index bcb6099cfb..cc08d356f9 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit { public class DrawableOsuEditRuleset : DrawableOsuRuleset { - public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + public DrawableOsuEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index c5452ae0aa..1c040e9dee 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit { } - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableOsuEditRuleset(ruleset, beatmap, mods); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] diff --git a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs new file mode 100644 index 0000000000..8bec68596c --- /dev/null +++ b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs @@ -0,0 +1,42 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Textures; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; +using osu.Game.Storyboards; + +namespace osu.Game.Screens.Edit +{ + public class EditorWorkingBeatmap : IWorkingBeatmap + where TObject : HitObject + { + private readonly Beatmap playableBeatmap; + private readonly WorkingBeatmap workingBeatmap; + + public EditorWorkingBeatmap(Beatmap playableBeatmap, WorkingBeatmap workingBeatmap) + { + this.playableBeatmap = playableBeatmap; + this.workingBeatmap = workingBeatmap; + } + + public IBeatmap Beatmap => workingBeatmap.Beatmap; + + public Texture Background => workingBeatmap.Background; + + public Track Track => workingBeatmap.Track; + + public Waveform Waveform => workingBeatmap.Waveform; + + public Storyboard Storyboard => workingBeatmap.Storyboard; + + public Skin Skin => workingBeatmap.Skin; + + public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) => playableBeatmap; + } +} From ae0a5504d705fb4ed1dd95751e71d581f40cf636 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 29 Aug 2019 19:43:33 +0900 Subject: [PATCH 513/645] Revert unnecessary change --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 1cce3dc5fe..90dde4239c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -96,7 +96,7 @@ namespace osu.Game.Beatmaps /// The applicable . protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); - public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) + public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) { var rulesetInstance = ruleset.CreateInstance(); From ec6a40af339a78b2d172b69089ea77b6afca8c5e Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 29 Aug 2019 15:32:21 +0300 Subject: [PATCH 514/645] Add adjustments on channel creation if there is --- osu.Game/Skinning/SkinnableSound.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index cb511fc775..e1d9b231dc 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -15,6 +15,9 @@ namespace osu.Game.Skinning public class SkinnableSound : SkinReloadableDrawable { private readonly ISampleInfo[] hitSamples; + + private readonly List<(AdjustableProperty, BindableDouble)> adjustments = new List<(AdjustableProperty, BindableDouble)>(); + private SampleChannel[] channels; private AudioManager audio; @@ -51,8 +54,17 @@ namespace osu.Game.Skinning public void Play() => channels?.ForEach(c => c.Play()); public void Stop() => channels?.ForEach(c => c.Stop()); - public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) => channels?.ForEach(c => c.AddAdjustment(type, adjustBindable)); - public void RemoveAdjustment(AdjustableProperty type, BindableDouble adjustBindable) => channels?.ForEach(c => c.RemoveAdjustment(type, adjustBindable)); + public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) + { + adjustments.Add((type, adjustBindable)); + channels?.ForEach(c => c.AddAdjustment(type, adjustBindable)); + } + + public void RemoveAdjustment(AdjustableProperty type, BindableDouble adjustBindable) + { + adjustments.Remove((type, adjustBindable)); + channels?.ForEach(c => c.RemoveAdjustment(type, adjustBindable)); + } public override bool IsPresent => Scheduler.HasPendingTasks; @@ -71,6 +83,9 @@ namespace osu.Game.Skinning { ch.Looping = looping; ch.Volume.Value = s.Volume / 100.0; + + foreach (var adjustment in adjustments) + ch.AddAdjustment(adjust.Item1, adjust.Item2); } return ch; From 06224a7d4ee9921180946040f62811d75689a406 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 29 Aug 2019 15:38:33 +0300 Subject: [PATCH 515/645] Fix build issue --- osu.Game/Skinning/SkinnableSound.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index e1d9b231dc..bf647baeec 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -85,7 +85,7 @@ namespace osu.Game.Skinning ch.Volume.Value = s.Volume / 100.0; foreach (var adjustment in adjustments) - ch.AddAdjustment(adjust.Item1, adjust.Item2); + ch.AddAdjustment(adjustment.Item1, adjustment.Item2); } return ch; From 3f500131d483b5ebbdc60fb4c905de2e754965d7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 11:33:50 +0900 Subject: [PATCH 516/645] Add basic xmldoc --- osu.Game/Screens/Edit/EditorWorkingBeatmap.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs index 8bec68596c..45fca493a2 100644 --- a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs @@ -13,6 +13,10 @@ using osu.Game.Storyboards; namespace osu.Game.Screens.Edit { + /// + /// Encapsulates a while providing an overridden . + /// + /// public class EditorWorkingBeatmap : IWorkingBeatmap where TObject : HitObject { From bfbec067b13ba7546b1ece8f460b4c433200564c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 11:54:36 +0900 Subject: [PATCH 517/645] Remove remnants of user skin PR --- osu.Game/Skinning/SkinManager.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 0e40eb5376..a713933c6e 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -60,9 +60,6 @@ namespace osu.Game.Skinning }; } - private Skin createIfNotExisting(SkinInfo skinInfo) => - GetSkin(Query(s => s.Name == skinInfo.Name) ?? Import(skinInfo).Result); - protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osk"; /// @@ -110,9 +107,6 @@ namespace osu.Game.Skinning /// A instance correlating to the provided . public Skin GetSkin(SkinInfo skinInfo) { - if (skinInfo == null) - return null; - if (skinInfo == SkinInfo.Default) return new DefaultSkin(); From 8fe37d0c43aec1182f9b437ba16cce2103a6a526 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 12:35:44 +0900 Subject: [PATCH 518/645] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 0f6e32d664..3854cab34f 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d791909372..5563f9efeb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9fc472bf40..a430ff59ab 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 9c622680e32a5f21777ffb4aee13acbee1a7fe86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 12:35:53 +0900 Subject: [PATCH 519/645] 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 3854cab34f..2c3c8bcaad 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5563f9efeb..8e6ce2d1ba 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index a430ff59ab..47cc6ec97a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,8 +118,8 @@ - - + + From 84e474826817f394594a0973016492d3bda740d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 12:59:58 +0900 Subject: [PATCH 520/645] Remove duplicate getAnimation function and improve namespacing --- osu.Game.Rulesets.Osu/OsuLegacySkin.cs | 236 ------------------ osu.Game.Rulesets.Osu/OsuRuleset.cs | 1 + .../Skinning/LegacyMainCirclePiece.cs | 81 ++++++ .../Skinning/LegacySliderBall.cs | 44 ++++ .../Skinning/OsuLegacySkin.cs | 97 +++++++ osu.Game/Beatmaps/IWorkingBeatmap.cs | 2 +- osu.Game/Screens/Edit/EditorWorkingBeatmap.cs | 2 +- osu.Game/Skinning/LegacySkin.cs | 40 +-- osu.Game/Skinning/LegacySkinExtensions.cs | 53 ++++ 9 files changed, 279 insertions(+), 277 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/OsuLegacySkin.cs create mode 100644 osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs create mode 100644 osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs create mode 100644 osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs create mode 100644 osu.Game/Skinning/LegacySkinExtensions.cs diff --git a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/OsuLegacySkin.cs deleted file mode 100644 index d4b00ab911..0000000000 --- a/osu.Game.Rulesets.Osu/OsuLegacySkin.cs +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Audio.Sample; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Animations; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Game.Audio; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Objects.Types; -using osu.Game.Skinning; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Rulesets.Osu -{ - public class OsuLegacySkin : ISkin - { - private readonly ISkin source; - - private Lazy configuration; - - private Lazy hasHitCircle; - - /// - /// On osu-stable, hitcircles have 5 pixels of transparent padding on each side to allow for shadows etc. - /// Their hittable area is 128px, but the actual circle portion is 118px. - /// We must account for some gameplay elements such as slider bodies, where this padding is not present. - /// - private const float legacy_circle_radius = 64 - 5; - - public OsuLegacySkin(ISkinSource source) - { - this.source = source; - - source.SourceChanged += sourceChanged; - sourceChanged(); - } - - private void sourceChanged() - { - // these need to be lazy in order to ensure they aren't called before the dependencies have been loaded into our source. - configuration = new Lazy(() => - { - var config = new SkinConfiguration(); - if (hasHitCircle.Value) - config.SliderPathRadius = legacy_circle_radius; - - // defaults should only be applied for non-beatmap skins (which are parsed via this constructor). - config.CustomColours["SliderBall"] = - source.GetValue(s => s.CustomColours.TryGetValue("SliderBall", out var val) ? val : (Color4?)null) - ?? new Color4(2, 170, 255, 255); - - return config; - }); - - hasHitCircle = new Lazy(() => source.GetTexture("hitcircle") != null); - } - - private const double default_frame_time = 1000 / 60d; - - public Drawable GetDrawableComponent(string componentName) - { - switch (componentName) - { - case "Play/osu/sliderball": - var sliderBallContent = getAnimation("sliderb", true, true, ""); - - if (sliderBallContent != null) - { - var size = sliderBallContent.Size; - - sliderBallContent.RelativeSizeAxes = Axes.Both; - sliderBallContent.Size = Vector2.One; - - return new LegacySliderBall(sliderBallContent) - { - Size = size - }; - } - - return null; - - case "Play/osu/hitcircle": - if (hasHitCircle.Value) - return new LegacyMainCirclePiece(); - - return null; - } - - return null; - } - - private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-") - { - Texture texture; - - Texture getFrameTexture(int frame) => source.GetTexture($"{componentName}{animationSeparator}{frame}"); - - TextureAnimation animation = null; - - if (animatable) - { - for (int i = 0;; i++) - { - if ((texture = getFrameTexture(i)) == null) - break; - - if (animation == null) - animation = new TextureAnimation - { - DefaultFrameLength = default_frame_time, - Repeat = looping - }; - - animation.AddFrame(texture); - } - } - - if (animation != null) - return animation; - - if ((texture = source.GetTexture(componentName)) != null) - return new Sprite { Texture = texture }; - - return null; - } - - public Texture GetTexture(string componentName) => null; - - public SampleChannel GetSample(ISampleInfo sample) => null; - - public TValue GetValue(Func query) where TConfiguration : SkinConfiguration - => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; - - public class LegacySliderBall : CompositeDrawable - { - private readonly Drawable animationContent; - - public LegacySliderBall(Drawable animationContent) - { - this.animationContent = animationContent; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin, DrawableHitObject drawableObject) - { - animationContent.Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; - - InternalChildren = new[] - { - new Sprite - { - Texture = skin.GetTexture("sliderb-nd"), - Colour = new Color4(5, 5, 5, 255), - }, - animationContent, - new Sprite - { - Texture = skin.GetTexture("sliderb-spec"), - Blending = BlendingParameters.Additive, - }, - }; - } - } - - public class LegacyMainCirclePiece : CompositeDrawable - { - public LegacyMainCirclePiece() - { - Size = new Vector2(128); - } - - private readonly IBindable state = new Bindable(); - - private readonly Bindable accentColour = new Bindable(); - - [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableObject, ISkinSource skin) - { - Sprite hitCircleSprite; - - InternalChildren = new Drawable[] - { - hitCircleSprite = new Sprite - { - Texture = skin.GetTexture("hitcircle"), - Colour = drawableObject.AccentColour.Value, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText - { - Font = OsuFont.Numeric.With(size: 40), - UseFullGlyphHeight = false, - }, confineMode: ConfineMode.NoScaling) - { - Text = (((IHasComboInformation)drawableObject.HitObject).IndexInCurrentCombo + 1).ToString() - }, - new Sprite - { - Texture = skin.GetTexture("hitcircleoverlay"), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - }; - - state.BindTo(drawableObject.State); - state.BindValueChanged(updateState, true); - - accentColour.BindTo(drawableObject.AccentColour); - accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); - } - - private void updateState(ValueChangedEvent state) - { - const double legacy_fade_duration = 240; - - switch (state.NewValue) - { - case ArmedState.Hit: - this.FadeOut(legacy_fade_duration, Easing.Out); - this.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - break; - } - } - } - } -} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index e2c64bbedf..49676933e1 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -23,6 +23,7 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Difficulty; +using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Scoring; using osu.Game.Skinning; diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs new file mode 100644 index 0000000000..a7906ddd24 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -0,0 +1,81 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Skinning; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Skinning +{ + public class LegacyMainCirclePiece : CompositeDrawable + { + public LegacyMainCirclePiece() + { + Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); + } + + private readonly IBindable state = new Bindable(); + + private readonly Bindable accentColour = new Bindable(); + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableObject, ISkinSource skin) + { + Sprite hitCircleSprite; + + InternalChildren = new Drawable[] + { + hitCircleSprite = new Sprite + { + Texture = skin.GetTexture("hitcircle"), + Colour = drawableObject.AccentColour.Value, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: 40), + UseFullGlyphHeight = false, + }, confineMode: ConfineMode.NoScaling) + { + Text = (((IHasComboInformation)drawableObject.HitObject).IndexInCurrentCombo + 1).ToString() + }, + new Sprite + { + Texture = skin.GetTexture("hitcircleoverlay"), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + + state.BindTo(drawableObject.State); + state.BindValueChanged(updateState, true); + + accentColour.BindTo(drawableObject.AccentColour); + accentColour.BindValueChanged(colour => hitCircleSprite.Colour = colour.NewValue, true); + } + + private void updateState(ValueChangedEvent state) + { + const double legacy_fade_duration = 240; + + switch (state.NewValue) + { + case ArmedState.Hit: + this.FadeOut(legacy_fade_duration, Easing.Out); + this.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs new file mode 100644 index 0000000000..ec838c596d --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBall.cs @@ -0,0 +1,44 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Skinning; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Skinning +{ + public class LegacySliderBall : CompositeDrawable + { + private readonly Drawable animationContent; + + public LegacySliderBall(Drawable animationContent) + { + this.animationContent = animationContent; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, DrawableHitObject drawableObject) + { + animationContent.Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; + + InternalChildren = new[] + { + new Sprite + { + Texture = skin.GetTexture("sliderb-nd"), + Colour = new Color4(5, 5, 5, 255), + }, + animationContent, + new Sprite + { + Texture = skin.GetTexture("sliderb-spec"), + Blending = BlendingParameters.Additive, + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs new file mode 100644 index 0000000000..927cbc5d2f --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -0,0 +1,97 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Textures; +using osu.Game.Audio; +using osu.Game.Skinning; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Skinning +{ + public class OsuLegacySkin : ISkin + { + private readonly ISkin source; + + private Lazy configuration; + + private Lazy hasHitCircle; + + /// + /// On osu-stable, hitcircles have 5 pixels of transparent padding on each side to allow for shadows etc. + /// Their hittable area is 128px, but the actual circle portion is 118px. + /// We must account for some gameplay elements such as slider bodies, where this padding is not present. + /// + private const float legacy_circle_radius = 64 - 5; + + public OsuLegacySkin(ISkinSource source) + { + this.source = source; + + source.SourceChanged += sourceChanged; + sourceChanged(); + } + + private void sourceChanged() + { + // these need to be lazy in order to ensure they aren't called before the dependencies have been loaded into our source. + configuration = new Lazy(() => + { + var config = new SkinConfiguration(); + if (hasHitCircle.Value) + config.SliderPathRadius = legacy_circle_radius; + + // defaults should only be applied for non-beatmap skins (which are parsed via this constructor). + config.CustomColours["SliderBall"] = + source.GetValue(s => s.CustomColours.TryGetValue("SliderBall", out var val) ? val : (Color4?)null) + ?? new Color4(2, 170, 255, 255); + + return config; + }); + + hasHitCircle = new Lazy(() => source.GetTexture("hitcircle") != null); + } + + public Drawable GetDrawableComponent(string componentName) + { + switch (componentName) + { + case "Play/osu/sliderball": + var sliderBallContent = this.GetAnimation("sliderb", true, true, ""); + + if (sliderBallContent != null) + { + var size = sliderBallContent.Size; + + sliderBallContent.RelativeSizeAxes = Axes.Both; + sliderBallContent.Size = Vector2.One; + + return new LegacySliderBall(sliderBallContent) + { + Size = size + }; + } + + return null; + + case "Play/osu/hitcircle": + if (hasHitCircle.Value) + return new LegacyMainCirclePiece(); + + return null; + } + + return null; + } + + public Texture GetTexture(string componentName) => null; + + public SampleChannel GetSample(ISampleInfo sample) => null; + + public TValue GetValue(Func query) where TConfiguration : SkinConfiguration + => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; + } +} diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index aea3751bb5..44071d9cc1 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps /// /// Retrieves the which this provides. /// - Skin Skin { get; } + ISkin Skin { get; } /// /// Constructs a playable from using the applicable converters for a specific . diff --git a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs index 45fca493a2..299059407c 100644 --- a/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorWorkingBeatmap.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Edit public Storyboard Storyboard => workingBeatmap.Storyboard; - public Skin Skin => workingBeatmap.Skin; + public ISkin Skin => workingBeatmap.Skin; public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) => playableBeatmap; } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 8dfefcfa1b..d567e48d9a 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; -using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; @@ -60,8 +59,6 @@ namespace osu.Game.Skinning Samples?.Dispose(); } - private const double default_frame_time = 1000 / 60d; - public override Drawable GetDrawableComponent(string componentName) { bool animatable = false; @@ -114,7 +111,7 @@ namespace osu.Game.Skinning }; } - return getAnimation(componentName, animatable, looping); + return this.GetAnimation(componentName, animatable, looping); } public override Texture GetTexture(string componentName) @@ -161,41 +158,6 @@ namespace osu.Game.Skinning return componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; } - private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-") - { - Texture texture; - - Texture getFrameTexture(int frame) => GetTexture($"{componentName}{animationSeparator}{frame}"); - - TextureAnimation animation = null; - - if (animatable) - { - for (int i = 0;; i++) - { - if ((texture = getFrameTexture(i)) == null) - break; - - if (animation == null) - animation = new TextureAnimation - { - DefaultFrameLength = default_frame_time, - Repeat = looping - }; - - animation.AddFrame(texture); - } - } - - if (animation != null) - return animation; - - if ((texture = GetTexture(componentName)) != null) - return new Sprite { Texture = texture }; - - return null; - } - protected class LegacySkinResourceStore : IResourceStore where T : INamedFileInfo { diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs new file mode 100644 index 0000000000..c5582af836 --- /dev/null +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -0,0 +1,53 @@ +// 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.Animations; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Skinning +{ + public static class LegacySkinExtensions + { + public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, string animationSeparator = "-") + { + const double default_frame_time = 1000 / 60d; + + Texture texture; + + Texture getFrameTexture(int frame) => source.GetTexture($"{componentName}{animationSeparator}{frame}"); + + TextureAnimation animation = null; + + if (animatable) + { + for (int i = 0;; i++) + { + if ((texture = getFrameTexture(i)) == null) + break; + + if (animation == null) + animation = new TextureAnimation + { + DefaultFrameLength = default_frame_time, + Repeat = looping + }; + + animation.AddFrame(texture); + } + } + + if (animation != null) + return animation; + + if ((texture = source.GetTexture(componentName)) != null) + return new Sprite + { + Texture = texture + }; + + return null; + } + } +} From 7bba8ca14bb92bea3f1d6a707ba1c85cc8f8f9a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 13:04:11 +0900 Subject: [PATCH 521/645] Split out nested classes --- osu.Game/Skinning/LegacySkin.cs | 112 ------------------- osu.Game/Skinning/LegacySkinResourceStore.cs | 76 +++++++++++++ osu.Game/Skinning/LegacySpriteText.cs | 53 +++++++++ 3 files changed, 129 insertions(+), 112 deletions(-) create mode 100644 osu.Game/Skinning/LegacySkinResourceStore.cs create mode 100644 osu.Game/Skinning/LegacySpriteText.cs diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index d567e48d9a..0151a211d3 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,11 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -14,11 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; -using osu.Framework.Text; using osu.Game.Audio; -using osu.Game.Database; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.UI; using osuTK; using osuTK.Graphics; @@ -158,111 +151,6 @@ namespace osu.Game.Skinning return componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; } - protected class LegacySkinResourceStore : IResourceStore - where T : INamedFileInfo - { - private readonly IHasFiles source; - private readonly IResourceStore underlyingStore; - - private string getPathForFile(string filename) - { - bool hasExtension = filename.Contains('.'); - - var file = source.Files.Find(f => - string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), filename, StringComparison.InvariantCultureIgnoreCase)); - return file?.FileInfo.StoragePath; - } - - public LegacySkinResourceStore(IHasFiles source, IResourceStore underlyingStore) - { - this.source = source; - this.underlyingStore = underlyingStore; - } - - public Stream GetStream(string name) - { - string path = getPathForFile(name); - return path == null ? null : underlyingStore.GetStream(path); - } - - public IEnumerable GetAvailableResources() => source.Files.Select(f => f.Filename); - - byte[] IResourceStore.Get(string name) => GetAsync(name).Result; - - public Task GetAsync(string name) - { - string path = getPathForFile(name); - return path == null ? Task.FromResult(null) : underlyingStore.GetAsync(path); - } - - #region IDisposable Support - - private bool isDisposed; - - protected virtual void Dispose(bool disposing) - { - if (!isDisposed) - { - isDisposed = true; - } - } - - ~LegacySkinResourceStore() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - } - - private class LegacySpriteText : OsuSpriteText - { - private readonly LegacyGlyphStore glyphStore; - - public LegacySpriteText(ISkin skin, string font) - { - Shadow = false; - UseFullGlyphHeight = false; - - Font = new FontUsage(font, OsuFont.DEFAULT_FONT_SIZE); - glyphStore = new LegacyGlyphStore(skin); - } - - protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore); - - private class LegacyGlyphStore : ITexturedGlyphLookupStore - { - private readonly ISkin skin; - - public LegacyGlyphStore(ISkin skin) - { - this.skin = skin; - } - - public ITexturedCharacterGlyph Get(string fontName, char character) - { - var texture = skin.GetTexture($"{fontName}-{character}"); - - if (texture != null) - // Approximate value that brings character sizing roughly in-line with stable - texture.ScaleAdjust *= 18; - - if (texture == null) - return null; - - return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture.Width, null), texture, 1f / texture.ScaleAdjust); - } - - public Task GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character)); - } - } - public class LegacyCursor : CompositeDrawable { public LegacyCursor() diff --git a/osu.Game/Skinning/LegacySkinResourceStore.cs b/osu.Game/Skinning/LegacySkinResourceStore.cs new file mode 100644 index 0000000000..c8912aeb1f --- /dev/null +++ b/osu.Game/Skinning/LegacySkinResourceStore.cs @@ -0,0 +1,76 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using osu.Framework.IO.Stores; +using osu.Game.Database; + +namespace osu.Game.Skinning +{ + public class LegacySkinResourceStore : IResourceStore + where T : INamedFileInfo + { + private readonly IHasFiles source; + private readonly IResourceStore underlyingStore; + + private string getPathForFile(string filename) + { + bool hasExtension = filename.Contains('.'); + + var file = source.Files.Find(f => + string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), filename, StringComparison.InvariantCultureIgnoreCase)); + return file?.FileInfo.StoragePath; + } + + public LegacySkinResourceStore(IHasFiles source, IResourceStore underlyingStore) + { + this.source = source; + this.underlyingStore = underlyingStore; + } + + public Stream GetStream(string name) + { + string path = getPathForFile(name); + return path == null ? null : underlyingStore.GetStream(path); + } + + public IEnumerable GetAvailableResources() => source.Files.Select(f => f.Filename); + + byte[] IResourceStore.Get(string name) => GetAsync(name).Result; + + public Task GetAsync(string name) + { + string path = getPathForFile(name); + return path == null ? Task.FromResult(null) : underlyingStore.GetAsync(path); + } + + #region IDisposable Support + + private bool isDisposed; + + protected virtual void Dispose(bool disposing) + { + if (!isDisposed) + { + isDisposed = true; + } + } + + ~LegacySkinResourceStore() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + } +} diff --git a/osu.Game/Skinning/LegacySpriteText.cs b/osu.Game/Skinning/LegacySpriteText.cs new file mode 100644 index 0000000000..dbcec019d6 --- /dev/null +++ b/osu.Game/Skinning/LegacySpriteText.cs @@ -0,0 +1,53 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Threading.Tasks; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Text; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Skinning +{ + public class LegacySpriteText : OsuSpriteText + { + private readonly LegacyGlyphStore glyphStore; + + public LegacySpriteText(ISkin skin, string font) + { + Shadow = false; + UseFullGlyphHeight = false; + + Font = new FontUsage(font, OsuFont.DEFAULT_FONT_SIZE); + glyphStore = new LegacyGlyphStore(skin); + } + + protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore); + + private class LegacyGlyphStore : ITexturedGlyphLookupStore + { + private readonly ISkin skin; + + public LegacyGlyphStore(ISkin skin) + { + this.skin = skin; + } + + public ITexturedCharacterGlyph Get(string fontName, char character) + { + var texture = skin.GetTexture($"{fontName}-{character}"); + + if (texture != null) + // Approximate value that brings character sizing roughly in-line with stable + texture.ScaleAdjust *= 18; + + if (texture == null) + return null; + + return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture.Width, null), texture, 1f / texture.ScaleAdjust); + } + + public Task GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character)); + } + } +} From c389a5c798974d33f1b8728b09b99ebdd7e23137 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 13:42:29 +0900 Subject: [PATCH 522/645] Move remaining osu-specific implementations to OsuLegacySkin --- .../Skinning/LegacyCursor.cs | 42 +++++++++++ .../Skinning/NonPlayfieldSprite.cs | 28 +++++++ .../Skinning/OsuLegacySkin.cs | 22 ++++++ osu.Game/Skinning/LegacySkin.cs | 73 ------------------- 4 files changed, 92 insertions(+), 73 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Skinning/LegacyCursor.cs create mode 100644 osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyCursor.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyCursor.cs new file mode 100644 index 0000000000..470ba3acae --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyCursor.cs @@ -0,0 +1,42 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Skinning; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Skinning +{ + public class LegacyCursor : CompositeDrawable + { + public LegacyCursor() + { + Size = new Vector2(50); + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin) + { + InternalChildren = new Drawable[] + { + new NonPlayfieldSprite + { + Texture = skin.GetTexture("cursormiddle"), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new NonPlayfieldSprite + { + Texture = skin.GetTexture("cursor"), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs new file mode 100644 index 0000000000..55257106e2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Osu.Skinning +{ + /// + /// A sprite which is displayed within the playfield, but historically was not considered part of the playfield. + /// Performs scale adjustment to undo the scale applied by (osu! ruleset specifically). + /// + public class NonPlayfieldSprite : Sprite + { + public override Texture Texture + { + get => base.Texture; + set + { + if (value != null) + // stable "magic ratio". see OsuPlayfieldAdjustmentContainer for full explanation. + value.ScaleAdjust *= 1.6f; + base.Texture = value; + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 927cbc5d2f..27bfdc315b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -82,6 +82,26 @@ namespace osu.Game.Rulesets.Osu.Skinning return new LegacyMainCirclePiece(); return null; + + case "Play/osu/cursor": + if (GetTexture("cursor") != null) + return new LegacyCursor(); + + return null; + + case "Play/osu/number-text": + + string font = GetValue(config => config.HitCircleFont); + var overlap = GetValue(config => config.HitCircleOverlap); + + return !hasFont(font) + ? null + : new LegacySpriteText(this, font) + { + // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size + Scale = new Vector2(0.96f), + Spacing = new Vector2(-overlap * 0.89f, 0) + }; } return null; @@ -93,5 +113,7 @@ namespace osu.Game.Rulesets.Osu.Skinning public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; + + private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 0151a211d3..9a47e01f4e 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -3,17 +3,12 @@ using System.IO; using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Audio; -using osu.Game.Rulesets.UI; -using osuTK; using osuTK.Graphics; namespace osu.Game.Skinning @@ -59,12 +54,6 @@ namespace osu.Game.Skinning switch (componentName) { - case "Play/osu/cursor": - if (GetTexture("cursor") != null) - return new LegacyCursor(); - - return null; - case "Play/osu/sliderfollowcircle": animatable = true; break; @@ -92,16 +81,6 @@ namespace osu.Game.Skinning animatable = true; looping = false; break; - - case "Play/osu/number-text": - return !hasFont(Configuration.HitCircleFont) - ? null - : new LegacySpriteText(this, Configuration.HitCircleFont) - { - Scale = new Vector2(0.96f), - // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size - Spacing = new Vector2(-Configuration.HitCircleOverlap * 0.89f, 0) - }; } return this.GetAnimation(componentName, animatable, looping); @@ -143,62 +122,10 @@ namespace osu.Game.Skinning return null; } - private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; - private string getFallbackName(string componentName) { string lastPiece = componentName.Split('/').Last(); return componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; } - - public class LegacyCursor : CompositeDrawable - { - public LegacyCursor() - { - Size = new Vector2(50); - - Anchor = Anchor.Centre; - Origin = Anchor.Centre; - } - - [BackgroundDependencyLoader] - private void load(ISkinSource skin) - { - InternalChildren = new Drawable[] - { - new NonPlayfieldSprite - { - Texture = skin.GetTexture("cursormiddle"), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new NonPlayfieldSprite - { - Texture = skin.GetTexture("cursor"), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - }; - } - } - - /// - /// A sprite which is displayed within the playfield, but historically was not considered part of the playfield. - /// Performs scale adjustment to undo the scale applied by (osu! ruleset specifically). - /// - private class NonPlayfieldSprite : Sprite - { - public override Texture Texture - { - get => base.Texture; - set - { - if (value != null) - // stable "magic ratio". see OsuPlayfieldAdjustmentContainer for full explanation. - value.ScaleAdjust *= 1.6f; - base.Texture = value; - } - } - } } } From 22e3ad8b9c388ee6b4ff43c9acb3f186a7070264 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 13:58:17 +0900 Subject: [PATCH 523/645] Add skinning support to cursor test --- .../Resources/default-skin/cursor@2x.png | Bin 0 -> 28063 bytes .../default-skin/cursormiddle@2x.png | Bin 0 -> 7676 bytes .../TestSceneGameplayCursor.cs | 18 ++++++------------ .../Skinning/OsuLegacySkin.cs | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) create mode 100755 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/cursor@2x.png create mode 100755 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/cursormiddle@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/cursor@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/cursor@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..75f9ba5ea6637636912004f8a889f5575d830436 GIT binary patch literal 28063 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/cursormiddle@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/cursormiddle@2x.png new file mode 100755 index 0000000000000000000000000000000000000000..ebf59c18ba9f62390f49be4bed696a997a51f05c GIT binary patch literal 7676 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 q!@f`~Q0000 RequiredTypes => new[] { typeof(CursorTrail) }; - public CursorContainer Cursor => cursorContainer; - - public bool ProvidingUserCursor => true; - [BackgroundDependencyLoader] private void load() { - Add(cursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both }); + SetContents(() => new OsuCursorContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + }); } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 27bfdc315b..0295a419ac 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Osu.Skinning return null; case "Play/osu/cursor": - if (GetTexture("cursor") != null) + if (source.GetTexture("cursor") != null) return new LegacyCursor(); return null; From 8f9fe9923746dfd62231d30dc198bf2458bfa36d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 14:40:36 +0900 Subject: [PATCH 524/645] Move SliderFollowCircle implementation --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs | 3 +++ osu.Game/Skinning/LegacySkin.cs | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 0295a419ac..3c508f34e0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -59,6 +59,9 @@ namespace osu.Game.Rulesets.Osu.Skinning { switch (componentName) { + case "Play/osu/sliderfollowcircle": + return this.GetAnimation(componentName, true, true); + case "Play/osu/sliderball": var sliderBallContent = this.GetAnimation("sliderb", true, true, ""); diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 9a47e01f4e..1572c588e8 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -54,10 +54,6 @@ namespace osu.Game.Skinning switch (componentName) { - case "Play/osu/sliderfollowcircle": - animatable = true; - break; - case "Play/Miss": componentName = "hit0"; animatable = true; From 493fc5d400d616135e94291f6ec6f498cbd971da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 14:44:36 +0900 Subject: [PATCH 525/645] Bring back OsuPlayer test --- .../TestSceneOsuPlayer.cs | 148 +---------------- .../TestSceneSkinFallbacks.cs | 157 ++++++++++++++++++ 2 files changed, 161 insertions(+), 144 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs index d61378f4f8..1ba027ea4b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs @@ -1,157 +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 System; -using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Timing; -using osu.Game.Audio; -using osu.Game.Beatmaps; -using osu.Game.Configuration; -using osu.Game.Graphics; -using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Screens.Play; -using osu.Game.Skinning; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { - [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene - { - private readonly TestSource testUserSkin; - private readonly TestSource testBeatmapSkin; - - public TestSceneOsuPlayer() - : base(new OsuRuleset()) + [TestFixture] + public class TestSceneOsuPlayer : PlayerTestScene { - testUserSkin = new TestSource("user"); - testBeatmapSkin = new TestSource("beatmap"); - } - - [Test] - public void TestBeatmapSkinDefault() - { - AddStep("enable user provider", () => testUserSkin.Enabled = true); - - AddStep("enable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, true)); - checkNextHitObject("beatmap"); - - AddStep("disable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, false)); - checkNextHitObject("user"); - - AddStep("disable user provider", () => testUserSkin.Enabled = false); - checkNextHitObject(null); - } - - private void checkNextHitObject(string skin) => - AddUntilStep($"check skin from {skin}", () => + public TestSceneOsuPlayer() + : base(new OsuRuleset()) { - var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.OfType().FirstOrDefault(); - - if (firstObject == null) - return false; - - var skinnable = firstObject.ApproachCircle.Child as SkinnableDrawable; - - if (skin == null && skinnable?.Drawable is Sprite) - // check for default skin provider - return true; - - var text = skinnable?.Drawable as SpriteText; - - return text?.Text == skin; - }); - - [Resolved] - private AudioManager audio { get; set; } - - protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin); - - protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap) => new CustomSkinWorkingBeatmap(beatmap, Clock, audio, testBeatmapSkin); - - public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap - { - private readonly ISkinSource skin; - - public CustomSkinWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) - : base(beatmap, frameBasedClock, audio) - { - this.skin = skin; - } - - protected override ISkin GetSkin() => skin; - } - - public class SkinProvidingPlayer : TestPlayer - { - private readonly TestSource userSkin; - - public SkinProvidingPlayer(TestSource userSkin) - { - this.userSkin = userSkin; - } - - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - - dependencies.CacheAs(userSkin); - - return dependencies; } } - - public class TestSource : ISkinSource - { - private readonly string identifier; - - public TestSource(string identifier) - { - this.identifier = identifier; - } - - public Drawable GetDrawableComponent(string componentName) - { - if (!enabled) return null; - - return new SpriteText - { - Text = identifier, - Font = OsuFont.Default.With(size: 30), - }; - } - - public Texture GetTexture(string componentName) => null; - - public SampleChannel GetSample(ISampleInfo sampleInfo) => null; - - public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => default; - - public event Action SourceChanged; - - private bool enabled = true; - - public bool Enabled - { - get => enabled; - set - { - if (value == enabled) - return; - - enabled = value; - SourceChanged?.Invoke(); - } - } - } - } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs new file mode 100644 index 0000000000..24d0b39bed --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -0,0 +1,157 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Timing; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Screens.Play; +using osu.Game.Skinning; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public class TestSceneSkinFallbacks : PlayerTestScene + { + private readonly TestSource testUserSkin; + private readonly TestSource testBeatmapSkin; + + public TestSceneSkinFallbacks() + : base(new OsuRuleset()) + { + testUserSkin = new TestSource("user"); + testBeatmapSkin = new TestSource("beatmap"); + } + + [Test] + public void TestBeatmapSkinDefault() + { + AddStep("enable user provider", () => testUserSkin.Enabled = true); + + AddStep("enable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, true)); + checkNextHitObject("beatmap"); + + AddStep("disable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, false)); + checkNextHitObject("user"); + + AddStep("disable user provider", () => testUserSkin.Enabled = false); + checkNextHitObject(null); + } + + private void checkNextHitObject(string skin) => + AddUntilStep($"check skin from {skin}", () => + { + var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.OfType().FirstOrDefault(); + + if (firstObject == null) + return false; + + var skinnable = firstObject.ApproachCircle.Child as SkinnableDrawable; + + if (skin == null && skinnable?.Drawable is Sprite) + // check for default skin provider + return true; + + var text = skinnable?.Drawable as SpriteText; + + return text?.Text == skin; + }); + + [Resolved] + private AudioManager audio { get; set; } + + protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin); + + protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap) => new CustomSkinWorkingBeatmap(beatmap, Clock, audio, testBeatmapSkin); + + public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + { + private readonly ISkinSource skin; + + public CustomSkinWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin) + : base(beatmap, frameBasedClock, audio) + { + this.skin = skin; + } + + protected override ISkin GetSkin() => skin; + } + + public class SkinProvidingPlayer : TestPlayer + { + private readonly TestSource userSkin; + + public SkinProvidingPlayer(TestSource userSkin) + { + this.userSkin = userSkin; + } + + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + + dependencies.CacheAs(userSkin); + + return dependencies; + } + } + + public class TestSource : ISkinSource + { + private readonly string identifier; + + public TestSource(string identifier) + { + this.identifier = identifier; + } + + public Drawable GetDrawableComponent(string componentName) + { + if (!enabled) return null; + + return new SpriteText + { + Text = identifier, + Font = OsuFont.Default.With(size: 30), + }; + } + + public Texture GetTexture(string componentName) => null; + + public SampleChannel GetSample(ISampleInfo sampleInfo) => null; + + public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => default; + + public event Action SourceChanged; + + private bool enabled = true; + + public bool Enabled + { + get => enabled; + set + { + if (value == enabled) + return; + + enabled = value; + SourceChanged?.Invoke(); + } + } + } + } +} From c3fb4b9099c9f7dd7e0bd71f6ae14a61d66c6f3d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 14:51:47 +0900 Subject: [PATCH 526/645] Fix test failing --- osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 24d0b39bed..731b0a84e9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void checkNextHitObject(string skin) => AddUntilStep($"check skin from {skin}", () => { - var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.OfType().FirstOrDefault(); + var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType().FirstOrDefault(); if (firstObject == null) return false; From ae05faa6d2e96d49c0de9d2791d0bbb4d12c4e21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 14:54:46 +0900 Subject: [PATCH 527/645] Fix indentation --- osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs index 1ba027ea4b..0a33b09ba8 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs @@ -6,12 +6,12 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { - [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene + [TestFixture] + public class TestSceneOsuPlayer : PlayerTestScene + { + public TestSceneOsuPlayer() + : base(new OsuRuleset()) { - public TestSceneOsuPlayer() - : base(new OsuRuleset()) - { - } } + } } From a15828ab25d6b727618fe4159fbadacb90fc9de5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 14:39:02 +0900 Subject: [PATCH 528/645] Introduce the concept of SkinComponents Removes reliance on string lookups and better defines elements for introduction into database --- .../TestSceneCatcher.cs | 6 ++-- osu.Game.Rulesets.Catch/CatchRuleset.cs | 4 ++- osu.Game.Rulesets.Catch/CatchSkinComponent.cs | 19 ++++++++++++ .../CatchSkinComponents.cs | 10 +++++++ osu.Game.Rulesets.Catch/UI/CatcherSprite.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 4 ++- osu.Game.Rulesets.Mania/ManiaSkinComponent.cs | 19 ++++++++++++ .../ManiaSkinComponents.cs | 9 ++++++ .../TestSceneSkinFallbacks.cs | 2 +- .../Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/DrawableHitCircle.cs | 2 +- .../Objects/Drawables/DrawableRepeatPoint.cs | 2 +- .../Objects/Drawables/DrawableSliderTick.cs | 2 +- .../Drawables/Pieces/ApproachCircle.cs | 6 ++-- .../Objects/Drawables/Pieces/ExplodePiece.cs | 5 ++-- .../Objects/Drawables/Pieces/FlashPiece.cs | 5 ++-- .../Objects/Drawables/Pieces/GlowPiece.cs | 7 ++--- .../Objects/Drawables/Pieces/NumberPiece.cs | 6 ++-- .../Objects/Drawables/Pieces/RingPiece.cs | 5 ++-- .../Objects/Drawables/Pieces/SliderBall.cs | 4 +-- osu.Game.Rulesets.Osu/OsuRuleset.cs | 4 ++- osu.Game.Rulesets.Osu/OsuSkinComponent.cs | 19 ++++++++++++ osu.Game.Rulesets.Osu/OsuSkinComponents.cs | 18 +++++++++++ .../Skinning/LegacyMainCirclePiece.cs | 2 +- .../Skinning/OsuLegacySkin.cs | 22 +++++++------- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 4 ++- osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs | 19 ++++++++++++ .../TaikoSkinComponents.cs | 9 ++++++ .../Gameplay/TestSceneSkinnableDrawable.cs | 30 ++++++++++++++----- .../Rulesets/Judgements/DrawableJudgement.cs | 2 +- .../Skinning/BeatmapSkinProvidingContainer.cs | 2 +- osu.Game/Skinning/DefaultSkin.cs | 4 +-- osu.Game/Skinning/ISkin.cs | 2 +- osu.Game/Skinning/ISkinComponent.cs | 10 +++++++ osu.Game/Skinning/LegacySkin.cs | 29 +++++------------- osu.Game/Skinning/PlaySkinComponent.cs | 23 ++++++++++++++ osu.Game/Skinning/Skin.cs | 4 +-- osu.Game/Skinning/SkinManager.cs | 4 +-- osu.Game/Skinning/SkinProvidingContainer.cs | 8 ++--- osu.Game/Skinning/SkinnableDrawable.cs | 20 ++++++------- osu.Game/Skinning/SkinnableSprite.cs | 6 ++-- osu.Game/Skinning/SkinnableSpriteText.cs | 4 +-- 43 files changed, 264 insertions(+), 104 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/CatchSkinComponent.cs create mode 100644 osu.Game.Rulesets.Catch/CatchSkinComponents.cs create mode 100644 osu.Game.Rulesets.Mania/ManiaSkinComponent.cs create mode 100644 osu.Game.Rulesets.Mania/ManiaSkinComponents.cs create mode 100644 osu.Game.Rulesets.Osu/OsuSkinComponent.cs create mode 100644 osu.Game.Rulesets.Osu/OsuSkinComponents.cs create mode 100644 osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs create mode 100644 osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs create mode 100644 osu.Game/Skinning/ISkinComponent.cs create mode 100644 osu.Game/Skinning/PlaySkinComponent.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 406c0af28d..13286f4524 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; @@ -82,9 +82,9 @@ namespace osu.Game.Rulesets.Catch.Tests remove { } } - public Drawable GetDrawableComponent(string componentName) + public Drawable GetDrawableComponent(ISkinComponent component) { - switch (componentName) + switch (component.LookupName) { case "Play/Catch/fruit-catcher-idle": return new CatcherCustomSkin(); diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 71e05083be..cd2f8d56af 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Catch public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); + public const string SHORT_NAME = "catch"; + public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { new KeyBinding(InputKey.Z, CatchAction.MoveLeft), @@ -117,7 +119,7 @@ namespace osu.Game.Rulesets.Catch public override string Description => "osu!catch"; - public override string ShortName => "fruits"; + public override string ShortName => SHORT_NAME; public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch }; diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs new file mode 100644 index 0000000000..620720310f --- /dev/null +++ b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Catch +{ + public class CatchSkinComponent : PlaySkinComponent + { + public CatchSkinComponent(CatchSkinComponents component) + : base(component) + { + } + + protected override string RulesetPrefix => CatchRuleset.SHORT_NAME; + + protected override string ComponentName => Component.ToString().ToLower(); + } +} diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs new file mode 100644 index 0000000000..c03fe42af7 --- /dev/null +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.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.Rulesets.Catch +{ + public enum CatchSkinComponents + { + Catcher + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs b/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs index c0c1952064..1c2fe3517a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.UI [BackgroundDependencyLoader] private void load() { - InternalChild = new SkinnableSprite(@"Play/Catch/fruit-catcher-idle") + InternalChild = new SkinnableSprite(new CatchSkinComponent(CatchSkinComponents.Catcher)) { RelativeSizeAxes = Axes.Both, Anchor = Anchor.TopCentre, diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 0de86c2149..0c4e7d4858 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -35,6 +35,8 @@ namespace osu.Game.Rulesets.Mania public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); + public const string SHORT_NAME = "mania"; + public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this); public override IEnumerable ConvertLegacyMods(LegacyMods mods) @@ -163,7 +165,7 @@ namespace osu.Game.Rulesets.Mania public override string Description => "osu!mania"; - public override string ShortName => "mania"; + public override string ShortName => SHORT_NAME; public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania }; diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs new file mode 100644 index 0000000000..72a3ce7ad5 --- /dev/null +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Mania +{ + public class ManiaSkinComponent : PlaySkinComponent + { + public ManiaSkinComponent(ManiaSkinComponents component) + : base(component) + { + } + + protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME; + + protected override string ComponentName => Component.ToString().ToLower(); + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponents.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponents.cs new file mode 100644 index 0000000000..6d85816e5a --- /dev/null +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponents.cs @@ -0,0 +1,9 @@ +// 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.Rulesets.Mania +{ + public enum ManiaSkinComponents + { + } +} diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 731b0a84e9..fe73e7c861 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -119,7 +119,7 @@ namespace osu.Game.Rulesets.Osu.Tests this.identifier = identifier; } - public Drawable GetDrawableComponent(string componentName) + public Drawable GetDrawableComponent(ISkinComponent component) { if (!enabled) return null; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 523e911434..89ffddf4cb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections { Origin = Anchor.Centre; - Child = new SkinnableDrawable("Play/osu/followpoint", _ => new Container + Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new Container { Masking = true, AutoSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 0af278f6a4..22b12be030 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables return true; }, }, - mainContent = new SkinnableDrawable("Play/osu/hitcircle", _ => new MainCirclePiece(HitObject.IndexInCurrentCombo)), + mainContent = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.HitCircle), _ => new MainCirclePiece(HitObject.IndexInCurrentCombo)), ApproachCircle = new ApproachCircle { Alpha = 0, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 1db1eec33e..50187781f6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Blending = BlendingParameters.Additive; Origin = Anchor.Centre; - InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon + InternalChild = scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.ChevronRight, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 653e73ac3f..c5fa5f0af5 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Origin = Anchor.Centre; - InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/sliderscorepoint", _ => new CircularContainer + InternalChild = scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer { Masking = true, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs index 5813197336..c17c276205 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs @@ -31,13 +31,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private class SkinnableApproachCircle : SkinnableSprite { public SkinnableApproachCircle() - : base("Play/osu/approachcircle") + : base(new OsuSkinComponent(OsuSkinComponents.ApproachCircle)) { } - protected override Drawable CreateDefault(string name) + protected override Drawable CreateDefault(ISkinComponent component) { - var drawable = base.CreateDefault(name); + var drawable = base.CreateDefault(component); // account for the sprite being used for the default approach circle being taken from stable, // when hitcircles have 5px padding on each size. this should be removed if we update the sprite. diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs index 1d21347cba..6381ddca69 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs @@ -3,7 +3,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Skinning; using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces @@ -20,12 +19,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Blending = BlendingParameters.Additive; Alpha = 0; - Child = new SkinnableDrawable("Play/osu/hitcircle-explode", _ => new TrianglesPiece + Child = new TrianglesPiece { Blending = BlendingParameters.Additive, RelativeSizeAxes = Axes.Both, Alpha = 0.2f, - }, s => s.GetTexture("Play/osu/hitcircle") == null); + }; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs index 1e3af567fe..038a2299e9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osuTK; using osu.Framework.Graphics.Shapes; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { @@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Blending = BlendingParameters.Additive; Alpha = 0; - Child = new SkinnableDrawable("Play/osu/hitcircle-flash", name => new CircularContainer + Child = new CircularContainer { Masking = true, RelativeSizeAxes = Axes.Both, @@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { RelativeSizeAxes = Axes.Both } - }, s => s.GetTexture("Play/osu/hitcircle") == null); + }; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs index a36d9e96c8..00188689dd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { @@ -22,14 +21,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces [BackgroundDependencyLoader] private void load(TextureStore textures) { - Child = new SkinnableDrawable("Play/osu/ring-glow", name => new Sprite + Child = new Sprite { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Texture = textures.Get(name), + Texture = textures.Get("ring-glow"), Blending = BlendingParameters.Additive, Alpha = 0.5f - }, s => s.GetTexture("Play/osu/hitcircle") == null); + }; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs index e8dc63abca..62c4ba5ee3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new Drawable[] { - new SkinnableDrawable("Play/osu/number-glow", name => new CircularContainer + new CircularContainer { Masking = true, Origin = Anchor.Centre, @@ -41,8 +41,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Colour = Color4.White.Opacity(0.5f), }, Child = new Box() - }, s => s.GetTexture("Play/osu/hitcircle") == null), - number = new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText + }, + number = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs index 575f2c92c5..c97b74756a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics.Containers; using osuTK; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { @@ -19,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre; Origin = Anchor.Centre; - InternalChild = new SkinnableDrawable("Play/osu/hitcircleoverlay", _ => new Container + InternalChild = new Container { Masking = true, CornerRadius = Size.X / 2, @@ -35,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces RelativeSizeAxes = Axes.Both } } - }); + }; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 329aed7b81..7c871c6ccd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre, RelativeSizeAxes = Axes.Both, Alpha = 0, - Child = new SkinnableDrawable("Play/osu/sliderfollowcircle", _ => new DefaultFollowCircle()), + Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()), }, new CircularContainer { @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Child = new Container { RelativeSizeAxes = Axes.Both, - Child = new SkinnableDrawable("Play/osu/sliderball", _ => new DefaultSliderBall()), + Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()), } } }; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 49676933e1..27899ab56e 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -35,6 +35,8 @@ namespace osu.Game.Rulesets.Osu public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); + public const string SHORT_NAME = "osu"; + public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { new KeyBinding(InputKey.Z, OsuAction.LeftButton), @@ -161,7 +163,7 @@ namespace osu.Game.Rulesets.Osu public override string Description => "osu!"; - public override string ShortName => "osu"; + public override string ShortName => SHORT_NAME; public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this); diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs new file mode 100644 index 0000000000..ef0df6cbda --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Osu +{ + public class OsuSkinComponent : PlaySkinComponent + { + public OsuSkinComponent(OsuSkinComponents component) + : base(component) + { + } + + protected override string RulesetPrefix => OsuRuleset.SHORT_NAME; + + protected override string ComponentName => Component.ToString().ToLower(); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs new file mode 100644 index 0000000000..5971f053c2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuSkinComponents.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. + +namespace osu.Game.Rulesets.Osu +{ + public enum OsuSkinComponents + { + HitCircle, + FollowPoint, + Cursor, + SliderScorePoint, + ApproachCircle, + ReverseArrow, + HitCircleText, + SliderFollowCircle, + SliderBall + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index a7906ddd24..83d507f64b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Skinning Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText + new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 3c508f34e0..002b3f8cda 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -55,14 +55,17 @@ namespace osu.Game.Rulesets.Osu.Skinning hasHitCircle = new Lazy(() => source.GetTexture("hitcircle") != null); } - public Drawable GetDrawableComponent(string componentName) + public Drawable GetDrawableComponent(ISkinComponent component) { - switch (componentName) - { - case "Play/osu/sliderfollowcircle": - return this.GetAnimation(componentName, true, true); + if (!(component is OsuSkinComponent osuComponent)) + return null; - case "Play/osu/sliderball": + switch (osuComponent.Component) + { + case OsuSkinComponents.SliderFollowCircle: + return this.GetAnimation("sliderfollowcircle", true, true); + + case OsuSkinComponents.SliderBall: var sliderBallContent = this.GetAnimation("sliderb", true, true, ""); if (sliderBallContent != null) @@ -80,20 +83,19 @@ namespace osu.Game.Rulesets.Osu.Skinning return null; - case "Play/osu/hitcircle": + case OsuSkinComponents.HitCircle: if (hasHitCircle.Value) return new LegacyMainCirclePiece(); return null; - case "Play/osu/cursor": + case OsuSkinComponents.Cursor: if (source.GetTexture("cursor") != null) return new LegacyCursor(); return null; - case "Play/osu/number-text": - + case OsuSkinComponents.HitCircleText: string font = GetValue(config => config.HitCircleFont); var overlap = GetValue(config => config.HitCircleOverlap); diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index eb1977a13d..869c27dcac 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, - Child = scaleTarget = new SkinnableDrawable("Play/osu/cursor", _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) + Child = scaleTarget = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 6d0a5eb1e1..7fdb823388 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Taiko public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableTaikoRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); + public const string SHORT_NAME = "taiko"; + public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { new KeyBinding(InputKey.MouseLeft, TaikoAction.LeftCentre), @@ -116,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko public override string Description => "osu!taiko"; - public override string ShortName => "taiko"; + public override string ShortName => SHORT_NAME; public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetTaiko }; diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs new file mode 100644 index 0000000000..474154279c --- /dev/null +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Taiko +{ + public class TaikoSkinComponent : PlaySkinComponent + { + public TaikoSkinComponent(TaikoSkinComponents component) + : base(component) + { + } + + protected override string RulesetPrefix => TaikoRuleset.SHORT_NAME; + + protected override string ComponentName => Component.ToString().ToLower(); + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs new file mode 100644 index 0000000000..04aca534c6 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs @@ -0,0 +1,9 @@ +// 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.Rulesets.Taiko +{ + public enum TaikoSkinComponents + { + } +} diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index 96dc864577..ee5552c6e0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -137,8 +137,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public new Drawable Drawable => base.Drawable; - public ExposedSkinnableDrawable(string name, Func defaultImplementation, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) - : base(name, defaultImplementation, allowFallback, confineMode) + public ExposedSkinnableDrawable(string name, Func defaultImplementation, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) + : base(new TestSkinComponent(name), defaultImplementation, allowFallback, confineMode) { } } @@ -206,8 +206,8 @@ namespace osu.Game.Tests.Visual.Gameplay public new Drawable Drawable => base.Drawable; public int SkinChangedCount { get; private set; } - public SkinConsumer(string name, Func defaultImplementation, Func allowFallback = null) - : base(name, defaultImplementation, allowFallback) + public SkinConsumer(string name, Func defaultImplementation, Func allowFallback = null) + : base(new TestSkinComponent(name), defaultImplementation, allowFallback) { } @@ -243,8 +243,8 @@ namespace osu.Game.Tests.Visual.Gameplay this.size = size; } - public Drawable GetDrawableComponent(string componentName) => - componentName == "available" + public Drawable GetDrawableComponent(ISkinComponent componentName) => + componentName.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, @@ -261,7 +261,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class SecondarySource : ISkin { - public Drawable GetDrawableComponent(string componentName) => new SecondarySourceBox(); + public Drawable GetDrawableComponent(ISkinComponent componentName) => new SecondarySourceBox(); public Texture GetTexture(string componentName) => throw new NotImplementedException(); @@ -272,7 +272,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class SkinSourceContainer : Container, ISkin { - public Drawable GetDrawableComponent(string componentName) => new BaseSourceBox(); + public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox(); public Texture GetTexture(string componentName) => throw new NotImplementedException(); @@ -280,5 +280,19 @@ namespace osu.Game.Tests.Visual.Gameplay public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); } + + private class TestSkinComponent : ISkinComponent + { + private readonly string name; + + public TestSkinComponent(string name) + { + this.name = name; + } + + public string ComponentGroup => string.Empty; + + public string LookupName => name; + } } } diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 61c2644c6f..ecbdc53493 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Judgements Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Child = new SkinnableDrawable($"Play/{Result.Type}", _ => JudgementText = new OsuSpriteText + Child = new SkinnableDrawable(new PlaySkinComponent(Result.Type), _ => JudgementText = new OsuSpriteText { Text = Result.Type.GetDescription().ToUpperInvariant(), Font = OsuFont.Numeric.With(size: 12), diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index 345df35b12..40335db697 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Skinning private readonly Bindable beatmapHitsounds = new Bindable(); protected override bool AllowConfigurationLookup => beatmapSkins.Value; - protected override bool AllowDrawableLookup(string componentName) => beatmapSkins.Value; + protected override bool AllowDrawableLookup(ISkinComponent component) => beatmapSkins.Value; protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value; protected override bool AllowSampleLookup(ISampleInfo componentName) => beatmapHitsounds.Value; diff --git a/osu.Game/Skinning/DefaultSkin.cs b/osu.Game/Skinning/DefaultSkin.cs index 6072bb64ed..f917514877 100644 --- a/osu.Game/Skinning/DefaultSkin.cs +++ b/osu.Game/Skinning/DefaultSkin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Audio.Sample; @@ -16,7 +16,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); } - public override Drawable GetDrawableComponent(string componentName) => null; + public override Drawable GetDrawableComponent(ISkinComponent component) => null; public override Texture GetTexture(string componentName) => null; diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index 4867aba0a9..bc1ae634c9 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -14,7 +14,7 @@ namespace osu.Game.Skinning /// public interface ISkin { - Drawable GetDrawableComponent(string componentName); + Drawable GetDrawableComponent(ISkinComponent component); Texture GetTexture(string componentName); diff --git a/osu.Game/Skinning/ISkinComponent.cs b/osu.Game/Skinning/ISkinComponent.cs new file mode 100644 index 0000000000..4bd9f21b6b --- /dev/null +++ b/osu.Game/Skinning/ISkinComponent.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.Skinning +{ + public interface ISkinComponent + { + string LookupName { get; } + } +} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 1572c588e8..179b93d405 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -47,39 +47,24 @@ namespace osu.Game.Skinning Samples?.Dispose(); } - public override Drawable GetDrawableComponent(string componentName) + public override Drawable GetDrawableComponent(ISkinComponent component) { - bool animatable = false; - bool looping = true; - - switch (componentName) + switch (component.LookupName) { case "Play/Miss": - componentName = "hit0"; - animatable = true; - looping = false; - break; + return this.GetAnimation("hit0", true, false); case "Play/Meh": - componentName = "hit50"; - animatable = true; - looping = false; - break; + return this.GetAnimation("hit50", true, false); case "Play/Good": - componentName = "hit100"; - animatable = true; - looping = false; - break; + return this.GetAnimation("hit100", true, false); case "Play/Great": - componentName = "hit300"; - animatable = true; - looping = false; - break; + return this.GetAnimation("hit300", true, false); } - return this.GetAnimation(componentName, animatable, looping); + return this.GetAnimation(component.LookupName, false, false); } public override Texture GetTexture(string componentName) diff --git a/osu.Game/Skinning/PlaySkinComponent.cs b/osu.Game/Skinning/PlaySkinComponent.cs new file mode 100644 index 0000000000..f228d5cf9c --- /dev/null +++ b/osu.Game/Skinning/PlaySkinComponent.cs @@ -0,0 +1,23 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; + +namespace osu.Game.Skinning +{ + public class PlaySkinComponent : ISkinComponent where T : struct + { + public readonly T Component; + + public PlaySkinComponent(T component) + { + this.Component = component; + } + + protected virtual string RulesetPrefix => string.Empty; + protected virtual string ComponentName => Component.ToString(); + + public string LookupName => + string.Join("/", new[] { "Play", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s))); + } +} diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 027d9df8b8..299f257e57 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -15,7 +15,7 @@ namespace osu.Game.Skinning public virtual SkinConfiguration Configuration { get; protected set; } - public abstract Drawable GetDrawableComponent(string componentName); + public abstract Drawable GetDrawableComponent(ISkinComponent componentName); public abstract SampleChannel GetSample(ISampleInfo sampleInfo); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index a713933c6e..a55a128dff 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -125,7 +125,7 @@ namespace osu.Game.Skinning public event Action SourceChanged; - public Drawable GetDrawableComponent(string componentName) => CurrentSkin.Value.GetDrawableComponent(componentName); + public Drawable GetDrawableComponent(ISkinComponent component) => CurrentSkin.Value.GetDrawableComponent(component); public Texture GetTexture(string componentName) => CurrentSkin.Value.GetTexture(componentName); diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 45b8baa0bb..85a80655ea 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Skinning private ISkinSource fallbackSource; - protected virtual bool AllowDrawableLookup(string componentName) => true; + protected virtual bool AllowDrawableLookup(ISkinComponent component) => true; protected virtual bool AllowTextureLookup(string componentName) => true; @@ -37,13 +37,13 @@ namespace osu.Game.Skinning RelativeSizeAxes = Axes.Both; } - public Drawable GetDrawableComponent(string componentName) + public Drawable GetDrawableComponent(ISkinComponent component) { Drawable sourceDrawable; - if (AllowDrawableLookup(componentName) && (sourceDrawable = skin?.GetDrawableComponent(componentName)) != null) + if (AllowDrawableLookup(component) && (sourceDrawable = skin?.GetDrawableComponent(component)) != null) return sourceDrawable; - return fallbackSource?.GetDrawableComponent(componentName); + return fallbackSource?.GetDrawableComponent(component); } public Texture GetTexture(string componentName) diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 07f802944b..9ca5d60cb0 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -18,39 +18,39 @@ namespace osu.Game.Skinning /// public Drawable Drawable { get; private set; } - private readonly string componentName; + private readonly ISkinComponent component; private readonly ConfineMode confineMode; /// /// Create a new skinnable drawable. /// - /// The namespace-complete resource name for this skinnable element. + /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(string name, Func defaultImplementation, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) - : this(name, allowFallback, confineMode) + public SkinnableDrawable(ISkinComponent component, Func defaultImplementation, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) + : this(component, allowFallback, confineMode) { createDefault = defaultImplementation; } - protected SkinnableDrawable(string name, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) + protected SkinnableDrawable(ISkinComponent component, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) : base(allowFallback) { - componentName = name; + this.component = component; this.confineMode = confineMode; RelativeSizeAxes = Axes.Both; } - private readonly Func createDefault; + private readonly Func createDefault; private readonly Cached scaling = new Cached(); private bool isDefault; - protected virtual Drawable CreateDefault(string name) => createDefault(name); + protected virtual Drawable CreateDefault(ISkinComponent component) => createDefault(component); /// /// Whether to apply size restrictions (specified via ) to the default implementation. @@ -59,13 +59,13 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - Drawable = skin.GetDrawableComponent(componentName); + Drawable = skin.GetDrawableComponent(component); isDefault = false; if (Drawable == null && allowFallback) { - Drawable = CreateDefault(componentName); + Drawable = CreateDefault(component); isDefault = true; } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 07ba48d6ae..0081aef520 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -19,11 +19,11 @@ namespace osu.Game.Skinning [Resolved] private TextureStore textures { get; set; } - public SkinnableSprite(string name, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) - : base(name, allowFallback, confineMode) + public SkinnableSprite(ISkinComponent component, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) + : base(component, allowFallback, confineMode) { } - protected override Drawable CreateDefault(string name) => new Sprite { Texture = textures.Get(name) }; + protected override Drawable CreateDefault(ISkinComponent component) => new Sprite { Texture = textures.Get(component.LookupName) }; } } diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 5af6df15e1..e72f9c9811 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -8,8 +8,8 @@ namespace osu.Game.Skinning { public class SkinnableSpriteText : SkinnableDrawable, IHasText { - public SkinnableSpriteText(string name, Func defaultImplementation, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) - : base(name, defaultImplementation, allowFallback, confineMode) + public SkinnableSpriteText(ISkinComponent component, Func defaultImplementation, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) + : base(component, defaultImplementation, allowFallback, confineMode) { } From a7c94c388307e02980a172ca357bb3da1fd78f63 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 15:12:03 +0900 Subject: [PATCH 529/645] Simplify hit result lookups --- osu.Game/Skinning/LegacySkin.cs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 179b93d405..e51bf8245c 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Audio; +using osu.Game.Rulesets.Scoring; using osuTK.Graphics; namespace osu.Game.Skinning @@ -49,19 +50,25 @@ namespace osu.Game.Skinning public override Drawable GetDrawableComponent(ISkinComponent component) { - switch (component.LookupName) + switch (component) { - case "Play/Miss": - return this.GetAnimation("hit0", true, false); + case PlaySkinComponent resultComponent: + switch (resultComponent.Component) + { + case HitResult.Miss: + return this.GetAnimation("hit0", true, false); - case "Play/Meh": - return this.GetAnimation("hit50", true, false); + case HitResult.Meh: + return this.GetAnimation("hit50", true, false); - case "Play/Good": - return this.GetAnimation("hit100", true, false); + case HitResult.Good: + return this.GetAnimation("hit100", true, false); - case "Play/Great": - return this.GetAnimation("hit300", true, false); + case HitResult.Great: + return this.GetAnimation("hit300", true, false); + } + + break; } return this.GetAnimation(component.LookupName, false, false); From 70e417533f47009049075747a8bc87636b633b53 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 15:10:11 +0900 Subject: [PATCH 530/645] Update naming --- osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs | 4 ++-- osu.Game.Rulesets.Catch/CatchSkinComponent.cs | 2 +- osu.Game.Rulesets.Mania/ManiaSkinComponent.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 2 +- .../Objects/Drawables/Pieces/CirclePiece.cs | 2 +- osu.Game.Rulesets.Osu/OsuSkinComponent.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 8 ++++---- osu.Game/Rulesets/Judgements/DrawableJudgement.cs | 2 +- .../{PlaySkinComponent.cs => GameplaySkinComponent.cs} | 6 +++--- osu.Game/Skinning/LegacySkin.cs | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) rename osu.Game/Skinning/{PlaySkinComponent.cs => GameplaySkinComponent.cs} (66%) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 13286f4524..c89cd95f36 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Tests { switch (component.LookupName) { - case "Play/Catch/fruit-catcher-idle": + case "Gameplay/Catch/fruit-catcher-idle": return new CatcherCustomSkin(); } diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs index 620720310f..0a3e43dcfc 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs @@ -5,7 +5,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { - public class CatchSkinComponent : PlaySkinComponent + public class CatchSkinComponent : GameplaySkinComponent { public CatchSkinComponent(CatchSkinComponents component) : base(component) diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs index 72a3ce7ad5..69bd4b0ecf 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs @@ -5,7 +5,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { - public class ManiaSkinComponent : PlaySkinComponent + public class ManiaSkinComponent : GameplaySkinComponent { public ManiaSkinComponent(ManiaSkinComponents component) : base(component) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index 445f81c6d4..1eb37f8119 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Osu.Mods [BackgroundDependencyLoader] private void load(TextureStore textures) { - Texture = textures.Get("Play/osu/blinds-panel"); + Texture = textures.Get("Gameplay/osu/blinds-panel"); } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs index a59cfc1123..210d5ff839 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Texture = textures.Get(@"Play/osu/disc"), + Texture = textures.Get(@"Gameplay/osu/disc"), }, new TrianglesPiece { diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs index ef0df6cbda..1d223f231b 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs @@ -5,7 +5,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { - public class OsuSkinComponent : PlaySkinComponent + public class OsuSkinComponent : GameplaySkinComponent { public OsuSkinComponent(OsuSkinComponents component) : base(component) diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs index 474154279c..e6e4bc0dd7 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs @@ -5,7 +5,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko { - public class TaikoSkinComponent : PlaySkinComponent + public class TaikoSkinComponent : GameplaySkinComponent { public TaikoSkinComponent(TaikoSkinComponents component) : base(component) diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index d6866c7d25..9766da9a24 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -132,10 +132,10 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(TextureStore textures, OsuColour colours) { - rim.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer"); - rimHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer-hit"); - centre.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner"); - centreHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner-hit"); + rim.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer"); + rimHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer-hit"); + centre.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner"); + centreHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner-hit"); rimHit.Colour = colours.Blue; centreHit.Colour = colours.Pink; diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index ecbdc53493..4f8cb7660b 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Judgements Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Child = new SkinnableDrawable(new PlaySkinComponent(Result.Type), _ => JudgementText = new OsuSpriteText + Child = new SkinnableDrawable(new GameplaySkinComponent(Result.Type), _ => JudgementText = new OsuSpriteText { Text = Result.Type.GetDescription().ToUpperInvariant(), Font = OsuFont.Numeric.With(size: 12), diff --git a/osu.Game/Skinning/PlaySkinComponent.cs b/osu.Game/Skinning/GameplaySkinComponent.cs similarity index 66% rename from osu.Game/Skinning/PlaySkinComponent.cs rename to osu.Game/Skinning/GameplaySkinComponent.cs index f228d5cf9c..da65084a1d 100644 --- a/osu.Game/Skinning/PlaySkinComponent.cs +++ b/osu.Game/Skinning/GameplaySkinComponent.cs @@ -5,11 +5,11 @@ using System.Linq; namespace osu.Game.Skinning { - public class PlaySkinComponent : ISkinComponent where T : struct + public class GameplaySkinComponent : ISkinComponent where T : struct { public readonly T Component; - public PlaySkinComponent(T component) + public GameplaySkinComponent(T component) { this.Component = component; } @@ -18,6 +18,6 @@ namespace osu.Game.Skinning protected virtual string ComponentName => Component.ToString(); public string LookupName => - string.Join("/", new[] { "Play", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s))); + string.Join("/", new[] { "Gameplay", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s))); } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index e51bf8245c..753b2ba41b 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -52,7 +52,7 @@ namespace osu.Game.Skinning { switch (component) { - case PlaySkinComponent resultComponent: + case GameplaySkinComponent resultComponent: switch (resultComponent.Component) { case HitResult.Miss: From 835ee0aa2fbd75ed38782a54750135131396e708 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 15:29:13 +0900 Subject: [PATCH 531/645] Code quality fixes --- .../Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index fae1b68e4a..fbd6aedd45 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -18,10 +18,13 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private const int margin = 10; private readonly Bindable type = new Bindable(); + private readonly HitWindows hitWindows; + private readonly ScoreProcessor processor; private BarHitErrorDisplay leftDisplay; + private BarHitErrorDisplay rightDisplay; public HitErrorDisplayOverlay(ScoreProcessor processor) @@ -40,10 +43,10 @@ namespace osu.Game.Screens.Play.HitErrorDisplay protected override void LoadComplete() { base.LoadComplete(); - type.BindValueChanged(onTypeChanged, true); + type.BindValueChanged(typeChanged, true); } - private void onTypeChanged(ValueChangedEvent type) + private void typeChanged(ValueChangedEvent type) { switch (type.NewValue) { From fe90e194e37b977ebcd2232f0af0b5177efef571 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 15:29:44 +0900 Subject: [PATCH 532/645] Remove redundant qualifier --- osu.Game/Skinning/PlaySkinComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/PlaySkinComponent.cs b/osu.Game/Skinning/PlaySkinComponent.cs index f228d5cf9c..68b67ee0c5 100644 --- a/osu.Game/Skinning/PlaySkinComponent.cs +++ b/osu.Game/Skinning/PlaySkinComponent.cs @@ -11,7 +11,7 @@ namespace osu.Game.Skinning public PlaySkinComponent(T component) { - this.Component = component; + Component = component; } protected virtual string RulesetPrefix => string.Empty; From bdbfa7bd2f5a4afde5c21478144f76a49dc25b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 15:32:47 +0900 Subject: [PATCH 533/645] Fix class naming --- ...isplay.cs => TestSceneBarHitErrorMeter.cs} | 12 +- osu.Game/Screens/Play/HUDOverlay.cs | 7 +- ...HitErrorDisplay.cs => BarHitErrorMeter.cs} | 4 +- .../Play/HitErrorDisplay/HitErrorDisplay.cs | 120 +++++++++++++++- .../HitErrorDisplay/HitErrorDisplayOverlay.cs | 129 ------------------ .../Play/HitErrorDisplay/HitErrorMeter.cs | 21 +++ 6 files changed, 146 insertions(+), 147 deletions(-) rename osu.Game.Tests/Visual/Gameplay/{TestSceneHitErrorDisplay.cs => TestSceneBarHitErrorMeter.cs} (94%) rename osu.Game/Screens/Play/HitErrorDisplay/{BarHitErrorDisplay.cs => BarHitErrorMeter.cs} (98%) delete mode 100644 osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs create mode 100644 osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs similarity index 94% rename from osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index a148bdad67..aac9e206c3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -19,16 +19,16 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneHitErrorDisplay : OsuTestScene + public class TestSceneBarHitErrorMeter : OsuTestScene { public override IReadOnlyList RequiredTypes => new[] { - typeof(HitErrorDisplay), + typeof(HitErrorMeter), }; - private HitErrorDisplay display; + private HitErrorMeter meter; - public TestSceneHitErrorDisplay() + public TestSceneBarHitErrorMeter() { recreateDisplay(new OsuHitWindows(), 5); AddStep("New random judgement", () => newJudgement()); @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Add(display = new BarHitErrorDisplay(hitWindows) + Add(meter = new BarHitErrorMeter(hitWindows) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -124,7 +124,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void newJudgement(float offset = 0) { - display?.OnNewJudgement(new JudgementResult(new Judgement()) + meter?.OnNewJudgement(new JudgementResult(new Judgement()) { TimeOffset = offset == 0 ? RNG.Next(-70, 70) : offset, Type = HitResult.Perfect, diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 02432cf64e..79392221e4 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -15,7 +15,6 @@ using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play.HitErrorDisplay; using osu.Game.Screens.Play.HUD; using osuTK; using osuTK.Input; @@ -34,7 +33,7 @@ namespace osu.Game.Screens.Play public readonly HealthDisplay HealthDisplay; public readonly SongProgress Progress; public readonly ModDisplay ModDisplay; - public readonly HitErrorDisplayOverlay HitErrorDisplayOverlay; + public readonly HitErrorDisplay.HitErrorDisplay HitErrorDisplay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; @@ -86,7 +85,7 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), - HitErrorDisplayOverlay = CreateHitErrorDisplayOverlay(), + HitErrorDisplay = CreateHitErrorDisplayOverlay(), } }, PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), @@ -259,7 +258,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplayOverlay CreateHitErrorDisplayOverlay() => new HitErrorDisplayOverlay(scoreProcessor) + protected virtual HitErrorDisplay.HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay.HitErrorDisplay(scoreProcessor) { RelativeSizeAxes = Axes.Both, }; diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs similarity index 98% rename from osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs rename to osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs index 85d017073a..3ec3740816 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs @@ -18,7 +18,7 @@ using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { - public class BarHitErrorDisplay : HitErrorDisplay + public class BarHitErrorMeter : HitErrorMeter { /// /// The amount of which will be stored to calculate arrow position. @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly List judgementOffsets = new List(); private readonly double maxHitWindows; - public BarHitErrorDisplay(HitWindows hitWindows, bool reversed = false) + public BarHitErrorMeter(HitWindows hitWindows, bool reversed = false) : base(hitWindows) { maxHitWindows = HitWindows.Meh == 0 ? HitWindows.Good : HitWindows.Meh; diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs index 422e151d8a..5c884f3f53 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs @@ -2,20 +2,128 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Judgements; +using osu.Framework.Graphics; +using osu.Game.Rulesets.Scoring; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Play.HitErrorDisplay { - public abstract class HitErrorDisplay : CompositeDrawable + public class HitErrorDisplay : Container { - protected readonly HitWindows HitWindows; + private const int fade_duration = 200; + private const int margin = 10; - protected HitErrorDisplay(HitWindows hitWindows) + private readonly Bindable type = new Bindable(); + + private readonly HitWindows hitWindows; + + private readonly ScoreProcessor processor; + + private BarHitErrorMeter leftMeter; + + private BarHitErrorMeter rightMeter; + + public HitErrorDisplay(ScoreProcessor processor) { - HitWindows = hitWindows; + this.processor = processor; + hitWindows = processor.CreateHitWindows(); } - public abstract void OnNewJudgement(JudgementResult newJudgement); + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, Bindable workingBeatmap) + { + config.BindWith(OsuSetting.ScoreMeter, type); + hitWindows.SetDifficulty(workingBeatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + type.BindValueChanged(typeChanged, true); + } + + private void typeChanged(ValueChangedEvent type) + { + switch (type.NewValue) + { + case ScoreMeterType.None: + removeLeftDisplay(); + removeRightDisplay(); + break; + + case ScoreMeterType.HitErrorBoth: + addLeftDisplay(); + addRightDisplay(); + break; + + case ScoreMeterType.HitErrorLeft: + addLeftDisplay(); + removeRightDisplay(); + break; + + case ScoreMeterType.HitErrorRight: + addRightDisplay(); + removeLeftDisplay(); + break; + } + } + + private void addLeftDisplay() + { + if (leftMeter != null) + return; + + leftMeter = createNew(); + } + + private void addRightDisplay() + { + if (rightMeter != null) + return; + + rightMeter = createNew(true); + } + + private void removeRightDisplay() + { + if (rightMeter == null) + return; + + processor.NewJudgement -= rightMeter.OnNewJudgement; + + rightMeter.FadeOut(fade_duration, Easing.OutQuint).Expire(); + rightMeter = null; + } + + private void removeLeftDisplay() + { + if (leftMeter == null) + return; + + processor.NewJudgement -= leftMeter.OnNewJudgement; + + leftMeter.FadeOut(fade_duration, Easing.OutQuint).Expire(); + leftMeter = null; + } + + private BarHitErrorMeter createNew(bool reversed = false) + { + var display = new BarHitErrorMeter(hitWindows, reversed) + { + Margin = new MarginPadding(margin), + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Alpha = 0, + }; + + processor.NewJudgement += display.OnNewJudgement; + Add(display); + display.FadeInFromZero(fade_duration, Easing.OutQuint); + return display; + } } } diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs deleted file mode 100644 index fbd6aedd45..0000000000 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics; -using osu.Game.Rulesets.Scoring; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Game.Beatmaps; -using osu.Game.Configuration; -using osu.Game.Rulesets.Objects; - -namespace osu.Game.Screens.Play.HitErrorDisplay -{ - public class HitErrorDisplayOverlay : Container - { - private const int fade_duration = 200; - private const int margin = 10; - - private readonly Bindable type = new Bindable(); - - private readonly HitWindows hitWindows; - - private readonly ScoreProcessor processor; - - private BarHitErrorDisplay leftDisplay; - - private BarHitErrorDisplay rightDisplay; - - public HitErrorDisplayOverlay(ScoreProcessor processor) - { - this.processor = processor; - hitWindows = processor.CreateHitWindows(); - } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config, Bindable workingBeatmap) - { - config.BindWith(OsuSetting.ScoreMeter, type); - hitWindows.SetDifficulty(workingBeatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - type.BindValueChanged(typeChanged, true); - } - - private void typeChanged(ValueChangedEvent type) - { - switch (type.NewValue) - { - case ScoreMeterType.None: - removeLeftDisplay(); - removeRightDisplay(); - break; - - case ScoreMeterType.HitErrorBoth: - addLeftDisplay(); - addRightDisplay(); - break; - - case ScoreMeterType.HitErrorLeft: - addLeftDisplay(); - removeRightDisplay(); - break; - - case ScoreMeterType.HitErrorRight: - addRightDisplay(); - removeLeftDisplay(); - break; - } - } - - private void addLeftDisplay() - { - if (leftDisplay != null) - return; - - leftDisplay = createNew(); - } - - private void addRightDisplay() - { - if (rightDisplay != null) - return; - - rightDisplay = createNew(true); - } - - private void removeRightDisplay() - { - if (rightDisplay == null) - return; - - processor.NewJudgement -= rightDisplay.OnNewJudgement; - - rightDisplay.FadeOut(fade_duration, Easing.OutQuint).Expire(); - rightDisplay = null; - } - - private void removeLeftDisplay() - { - if (leftDisplay == null) - return; - - processor.NewJudgement -= leftDisplay.OnNewJudgement; - - leftDisplay.FadeOut(fade_duration, Easing.OutQuint).Expire(); - leftDisplay = null; - } - - private BarHitErrorDisplay createNew(bool reversed = false) - { - var display = new BarHitErrorDisplay(hitWindows, reversed) - { - Margin = new MarginPadding(margin), - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Alpha = 0, - }; - - processor.NewJudgement += display.OnNewJudgement; - Add(display); - display.FadeInFromZero(fade_duration, Easing.OutQuint); - return display; - } - } -} diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs new file mode 100644 index 0000000000..848e892eaa --- /dev/null +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Screens.Play.HitErrorDisplay +{ + public abstract class HitErrorMeter : CompositeDrawable + { + protected readonly HitWindows HitWindows; + + protected HitErrorMeter(HitWindows hitWindows) + { + HitWindows = hitWindows; + } + + public abstract void OnNewJudgement(JudgementResult newJudgement); + } +} From 6640161bc1fde5e88fff7e1084c83468670660ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 15:51:36 +0900 Subject: [PATCH 534/645] Simplify event propagation --- .../Play/HitErrorDisplay/BarHitErrorMeter.cs | 16 ++-- .../Play/HitErrorDisplay/HitErrorDisplay.cs | 90 ++++++------------- 2 files changed, 36 insertions(+), 70 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs index 3ec3740816..b00f3f6f5f 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly List judgementOffsets = new List(); private readonly double maxHitWindows; - public BarHitErrorMeter(HitWindows hitWindows, bool reversed = false) + public BarHitErrorMeter(HitWindows hitWindows, bool rightAligned = false) : base(hitWindows) { maxHitWindows = HitWindows.Meh == 0 ? HitWindows.Good : HitWindows.Meh; @@ -54,23 +54,23 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { judgementsContainer = new Container { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, Width = judgement_line_width, RelativeSizeAxes = Axes.Y, }, bar = new FillFlowContainer { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, Width = bar_width, RelativeSizeAxes = Axes.Y, Direction = FillDirection.Vertical, }, new Container { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, AutoSizeAxes = Axes.X, RelativeSizeAxes = Axes.Y, Child = arrow = new SpriteIcon @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativePositionAxes = Axes.Y, - Icon = reversed ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, + Icon = rightAligned ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, Size = new Vector2(8), } }, diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs index 5c884f3f53..eaaf8e810c 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs @@ -1,13 +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 System.Linq; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Play.HitErrorDisplay @@ -19,25 +22,33 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly Bindable type = new Bindable(); - private readonly HitWindows hitWindows; + private HitWindows hitWindows; private readonly ScoreProcessor processor; - private BarHitErrorMeter leftMeter; - - private BarHitErrorMeter rightMeter; - public HitErrorDisplay(ScoreProcessor processor) { this.processor = processor; - hitWindows = processor.CreateHitWindows(); + processor.NewJudgement += onNewJudgement; + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + processor.NewJudgement -= onNewJudgement; + } + + private void onNewJudgement(JudgementResult result) + { + foreach (var c in Children) + c.OnNewJudgement(result); } [BackgroundDependencyLoader] private void load(OsuConfigManager config, Bindable workingBeatmap) { config.BindWith(OsuSetting.ScoreMeter, type); - hitWindows.SetDifficulty(workingBeatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); + hitWindows = workingBeatmap.Value.Beatmap.HitObjects.First().HitWindows; } protected override void LoadComplete() @@ -48,82 +59,37 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private void typeChanged(ValueChangedEvent type) { + Children.ForEach(c => c.FadeOut(fade_duration, Easing.OutQuint)); + switch (type.NewValue) { - case ScoreMeterType.None: - removeLeftDisplay(); - removeRightDisplay(); - break; - case ScoreMeterType.HitErrorBoth: - addLeftDisplay(); - addRightDisplay(); + createBar(false); + createBar(true); break; case ScoreMeterType.HitErrorLeft: - addLeftDisplay(); - removeRightDisplay(); + createBar(false); break; case ScoreMeterType.HitErrorRight: - addRightDisplay(); - removeLeftDisplay(); + createBar(true); break; } } - private void addLeftDisplay() + private void createBar(bool rightAligned) { - if (leftMeter != null) - return; - - leftMeter = createNew(); - } - - private void addRightDisplay() - { - if (rightMeter != null) - return; - - rightMeter = createNew(true); - } - - private void removeRightDisplay() - { - if (rightMeter == null) - return; - - processor.NewJudgement -= rightMeter.OnNewJudgement; - - rightMeter.FadeOut(fade_duration, Easing.OutQuint).Expire(); - rightMeter = null; - } - - private void removeLeftDisplay() - { - if (leftMeter == null) - return; - - processor.NewJudgement -= leftMeter.OnNewJudgement; - - leftMeter.FadeOut(fade_duration, Easing.OutQuint).Expire(); - leftMeter = null; - } - - private BarHitErrorMeter createNew(bool reversed = false) - { - var display = new BarHitErrorMeter(hitWindows, reversed) + var display = new BarHitErrorMeter(hitWindows, rightAligned) { Margin = new MarginPadding(margin), - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, Alpha = 0, }; - processor.NewJudgement += display.OnNewJudgement; Add(display); display.FadeInFromZero(fade_duration, Easing.OutQuint); - return display; } } } From b03b520818eb2e9474fa7f7ea7daf01c287263b5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 30 Aug 2019 10:13:21 +0300 Subject: [PATCH 535/645] Move Absing from the APIKudosuHistory --- osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs | 6 ------ .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index 19ce11aa13..67ff20e6c2 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -13,12 +13,6 @@ namespace osu.Game.Online.API.Requests.Responses public DateTimeOffset CreatedAt; [JsonProperty("amount")] - private int amount - { - //We can receive negative values. However "action" is enough to build needed items - set => Amount = Math.Abs(value); - } - public int Amount; [JsonProperty("post")] diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index fb7d597012..94733324ba 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; +using System; namespace osu.Game.Overlays.Profile.Sections.Kudosu { @@ -56,7 +57,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu if (!string.IsNullOrEmpty(prefix)) { linkFlowContainer.AddText(prefix); - linkFlowContainer.AddText($@" {historyItem.Amount} kudosu", t => + linkFlowContainer.AddText($@" {Math.Abs(historyItem.Amount)} kudosu", t => { t.Font = t.Font.With(italics: true); t.Colour = colours.Blue; From 71c844facdff1219fc5b0a6e1189b81e6058c8d5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 30 Aug 2019 10:22:49 +0300 Subject: [PATCH 536/645] Remove unwanted spacings --- .../Kudosu/DrawableKudosuHistoryItem.cs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 94733324ba..408468fa73 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -10,6 +10,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; using System; +using osuTK; namespace osu.Game.Overlays.Profile.Sections.Kudosu { @@ -37,6 +38,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, + Spacing = new Vector2(3), }, date = new DrawableDate(historyItem.CreatedAt) { @@ -57,7 +59,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu if (!string.IsNullOrEmpty(prefix)) { linkFlowContainer.AddText(prefix); - linkFlowContainer.AddText($@" {Math.Abs(historyItem.Amount)} kudosu", t => + linkFlowContainer.AddText($@"{Math.Abs(historyItem.Amount)} kudosu", t => { t.Font = t.Font.With(italics: true); t.Colour = colours.Blue; @@ -75,40 +77,40 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu switch (historyItem.Action) { case KudosuAction.VoteGive: - return @" from obtaining votes in modding post of"; + return @"from obtaining votes in modding post of"; case KudosuAction.Give: - return $@" from {userLink()} for a post at"; + return $@"from {userLink()} for a post at"; case KudosuAction.Reset: return $@"Kudosu reset by {userLink()} for the post"; case KudosuAction.VoteReset: - return @" from losing votes in modding post of"; + return @"from losing votes in modding post of"; case KudosuAction.DenyKudosuReset: - return @" from modding post"; + return @"from modding post"; case KudosuAction.Revoke: return $@"Denied kudosu by {userLink()} for the post"; case KudosuAction.AllowKudosuGive: - return @" from kudosu deny repeal of modding post"; + return @"from kudosu deny repeal of modding post"; case KudosuAction.DeleteReset: - return @" from modding post deletion of"; + return @"from modding post deletion of"; case KudosuAction.RestoreGive: - return @" from modding post restoration of"; + return @"from modding post restoration of"; case KudosuAction.RecalculateGive: - return @" from votes recalculation in modding post of"; + return @"from votes recalculation in modding post of"; case KudosuAction.RecalculateReset: - return @" from votes recalculation in modding post of"; + return @"from votes recalculation in modding post of"; default: - return @" from unknown event "; + return @"from unknown event"; } } From 72dbeaec1632ce6a94c71bc82141d447a1f19d4f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 30 Aug 2019 10:26:11 +0300 Subject: [PATCH 537/645] Fix the comment --- osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index 67ff20e6c2..f2297f7a10 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -44,7 +44,7 @@ namespace osu.Game.Online.API.Requests.Responses { set { - //We will receive something like "foo.bar" or just "foo" + //We will receive something like "event.action" or just "action" string parsed = value.Contains(".") ? value.Split('.')[0].Pascalize() + value.Split('.')[1].Pascalize() : value.Pascalize(); Action = (KudosuAction)Enum.Parse(typeof(KudosuAction), parsed); From 5f3e638499c1d8fde4362239bdbfef91b9add024 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 16:40:24 +0900 Subject: [PATCH 538/645] Make test useful --- .../Visual/Gameplay/TestSceneBarHitErrorMeter.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index aac9e206c3..28c5f0ae08 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -30,8 +30,14 @@ namespace osu.Game.Tests.Visual.Gameplay public TestSceneBarHitErrorMeter() { - recreateDisplay(new OsuHitWindows(), 5); - AddStep("New random judgement", () => newJudgement()); + var hitWindows = new OsuHitWindows(); + + recreateDisplay(hitWindows, 5); + + AddRepeatStep("New random judgement", () => newJudgement(), 40); + + AddRepeatStep("New max negative", () => newJudgement(-hitWindows.Meh), 20); + AddRepeatStep("New max positive", () => newJudgement(hitWindows.Meh), 20); AddStep("New fixed judgement (50ms)", () => newJudgement(50)); } @@ -122,11 +128,11 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private void newJudgement(float offset = 0) + private void newJudgement(double offset = 0) { meter?.OnNewJudgement(new JudgementResult(new Judgement()) { - TimeOffset = offset == 0 ? RNG.Next(-70, 70) : offset, + TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, }); } From a73d672c2f3c0397d80400d8c3e96d4b22b55d2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 16:40:39 +0900 Subject: [PATCH 539/645] Tidy up judgement line logic (and fix it displaying at the wrong place) --- .../Play/HitErrorDisplay/BarHitErrorMeter.cs | 119 +++++++++--------- .../Play/HitErrorDisplay/HitErrorMeter.cs | 2 +- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs index b00f3f6f5f..ffaada6ff4 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -8,42 +9,46 @@ using osu.Game.Rulesets.Judgements; using osuTK.Graphics; using osuTK; using osu.Framework.Graphics.Sprites; -using System.Collections.Generic; using osu.Game.Rulesets.Objects; using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; -using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { public class BarHitErrorMeter : HitErrorMeter { - /// - /// The amount of which will be stored to calculate arrow position. - /// - private const int stored_judgements_amount = 5; + private readonly bool rightAligned; private const int judgement_fade_duration = 10000; - private const int arrow_move_duration = 500; + + private const int arrow_move_duration = 400; + private const int judgement_line_width = 8; + private const int bar_height = 200; + private const int bar_width = 3; + private const int spacing = 3; private readonly SpriteIcon arrow; + private readonly FillFlowContainer bar; + private readonly Container judgementsContainer; - private readonly List judgementOffsets = new List(); - private readonly double maxHitWindows; + + private readonly double maxHitWindow; public BarHitErrorMeter(HitWindows hitWindows, bool rightAligned = false) : base(hitWindows) { - maxHitWindows = HitWindows.Meh == 0 ? HitWindows.Good : HitWindows.Meh; + this.rightAligned = rightAligned; + maxHitWindow = Math.Max(Math.Max(HitWindows.Meh, HitWindows.Ok), HitWindows.Good); AutoSizeAxes = Axes.Both; + AddInternal(new FillFlowContainer { AutoSizeAxes = Axes.X, @@ -75,9 +80,10 @@ namespace osu.Game.Screens.Play.HitErrorDisplay RelativeSizeAxes = Axes.Y, Child = arrow = new SpriteIcon { - Anchor = Anchor.Centre, + Anchor = Anchor.TopCentre, Origin = Anchor.Centre, RelativePositionAxes = Axes.Y, + Y = 0.5f, Icon = rightAligned ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, Size = new Vector2(8), } @@ -93,24 +99,20 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { bar.AddRange(new[] { - createColoredPiece(ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - (maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)), - createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), - createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindows), - createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), - createColoredPiece(ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - (maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)) + createColoredPiece(ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), (maxHitWindow - HitWindows.Good) / (maxHitWindow * 2)), + createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), + createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindow), + createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), + createColoredPiece(ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), (maxHitWindow - HitWindows.Good) / (maxHitWindow * 2)) }); } else { bar.AddRange(new[] { - createColoredPiece(ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green), - (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), - createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindows), - createColoredPiece(ColourInfo.GradientVertical(colours.Green, colours.Green.Opacity(0)), - (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), + createColoredPiece(ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green), (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), + createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindow), + createColoredPiece(ColourInfo.GradientVertical(colours.Green, colours.Green.Opacity(0)), (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), }); } } @@ -122,51 +124,54 @@ namespace osu.Game.Screens.Play.HitErrorDisplay Height = (float)height }; - public override void OnNewJudgement(JudgementResult newJudgement) + private double floatingAverage; + + public override void OnNewJudgement(JudgementResult judgement) { - if (!newJudgement.IsHit) + if (!judgement.IsHit) return; - var judgementLine = CreateJudgementLine(newJudgement); + judgementsContainer.Add(new JudgementLine + { + Y = getRelativeJudgementPosition(judgement.TimeOffset), + Anchor = rightAligned ? Anchor.TopLeft : Anchor.TopRight, + Origin = rightAligned ? Anchor.TopLeft : Anchor.TopRight, + }); - judgementsContainer.Add(judgementLine); - - judgementLine.FadeOut(judgement_fade_duration, Easing.OutQuint).Expire(); - - arrow.MoveToY(calculateArrowPosition(newJudgement), arrow_move_duration, Easing.OutQuint); + arrow.MoveToY(getRelativeJudgementPosition(floatingAverage = floatingAverage * 0.9 + judgement.TimeOffset * 0.1) + , arrow_move_duration, Easing.Out); } - protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer + private float getRelativeJudgementPosition(double value) => (float)((value / maxHitWindow) + 1) / 2; + + public class JudgementLine : CompositeDrawable { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Masking = true, - RelativeSizeAxes = Axes.X, - Height = 2, - RelativePositionAxes = Axes.Y, - Y = getRelativeJudgementPosition(judgement.TimeOffset), - Child = new Box + public JudgementLine() { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, + RelativeSizeAxes = Axes.X; + RelativePositionAxes = Axes.Y; + Height = 2; + + InternalChild = new CircularContainer + { + Masking = true, + RelativeSizeAxes = Axes.Both, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + } + }; } - }; - private float getRelativeJudgementPosition(double value) => (float)(value / maxHitWindows); + protected override void LoadComplete() + { + base.LoadComplete(); - private float calculateArrowPosition(JudgementResult newJudgement) - { - judgementOffsets.Add(newJudgement.TimeOffset); - - if (judgementOffsets.Count < stored_judgements_amount) - return getRelativeJudgementPosition(judgementOffsets.Average()); - - double sum = 0; - - for (int i = judgementOffsets.Count - stored_judgements_amount; i < judgementOffsets.Count; i++) - sum += judgementOffsets[i]; - - return getRelativeJudgementPosition(sum / stored_judgements_amount); + Width = 0; + this.ResizeWidthTo(1, 150, Easing.OutElasticHalf); + this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration, Easing.OutQuint).Expire(); + } } } } diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs index 848e892eaa..e4599eb2fc 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs @@ -16,6 +16,6 @@ namespace osu.Game.Screens.Play.HitErrorDisplay HitWindows = hitWindows; } - public abstract void OnNewJudgement(JudgementResult newJudgement); + public abstract void OnNewJudgement(JudgementResult judgement); } } From 54696eef3990a1a93f2f707653d2b1fef5071ddc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 17:06:23 +0900 Subject: [PATCH 540/645] Reverse display, add animation and reduce width --- .../Gameplay/TestSceneBarHitErrorMeter.cs | 24 +++++--- .../Play/HitErrorDisplay/BarHitErrorMeter.cs | 59 +++++++++++-------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index 28c5f0ae08..334e0d3b90 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -27,6 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay }; private HitErrorMeter meter; + private HitErrorMeter meter2; public TestSceneBarHitErrorMeter() { @@ -109,8 +110,8 @@ namespace osu.Game.Tests.Visual.Gameplay Add(new FillFlowContainer { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Both, Children = new[] @@ -121,20 +122,29 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Add(meter = new BarHitErrorMeter(hitWindows) + Add(meter = new BarHitErrorMeter(hitWindows, true) { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + }); + + Add(meter2 = new BarHitErrorMeter(hitWindows, false) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, }); } private void newJudgement(double offset = 0) { - meter?.OnNewJudgement(new JudgementResult(new Judgement()) + var judgement = new JudgementResult(new Judgement()) { TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, - }); + }; + + meter.OnNewJudgement(judgement); + meter2.OnNewJudgement(judgement); } } } diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs index ffaada6ff4..7fb7b3cf99 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs @@ -25,19 +25,19 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private const int arrow_move_duration = 400; - private const int judgement_line_width = 8; + private const int judgement_line_width = 6; private const int bar_height = 200; - private const int bar_width = 3; + private const int bar_width = 2; - private const int spacing = 3; + private const int spacing = 2; - private readonly SpriteIcon arrow; + private SpriteIcon arrow; - private readonly FillFlowContainer bar; + private FillFlowContainer colourBarFlow; - private readonly Container judgementsContainer; + private Container judgementsContainer; private readonly double maxHitWindow; @@ -48,34 +48,39 @@ namespace osu.Game.Screens.Play.HitErrorDisplay maxHitWindow = Math.Max(Math.Max(HitWindows.Meh, HitWindows.Ok), HitWindows.Good); AutoSizeAxes = Axes.Both; + } - AddInternal(new FillFlowContainer + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.X, Height = bar_height, Direction = FillDirection.Horizontal, Spacing = new Vector2(spacing, 0), + Margin = new MarginPadding(2), Children = new Drawable[] { judgementsContainer = new Container { - Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, Width = judgement_line_width, RelativeSizeAxes = Axes.Y, }, - bar = new FillFlowContainer + colourBarFlow = new FillFlowContainer { - Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, Width = bar_width, RelativeSizeAxes = Axes.Y, Direction = FillDirection.Vertical, }, new Container { - Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Anchor = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, AutoSizeAxes = Axes.X, RelativeSizeAxes = Axes.Y, Child = arrow = new SpriteIcon @@ -84,20 +89,16 @@ namespace osu.Game.Screens.Play.HitErrorDisplay Origin = Anchor.Centre, RelativePositionAxes = Axes.Y, Y = 0.5f, - Icon = rightAligned ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, + Icon = rightAligned ? FontAwesome.Solid.ChevronLeft : FontAwesome.Solid.ChevronRight, Size = new Vector2(8), } }, } - }); - } + }; - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { if (HitWindows.Meh != 0) { - bar.AddRange(new[] + colourBarFlow.AddRange(new[] { createColoredPiece(ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), (maxHitWindow - HitWindows.Good) / (maxHitWindow * 2)), createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), @@ -108,7 +109,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay } else { - bar.AddRange(new[] + colourBarFlow.AddRange(new[] { createColoredPiece(ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green), (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindow), @@ -117,6 +118,16 @@ namespace osu.Game.Screens.Play.HitErrorDisplay } } + protected override void LoadComplete() + { + base.LoadComplete(); + + colourBarFlow.Height = 0; + colourBarFlow.ResizeHeightTo(1, 400, Easing.OutQuint); + + arrow.FadeInFromZero(400); + } + private Box createColoredPiece(ColourInfo colour, double height) => new Box { RelativeSizeAxes = Axes.Both, @@ -134,8 +145,8 @@ namespace osu.Game.Screens.Play.HitErrorDisplay judgementsContainer.Add(new JudgementLine { Y = getRelativeJudgementPosition(judgement.TimeOffset), - Anchor = rightAligned ? Anchor.TopLeft : Anchor.TopRight, - Origin = rightAligned ? Anchor.TopLeft : Anchor.TopRight, + Anchor = rightAligned ? Anchor.TopRight : Anchor.TopLeft, + Origin = rightAligned ? Anchor.TopRight : Anchor.TopLeft, }); arrow.MoveToY(getRelativeJudgementPosition(floatingAverage = floatingAverage * 0.9 + judgement.TimeOffset * 0.1) From 40729356fa1d19849f15120851653c323c372388 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 30 Aug 2019 17:34:02 +0900 Subject: [PATCH 541/645] Move beat divisor colour retrieval to BindableBeatDivisor --- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 39 +++++++++++++++ .../Compose/Components/BeatDivisorControl.cs | 47 +++---------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index ea3b68e3bd..055077cc4f 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs @@ -4,6 +4,9 @@ using System; using System.Linq; using osu.Framework.Bindables; +using osu.Framework.Graphics.Colour; +using osu.Game.Graphics; +using osuTK.Graphics; namespace osu.Game.Screens.Edit { @@ -35,5 +38,41 @@ namespace osu.Game.Screens.Edit protected override int DefaultMinValue => VALID_DIVISORS.First(); protected override int DefaultMaxValue => VALID_DIVISORS.Last(); protected override int DefaultPrecision => 1; + + /// + /// Retrieves the appropriate colour for a beat divisor. + /// + /// The beat divisor. + /// The set of colours. + /// The applicable colour from for . + public ColourInfo GetColourFor(int beatDivisor, OsuColour colours) + { + switch (beatDivisor) + { + case 2: + return colours.BlueLight; + + case 4: + return colours.Blue; + + case 8: + return colours.BlueDarker; + + case 16: + return colours.PurpleDark; + + case 3: + return colours.YellowLight; + + case 6: + return colours.Yellow; + + case 12: + return colours.YellowDarker; + + default: + return Color4.White; + } + } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index 0d16d8474b..ddcdfdaf80 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -188,6 +188,9 @@ namespace osu.Game.Screens.Edit.Compose.Components { private Marker marker; + [Resolved] + private OsuColour colours { get; set; } + private readonly BindableBeatDivisor beatDivisor; private readonly int[] availableDivisors; @@ -204,11 +207,12 @@ namespace osu.Game.Screens.Edit.Compose.Components { foreach (var t in availableDivisors) { - AddInternal(new Tick(t) + AddInternal(new Tick { Anchor = Anchor.TopLeft, Origin = Anchor.TopCentre, RelativePositionAxes = Axes.X, + Colour = beatDivisor.GetColourFor(t, colours), X = getMappedPosition(t) }); } @@ -284,11 +288,8 @@ namespace osu.Game.Screens.Edit.Compose.Components private class Tick : CompositeDrawable { - private readonly int divisor; - - public Tick(int divisor) + public Tick() { - this.divisor = divisor; Size = new Vector2(2.5f, 10); InternalChild = new Box { RelativeSizeAxes = Axes.Both }; @@ -296,42 +297,6 @@ namespace osu.Game.Screens.Edit.Compose.Components CornerRadius = 0.5f; Masking = true; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Colour = getColourForDivisor(divisor, colours); - } - - private ColourInfo getColourForDivisor(int divisor, OsuColour colours) - { - switch (divisor) - { - case 2: - return colours.BlueLight; - - case 4: - return colours.Blue; - - case 8: - return colours.BlueDarker; - - case 16: - return colours.PurpleDark; - - case 3: - return colours.YellowLight; - - case 6: - return colours.Yellow; - - case 12: - return colours.YellowDarker; - - default: - return Color4.White; - } - } } private class Marker : CompositeDrawable From 741bd0a5cffd4a972291054188cc139d62a7358d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 18:35:06 +0900 Subject: [PATCH 542/645] Fix incorrect colour sizes and simplify alignment specification --- .../Gameplay/TestSceneBarHitErrorMeter.cs | 4 +- osu.Game/Rulesets/Objects/HitWindows.cs | 13 ++ .../Play/HitErrorDisplay/BarHitErrorMeter.cs | 172 +++++++++++++----- 3 files changed, 140 insertions(+), 49 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index 334e0d3b90..8852a27f50 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -37,8 +37,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep("New random judgement", () => newJudgement(), 40); - AddRepeatStep("New max negative", () => newJudgement(-hitWindows.Meh), 20); - AddRepeatStep("New max positive", () => newJudgement(hitWindows.Meh), 20); + AddRepeatStep("New max negative", () => newJudgement(-hitWindows.HalfWindowFor(HitResult.Meh)), 20); + AddRepeatStep("New max positive", () => newJudgement(hitWindows.HalfWindowFor(HitResult.Meh)), 20); AddStep("New fixed judgement (50ms)", () => newJudgement(50)); } diff --git a/osu.Game/Rulesets/Objects/HitWindows.cs b/osu.Game/Rulesets/Objects/HitWindows.cs index fe099aaee7..e88af67c7c 100644 --- a/osu.Game/Rulesets/Objects/HitWindows.cs +++ b/osu.Game/Rulesets/Objects/HitWindows.cs @@ -65,6 +65,19 @@ namespace osu.Game.Rulesets.Objects return HitResult.None; } + /// + /// Retrieves a mapping of s to their half window timing for all allowed s. + /// + /// + public IEnumerable<(HitResult result, double length)> GetAllAvailableHalfWindows() + { + for (var result = HitResult.Meh; result <= HitResult.Perfect; ++result) + { + if (IsHitResultAllowed(result)) + yield return (result, HalfWindowFor(result)); + } + } + /// /// Check whether it is possible to achieve the provided . /// diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs index 7fb7b3cf99..5a2d892d7f 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs @@ -1,7 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -11,15 +11,16 @@ using osuTK; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Objects; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics.Colour; using osu.Game.Graphics; -using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HitErrorDisplay { public class BarHitErrorMeter : HitErrorMeter { - private readonly bool rightAligned; + private readonly Anchor alignment; private const int judgement_fade_duration = 10000; @@ -35,17 +36,17 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private SpriteIcon arrow; - private FillFlowContainer colourBarFlow; + private Container colourBarsEarly; + private Container colourBarsLate; private Container judgementsContainer; - private readonly double maxHitWindow; + private double maxHitWindow; public BarHitErrorMeter(HitWindows hitWindows, bool rightAligned = false) : base(hitWindows) { - this.rightAligned = rightAligned; - maxHitWindow = Math.Max(Math.Max(HitWindows.Meh, HitWindows.Ok), HitWindows.Good); + alignment = rightAligned ? Anchor.x0 : Anchor.x2; AutoSizeAxes = Axes.Both; } @@ -64,23 +65,40 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { judgementsContainer = new Container { - Anchor = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, + Anchor = Anchor.y1 | alignment, + Origin = Anchor.y1 | alignment, Width = judgement_line_width, RelativeSizeAxes = Axes.Y, }, - colourBarFlow = new FillFlowContainer + colourBars = new Container { - Anchor = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, Width = bar_width, RelativeSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, + Anchor = Anchor.y1 | alignment, + Origin = Anchor.y1 | alignment, + Children = new Drawable[] + { + colourBarsEarly = new Container + { + Anchor = Anchor.y1 | alignment, + Origin = alignment, + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Scale = new Vector2(1, -1), + }, + colourBarsLate = new Container + { + Anchor = Anchor.y1 | alignment, + Origin = alignment, + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + }, + } }, new Container { - Anchor = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = rightAligned ? Anchor.CentreLeft : Anchor.CentreRight, + Anchor = Anchor.y1 | alignment, + Origin = Anchor.y1 | alignment, AutoSizeAxes = Axes.X, RelativeSizeAxes = Axes.Y, Child = arrow = new SpriteIcon @@ -89,53 +107,111 @@ namespace osu.Game.Screens.Play.HitErrorDisplay Origin = Anchor.Centre, RelativePositionAxes = Axes.Y, Y = 0.5f, - Icon = rightAligned ? FontAwesome.Solid.ChevronLeft : FontAwesome.Solid.ChevronRight, + Icon = alignment == Anchor.x2 ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, Size = new Vector2(8), } }, } }; - if (HitWindows.Meh != 0) - { - colourBarFlow.AddRange(new[] - { - createColoredPiece(ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), (maxHitWindow - HitWindows.Good) / (maxHitWindow * 2)), - createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), - createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindow), - createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), - createColoredPiece(ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), (maxHitWindow - HitWindows.Good) / (maxHitWindow * 2)) - }); - } - else - { - colourBarFlow.AddRange(new[] - { - createColoredPiece(ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green), (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), - createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindow), - createColoredPiece(ColourInfo.GradientVertical(colours.Green, colours.Green.Opacity(0)), (HitWindows.Good - HitWindows.Great) / (maxHitWindow * 2)), - }); - } + createColourBars(colours); } protected override void LoadComplete() { base.LoadComplete(); - colourBarFlow.Height = 0; - colourBarFlow.ResizeHeightTo(1, 400, Easing.OutQuint); + colourBars.Height = 0; + colourBars.ResizeHeightTo(1, 800, Easing.OutQuint); - arrow.FadeInFromZero(400); + arrow.Alpha = 0.01f; + arrow.Delay(200).FadeInFromZero(600); } - private Box createColoredPiece(ColourInfo colour, double height) => new Box + private void createColourBars(OsuColour colours) { - RelativeSizeAxes = Axes.Both, - Colour = colour, - Height = (float)height - }; + var windows = HitWindows.GetAllAvailableHalfWindows().ToArray(); + + maxHitWindow = windows.First().length; + + for (var i = 0; i < windows.Length; i++) + { + var (result, length) = windows[i]; + + colourBarsEarly.Add(createColourBar(result, (float)(length / maxHitWindow), i == 0)); + colourBarsLate.Add(createColourBar(result, (float)(length / maxHitWindow), i == 0)); + } + + // a little nub to mark the centre point. + var centre = createColourBar(windows.Last().result, 0.01f); + centre.Anchor = centre.Origin = Anchor.y1 | alignment; + centre.Width = 1.5f; + colourBars.Add(centre); + + Color4 getColour(HitResult result) + { + switch (result) + { + case HitResult.Meh: + return colours.Yellow; + + case HitResult.Ok: + return colours.Green; + + case HitResult.Good: + return colours.GreenLight; + + case HitResult.Great: + return colours.Blue; + + default: + return colours.BlueLight; + } + } + + Drawable createColourBar(HitResult result, float height, bool first = false) + { + var colour = getColour(result); + + if (first) + { + // the first bar needs gradient rendering. + const float gradient_start = 0.8f; + + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = getColour(result), + Height = height * gradient_start + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(colour, colour.Opacity(0)), + Y = gradient_start, + Height = height * (1 - gradient_start) + }, + } + }; + } + + return new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colour, + Height = height + }; + } + } private double floatingAverage; + private Container colourBars; public override void OnNewJudgement(JudgementResult judgement) { @@ -145,11 +221,12 @@ namespace osu.Game.Screens.Play.HitErrorDisplay judgementsContainer.Add(new JudgementLine { Y = getRelativeJudgementPosition(judgement.TimeOffset), - Anchor = rightAligned ? Anchor.TopRight : Anchor.TopLeft, - Origin = rightAligned ? Anchor.TopRight : Anchor.TopLeft, + Anchor = alignment == Anchor.x2 ? Anchor.x0 : Anchor.x2, + Origin = alignment == Anchor.x2 ? Anchor.x0 : Anchor.x2, }); - arrow.MoveToY(getRelativeJudgementPosition(floatingAverage = floatingAverage * 0.9 + judgement.TimeOffset * 0.1) + arrow.MoveToY( + getRelativeJudgementPosition(floatingAverage = floatingAverage * 0.9 + judgement.TimeOffset * 0.1) , arrow_move_duration, Easing.Out); } @@ -180,6 +257,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay base.LoadComplete(); Width = 0; + this.ResizeWidthTo(1, 150, Easing.OutElasticHalf); this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration, Easing.OutQuint).Expire(); } From 8fc177b743d8a1b3c5300379b597c5487650cb31 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 18:46:42 +0900 Subject: [PATCH 543/645] Fix namespacing and hitwindow source --- .../Gameplay/TestSceneBarHitErrorMeter.cs | 2 +- .../HitErrorDisplay.cs | 22 ++++++++++--------- .../HitErrorMeters}/BarHitErrorMeter.cs | 18 +++++++-------- .../HitErrorMeters}/HitErrorMeter.cs | 2 +- osu.Game/Screens/Play/HUDOverlay.cs | 8 +++---- 5 files changed, 26 insertions(+), 26 deletions(-) rename osu.Game/Screens/Play/{HitErrorDisplay => HUD}/HitErrorDisplay.cs (87%) rename osu.Game/Screens/Play/{HitErrorDisplay => HUD/HitErrorMeters}/BarHitErrorMeter.cs (99%) rename osu.Game/Screens/Play/{HitErrorDisplay => HUD/HitErrorMeters}/HitErrorMeter.cs (91%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index 8852a27f50..98826331e1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Screens.Play.HitErrorDisplay; using System; using System.Collections.Generic; using osu.Game.Rulesets.Judgements; @@ -16,6 +15,7 @@ using osu.Framework.MathUtils; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Game.Screens.Play.HUD.HitErrorMeters; namespace osu.Game.Tests.Visual.Gameplay { diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs similarity index 87% rename from osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs rename to osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index eaaf8e810c..0dcb1fee2b 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -1,19 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics; -using osu.Game.Rulesets.Scoring; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Game.Beatmaps; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Configuration; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Play.HUD.HitErrorMeters; -namespace osu.Game.Screens.Play.HitErrorDisplay +namespace osu.Game.Screens.Play.HUD { public class HitErrorDisplay : Container { @@ -22,13 +21,17 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly Bindable type = new Bindable(); - private HitWindows hitWindows; + private readonly HitWindows hitWindows; private readonly ScoreProcessor processor; - public HitErrorDisplay(ScoreProcessor processor) + public HitErrorDisplay(ScoreProcessor processor, HitWindows hitWindows) { this.processor = processor; + this.hitWindows = hitWindows; + + RelativeSizeAxes = Axes.Both; + processor.NewJudgement += onNewJudgement; } @@ -45,10 +48,9 @@ namespace osu.Game.Screens.Play.HitErrorDisplay } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, Bindable workingBeatmap) + private void load(OsuConfigManager config) { config.BindWith(OsuSetting.ScoreMeter, type); - hitWindows = workingBeatmap.Value.Beatmap.HitObjects.First().HitWindows; } protected override void LoadComplete() diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs similarity index 99% rename from osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs rename to osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 5a2d892d7f..22cccf30d7 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -2,21 +2,21 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Rulesets.Judgements; -using osuTK.Graphics; -using osuTK; -using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Objects; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; +using osuTK; +using osuTK.Graphics; -namespace osu.Game.Screens.Play.HitErrorDisplay +namespace osu.Game.Screens.Play.HUD.HitErrorMeters { public class BarHitErrorMeter : HitErrorMeter { diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs similarity index 91% rename from osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs rename to osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs index e4599eb2fc..da1d9fff0d 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; -namespace osu.Game.Screens.Play.HitErrorDisplay +namespace osu.Game.Screens.Play.HUD.HitErrorMeters { public abstract class HitErrorMeter : CompositeDrawable { diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 79392221e4..21d5ae557f 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -33,7 +34,7 @@ namespace osu.Game.Screens.Play public readonly HealthDisplay HealthDisplay; public readonly SongProgress Progress; public readonly ModDisplay ModDisplay; - public readonly HitErrorDisplay.HitErrorDisplay HitErrorDisplay; + public readonly HitErrorDisplay HitErrorDisplay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; @@ -258,10 +259,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay.HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay.HitErrorDisplay(scoreProcessor) - { - RelativeSizeAxes = Axes.Both, - }; + protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.First().HitWindows); protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From 171f88da409964efc0b56908fc30a0824ee20da9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2019 09:47:18 +0000 Subject: [PATCH 544/645] Bump ppy.osu.Framework from 2019.830.0 to 2019.830.1 Bumps [ppy.osu.Framework](https://github.com/ppy/osu-framework) from 2019.830.0 to 2019.830.1. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.830.0...2019.830.1) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8e6ce2d1ba..330018d5cb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 47cc6ec97a..298fbc6704 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,7 +118,7 @@ - + From c3abf0ccb7112f654910ef867a658986e517fa54 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 18:50:38 +0900 Subject: [PATCH 545/645] Improve visuals --- .../Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 22cccf30d7..4e32be3cda 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -22,8 +22,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { private readonly Anchor alignment; - private const int judgement_fade_duration = 10000; - private const int arrow_move_duration = 400; private const int judgement_line_width = 6; @@ -34,6 +32,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private const int spacing = 2; + private const float chevron_size = 8; + private SpriteIcon arrow; private Container colourBarsEarly; @@ -99,7 +99,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { Anchor = Anchor.y1 | alignment, Origin = Anchor.y1 | alignment, - AutoSizeAxes = Axes.X, + Width = chevron_size, RelativeSizeAxes = Axes.Y, Child = arrow = new SpriteIcon { @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters RelativePositionAxes = Axes.Y, Y = 0.5f, Icon = alignment == Anchor.x2 ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, - Size = new Vector2(8), + Size = new Vector2(chevron_size), } }, } @@ -124,7 +124,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters colourBars.Height = 0; colourBars.ResizeHeightTo(1, 800, Easing.OutQuint); - arrow.Alpha = 0.01f; + arrow.Alpha = 0; arrow.Delay(200).FadeInFromZero(600); } @@ -234,11 +234,13 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public class JudgementLine : CompositeDrawable { + private const int judgement_fade_duration = 10000; + public JudgementLine() { RelativeSizeAxes = Axes.X; RelativePositionAxes = Axes.Y; - Height = 2; + Height = 3; InternalChild = new CircularContainer { @@ -258,7 +260,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Width = 0; - this.ResizeWidthTo(1, 150, Easing.OutElasticHalf); + this.ResizeWidthTo(1, 200, Easing.OutElasticHalf); this.FadeTo(0.8f, 150).Then().FadeOut(judgement_fade_duration, Easing.OutQuint).Expire(); } } From b639ce8e5d237c845adec63f26f5993df4140be8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2019 10:01:16 +0000 Subject: [PATCH 546/645] Bump ppy.osu.Framework.iOS from 2019.830.0 to 2019.830.1 Bumps [ppy.osu.Framework.iOS](https://github.com/ppy/osu-framework) from 2019.830.0 to 2019.830.1. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.830.0...2019.830.1) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 47cc6ec97a..afb0b9217e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -119,7 +119,7 @@ - + From 815220de039ef25606591f5a0e0f7f1122952870 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2019 10:01:35 +0000 Subject: [PATCH 547/645] Bump ppy.osu.Framework.Android from 2019.830.0 to 2019.830.1 Bumps [ppy.osu.Framework.Android](https://github.com/ppy/osu-framework) from 2019.830.0 to 2019.830.1. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.830.0...2019.830.1) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android.props b/osu.Android.props index 2c3c8bcaad..93a9a073a4 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + From 80671cefd7db5e83b1059fdccaa3bc5a475bd603 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 19:14:07 +0900 Subject: [PATCH 548/645] Final visual polish --- .../HUD/HitErrorMeters/BarHitErrorMeter.cs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 4e32be3cda..51f9be4792 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -93,6 +93,22 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters RelativeSizeAxes = Axes.Both, Height = 0.5f, }, + new SpriteIcon + { + Y = -10, + Size = new Vector2(10), + Icon = FontAwesome.Solid.ShippingFast, + Anchor = Anchor.y0 | alignment, + Origin = Anchor.y0 | alignment, + }, + new SpriteIcon + { + Y = 10, + Size = new Vector2(10), + Icon = FontAwesome.Solid.Bicycle, + Anchor = Anchor.y2 | alignment, + Origin = Anchor.y2 | alignment, + } } }, new Container @@ -144,8 +160,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters // a little nub to mark the centre point. var centre = createColourBar(windows.Last().result, 0.01f); - centre.Anchor = centre.Origin = Anchor.y1 | alignment; - centre.Width = 1.5f; + centre.Anchor = centre.Origin = Anchor.y1 | (alignment == Anchor.x2 ? Anchor.x0 : Anchor.x2); + centre.Width = 2.5f; colourBars.Add(centre); Color4 getColour(HitResult result) From 665fc95d49c595b751d44ca5cf5bae91ae5bda58 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 19:37:20 +0900 Subject: [PATCH 549/645] Handle no hitobjects / no hitwindows (osu!catch) --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 3 +++ osu.Game/Screens/Play/HUDOverlay.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 0dcb1fee2b..2e28d17b80 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -63,6 +63,9 @@ namespace osu.Game.Screens.Play.HUD { Children.ForEach(c => c.FadeOut(fade_duration, Easing.OutQuint)); + if (hitWindows == null) + return; + switch (type.NewValue) { case ScoreMeterType.HitErrorBoth: diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 21d5ae557f..285737f7a8 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -259,7 +259,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.First().HitWindows); + protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.FirstOrDefault().HitWindows); protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From fab12fa9cd00043a9b820d7511ca2fcddb729d8d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 30 Aug 2019 19:34:28 +0900 Subject: [PATCH 550/645] Centre align the icons Seems to look better this way. --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 51f9be4792..7d3b0ae141 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -98,16 +98,16 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Y = -10, Size = new Vector2(10), Icon = FontAwesome.Solid.ShippingFast, - Anchor = Anchor.y0 | alignment, - Origin = Anchor.y0 | alignment, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, }, new SpriteIcon { Y = 10, Size = new Vector2(10), Icon = FontAwesome.Solid.Bicycle, - Anchor = Anchor.y2 | alignment, - Origin = Anchor.y2 | alignment, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, } } }, From 8b4976ad92399c19acffa4275710eaffe3d9ff02 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 30 Aug 2019 19:37:18 +0900 Subject: [PATCH 551/645] Remove unnecessary intermediate OD tests --- .../Gameplay/TestSceneBarHitErrorMeter.cs | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index 98826331e1..d317c6551f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -46,14 +46,6 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestOsu() { AddStep("OD 1", () => recreateDisplay(new OsuHitWindows(), 1)); - AddStep("OD 2", () => recreateDisplay(new OsuHitWindows(), 2)); - AddStep("OD 3", () => recreateDisplay(new OsuHitWindows(), 3)); - AddStep("OD 4", () => recreateDisplay(new OsuHitWindows(), 4)); - AddStep("OD 5", () => recreateDisplay(new OsuHitWindows(), 5)); - AddStep("OD 6", () => recreateDisplay(new OsuHitWindows(), 6)); - AddStep("OD 7", () => recreateDisplay(new OsuHitWindows(), 7)); - AddStep("OD 8", () => recreateDisplay(new OsuHitWindows(), 8)); - AddStep("OD 9", () => recreateDisplay(new OsuHitWindows(), 9)); AddStep("OD 10", () => recreateDisplay(new OsuHitWindows(), 10)); } @@ -61,14 +53,6 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestTaiko() { AddStep("OD 1", () => recreateDisplay(new TaikoHitWindows(), 1)); - AddStep("OD 2", () => recreateDisplay(new TaikoHitWindows(), 2)); - AddStep("OD 3", () => recreateDisplay(new TaikoHitWindows(), 3)); - AddStep("OD 4", () => recreateDisplay(new TaikoHitWindows(), 4)); - AddStep("OD 5", () => recreateDisplay(new TaikoHitWindows(), 5)); - AddStep("OD 6", () => recreateDisplay(new TaikoHitWindows(), 6)); - AddStep("OD 7", () => recreateDisplay(new TaikoHitWindows(), 7)); - AddStep("OD 8", () => recreateDisplay(new TaikoHitWindows(), 8)); - AddStep("OD 9", () => recreateDisplay(new TaikoHitWindows(), 9)); AddStep("OD 10", () => recreateDisplay(new TaikoHitWindows(), 10)); } @@ -76,14 +60,6 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestMania() { AddStep("OD 1", () => recreateDisplay(new ManiaHitWindows(), 1)); - AddStep("OD 2", () => recreateDisplay(new ManiaHitWindows(), 2)); - AddStep("OD 3", () => recreateDisplay(new ManiaHitWindows(), 3)); - AddStep("OD 4", () => recreateDisplay(new ManiaHitWindows(), 4)); - AddStep("OD 5", () => recreateDisplay(new ManiaHitWindows(), 5)); - AddStep("OD 6", () => recreateDisplay(new ManiaHitWindows(), 6)); - AddStep("OD 7", () => recreateDisplay(new ManiaHitWindows(), 7)); - AddStep("OD 8", () => recreateDisplay(new ManiaHitWindows(), 8)); - AddStep("OD 9", () => recreateDisplay(new ManiaHitWindows(), 9)); AddStep("OD 10", () => recreateDisplay(new ManiaHitWindows(), 10)); } @@ -91,14 +67,6 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestCatch() { AddStep("OD 1", () => recreateDisplay(new CatchHitWindows(), 1)); - AddStep("OD 2", () => recreateDisplay(new CatchHitWindows(), 2)); - AddStep("OD 3", () => recreateDisplay(new CatchHitWindows(), 3)); - AddStep("OD 4", () => recreateDisplay(new CatchHitWindows(), 4)); - AddStep("OD 5", () => recreateDisplay(new CatchHitWindows(), 5)); - AddStep("OD 6", () => recreateDisplay(new CatchHitWindows(), 6)); - AddStep("OD 7", () => recreateDisplay(new CatchHitWindows(), 7)); - AddStep("OD 8", () => recreateDisplay(new CatchHitWindows(), 8)); - AddStep("OD 9", () => recreateDisplay(new CatchHitWindows(), 9)); AddStep("OD 10", () => recreateDisplay(new CatchHitWindows(), 10)); } From 6fb8a6cdbe894343c98a54e115c97a2451264717 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 30 Aug 2019 19:47:13 +0900 Subject: [PATCH 552/645] Fix testcases not working for OD10 --- .../Visual/Gameplay/TestSceneBarHitErrorMeter.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index d317c6551f..f20440249b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -28,12 +28,11 @@ namespace osu.Game.Tests.Visual.Gameplay private HitErrorMeter meter; private HitErrorMeter meter2; + private HitWindows hitWindows; public TestSceneBarHitErrorMeter() { - var hitWindows = new OsuHitWindows(); - - recreateDisplay(hitWindows, 5); + recreateDisplay(new OsuHitWindows(), 5); AddRepeatStep("New random judgement", () => newJudgement(), 40); @@ -72,7 +71,9 @@ namespace osu.Game.Tests.Visual.Gameplay private void recreateDisplay(HitWindows hitWindows, float overallDifficulty) { - hitWindows.SetDifficulty(overallDifficulty); + this.hitWindows = hitWindows; + + hitWindows?.SetDifficulty(overallDifficulty); Clear(); @@ -84,9 +85,9 @@ namespace osu.Game.Tests.Visual.Gameplay AutoSizeAxes = Axes.Both, Children = new[] { - new SpriteText { Text = $@"Great: {hitWindows.Great}" }, - new SpriteText { Text = $@"Good: {hitWindows.Good}" }, - new SpriteText { Text = $@"Meh: {hitWindows.Meh}" }, + new SpriteText { Text = $@"Great: {hitWindows?.Great}" }, + new SpriteText { Text = $@"Good: {hitWindows?.Good}" }, + new SpriteText { Text = $@"Meh: {hitWindows?.Meh}" }, } }); From dfccc6036109226ca4be14cd92ca38f6fd3e6d5c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 30 Aug 2019 19:47:21 +0900 Subject: [PATCH 553/645] Reorder HitErrorDisplay --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 2e28d17b80..cdfa0e993b 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -35,18 +35,6 @@ namespace osu.Game.Screens.Play.HUD processor.NewJudgement += onNewJudgement; } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - processor.NewJudgement -= onNewJudgement; - } - - private void onNewJudgement(JudgementResult result) - { - foreach (var c in Children) - c.OnNewJudgement(result); - } - [BackgroundDependencyLoader] private void load(OsuConfigManager config) { @@ -59,6 +47,12 @@ namespace osu.Game.Screens.Play.HUD type.BindValueChanged(typeChanged, true); } + private void onNewJudgement(JudgementResult result) + { + foreach (var c in Children) + c.OnNewJudgement(result); + } + private void typeChanged(ValueChangedEvent type) { Children.ForEach(c => c.FadeOut(fade_duration, Easing.OutQuint)); @@ -96,5 +90,11 @@ namespace osu.Game.Screens.Play.HUD Add(display); display.FadeInFromZero(fade_duration, Easing.OutQuint); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + processor.NewJudgement -= onNewJudgement; + } } } From fc813347ac522fad92e2b88b022ab2561957b6ee Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 30 Aug 2019 19:54:36 +0900 Subject: [PATCH 554/645] Make JudgementLine private --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 7d3b0ae141..d5d3cb528e 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -248,7 +248,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private float getRelativeJudgementPosition(double value) => (float)((value / maxHitWindow) + 1) / 2; - public class JudgementLine : CompositeDrawable + private class JudgementLine : CompositeDrawable { private const int judgement_fade_duration = 10000; From f1db6c7039c1bbc037c36c0449a599f9a6694497 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Aug 2019 20:18:21 +0900 Subject: [PATCH 555/645] Fix likely nullref --- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 285737f7a8..8e642ea552 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -259,7 +259,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.FirstOrDefault().HitWindows); + protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.FirstOrDefault()?.HitWindows); protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From 2876588193897bc9128bb62041c0e6adbc13941b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2019 13:36:31 +0000 Subject: [PATCH 556/645] Bump NUnit3TestAdapter from 3.15.0 to 3.15.1 Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 3.15.0 to 3.15.1. - [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases) - [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V3.15...V3.15.1) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 7c282f449b..c527a81f51 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 4dcfc1b81f..af10d5e06e 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 197309c7c4..c331c811d2 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index a5db1625d9..d2a0a8fa6f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 4a9d88f3a6..84f67c9319 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index 2a8bd393da..bba3c92245 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -7,7 +7,7 @@ - + WinExe From 1ddf292ad687878c0acf8ef247a0060ba08a5d5c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 31 Aug 2019 12:20:50 +0900 Subject: [PATCH 557/645] Fix vertical alignment of hit error display ticks Wasn't correctly centered before. --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index d5d3cb528e..594dd64e52 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -238,7 +238,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { Y = getRelativeJudgementPosition(judgement.TimeOffset), Anchor = alignment == Anchor.x2 ? Anchor.x0 : Anchor.x2, - Origin = alignment == Anchor.x2 ? Anchor.x0 : Anchor.x2, + Origin = Anchor.y1 | (alignment == Anchor.x2 ? Anchor.x0 : Anchor.x2), }); arrow.MoveToY( From f89981e1a330c3105e7fe87481f7a0df6721fa32 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 31 Aug 2019 12:23:15 +0900 Subject: [PATCH 558/645] Fix legacy skin text reading from the wrong source Regressed with ruleset legacy skin implementation. --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 3c508f34e0..d1bd0f0a88 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Skinning return !hasFont(font) ? null - : new LegacySpriteText(this, font) + : new LegacySpriteText(source, font) { // Spacing value was reverse-engineered from the ratio of the rendered sprite size in the visual inspector vs the actual texture size Scale = new Vector2(0.96f), @@ -117,6 +117,6 @@ namespace osu.Game.Rulesets.Osu.Skinning public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; - private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; + private bool hasFont(string fontName) => source.GetTexture($"{fontName}-0") != null; } } From 12eeec36fca2dccda14043caab9802aa9cdc9754 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 31 Aug 2019 12:33:29 +0900 Subject: [PATCH 559/645] Fix ruleset skins incorrectly providing configuration defaults --- osu.Game/Skinning/DefaultSkin.cs | 2 +- osu.Game/Skinning/DefaultSkinConfiguration.cs | 28 +++++++++++++++++++ osu.Game/Skinning/LegacySkin.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 15 ++++------ 4 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Skinning/DefaultSkinConfiguration.cs diff --git a/osu.Game/Skinning/DefaultSkin.cs b/osu.Game/Skinning/DefaultSkin.cs index 6072bb64ed..ec957566cb 100644 --- a/osu.Game/Skinning/DefaultSkin.cs +++ b/osu.Game/Skinning/DefaultSkin.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning public DefaultSkin() : base(SkinInfo.Default) { - Configuration = new SkinConfiguration(); + Configuration = new DefaultSkinConfiguration(); } public override Drawable GetDrawableComponent(string componentName) => null; diff --git a/osu.Game/Skinning/DefaultSkinConfiguration.cs b/osu.Game/Skinning/DefaultSkinConfiguration.cs new file mode 100644 index 0000000000..722b35f102 --- /dev/null +++ b/osu.Game/Skinning/DefaultSkinConfiguration.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osuTK.Graphics; + +namespace osu.Game.Skinning +{ + /// + /// A skin configuration pre-populated with sane defaults. + /// + public class DefaultSkinConfiguration : SkinConfiguration + { + public DefaultSkinConfiguration() + { + HitCircleFont = "default"; + + ComboColours.AddRange(new[] + { + new Color4(17, 136, 170, 255), + new Color4(102, 136, 0, 255), + new Color4(204, 102, 0, 255), + new Color4(121, 9, 13, 255) + }); + + CursorExpand = true; + } + } +} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 1572c588e8..56b8aa19c2 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -34,7 +34,7 @@ namespace osu.Game.Skinning using (StreamReader reader = new StreamReader(stream)) Configuration = new LegacySkinDecoder().Decode(reader); else - Configuration = new SkinConfiguration(); + Configuration = new DefaultSkinConfiguration(); Samples = audioManager.GetSampleStore(storage); Textures = new TextureStore(new TextureLoaderStore(storage)); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 93b599f9f6..d585c58ef1 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -7,21 +7,18 @@ using osuTK.Graphics; namespace osu.Game.Skinning { + /// + /// An empty skin configuration. + /// public class SkinConfiguration : IHasComboColours, IHasCustomColours { public readonly SkinInfo SkinInfo = new SkinInfo(); - public List ComboColours { get; set; } = new List - { - new Color4(17, 136, 170, 255), - new Color4(102, 136, 0, 255), - new Color4(204, 102, 0, 255), - new Color4(121, 9, 13, 255) - }; + public List ComboColours { get; set; } = new List(); public Dictionary CustomColours { get; set; } = new Dictionary(); - public string HitCircleFont { get; set; } = "default"; + public string HitCircleFont { get; set; } public int HitCircleOverlap { get; set; } @@ -29,6 +26,6 @@ namespace osu.Game.Skinning public float? SliderPathRadius { get; set; } - public bool? CursorExpand { get; set; } = true; + public bool? CursorExpand { get; set; } } } From d2a3e0581b750c030d197573e6923815ca2e60f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 31 Aug 2019 13:27:03 +0900 Subject: [PATCH 560/645] Fix legacy decoder using wrong configuration --- osu.Game/Skinning/LegacySkinDecoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkinDecoder.cs b/osu.Game/Skinning/LegacySkinDecoder.cs index ecb112955c..0160755eed 100644 --- a/osu.Game/Skinning/LegacySkinDecoder.cs +++ b/osu.Game/Skinning/LegacySkinDecoder.cs @@ -5,14 +5,14 @@ using osu.Game.Beatmaps.Formats; namespace osu.Game.Skinning { - public class LegacySkinDecoder : LegacyDecoder + public class LegacySkinDecoder : LegacyDecoder { public LegacySkinDecoder() : base(1) { } - protected override void ParseLine(SkinConfiguration skin, Section section, string line) + protected override void ParseLine(DefaultSkinConfiguration skin, Section section, string line) { line = StripComments(line); From 2988624f1fd66896c72cb286984a733ebd4bfb02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 31 Aug 2019 16:52:41 +0900 Subject: [PATCH 561/645] Add fallback for safety --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 3c508f34e0..97db2d7c8e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Skinning public SampleChannel GetSample(ISampleInfo sample) => null; public TValue GetValue(Func query) where TConfiguration : SkinConfiguration - => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; + => configuration.Value is TConfiguration conf ? query.Invoke(conf) : source.GetValue(query); private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; } From 3da5eb6c8b3642980a8f2e0197d0a644122bae13 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 31 Aug 2019 16:56:32 +0900 Subject: [PATCH 562/645] Add source lookups for safety --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index d1bd0f0a88..f9fbdcd0e9 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -110,9 +110,9 @@ namespace osu.Game.Rulesets.Osu.Skinning return null; } - public Texture GetTexture(string componentName) => null; + public Texture GetTexture(string componentName) => source.GetTexture(componentName); - public SampleChannel GetSample(ISampleInfo sample) => null; + public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => configuration.Value is TConfiguration conf ? query.Invoke(conf) : default; From cbbc6aad6eefdf4bcac3b1fba363dce0e66879d5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 31 Aug 2019 21:32:02 +0900 Subject: [PATCH 563/645] Make method static --- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 2 +- osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index 055077cc4f..2aeb1ef04b 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Edit /// The beat divisor. /// The set of colours. /// The applicable colour from for . - public ColourInfo GetColourFor(int beatDivisor, OsuColour colours) + public static ColourInfo GetColourFor(int beatDivisor, OsuColour colours) { switch (beatDivisor) { diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index ddcdfdaf80..4d89e43ee5 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -212,7 +212,7 @@ namespace osu.Game.Screens.Edit.Compose.Components Anchor = Anchor.TopLeft, Origin = Anchor.TopCentre, RelativePositionAxes = Axes.X, - Colour = beatDivisor.GetColourFor(t, colours), + Colour = BindableBeatDivisor.GetColourFor(t, colours), X = getMappedPosition(t) }); } From 1b4ae5a4a495917257be26a88a0b48a57cc231e4 Mon Sep 17 00:00:00 2001 From: pi1024e Date: Thu, 22 Aug 2019 22:37:01 -0400 Subject: [PATCH 564/645] Spelling fixes --- osu.Game/Online/API/APIAccess.cs | 2 +- osu.Game/Screens/Menu/IntroCircles.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 4 ++-- osu.Game/Screens/Menu/OsuLogo.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index d722c7a98a..0303293c41 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -165,7 +165,7 @@ namespace osu.Game.Online.API } // The Success callback event is fired on the main thread, so we should wait for that to run before proceeding. - // Without this, we will end up circulating this Connecting loop multiple times and queueing up many web requests + // Without this, we will end up circulating this Connecting loop multiple times and queuing up many web requests // before actually going online. while (State > APIState.Offline && State < APIState.Online) Thread.Sleep(500); diff --git a/osu.Game/Screens/Menu/IntroCircles.cs b/osu.Game/Screens/Menu/IntroCircles.cs index 4fa1a81123..c069f82134 100644 --- a/osu.Game/Screens/Menu/IntroCircles.cs +++ b/osu.Game/Screens/Menu/IntroCircles.cs @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Menu Scheduler.AddDelayed(delegate { - // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (menuMusic.Value) { track.Restart(); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 9d0a5cd05b..6984959e9c 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Menu private const float visualiser_rounds = 5; /// - /// How much should each bar go down each milisecond (based on a full bar). + /// How much should each bar go down each millisecond (based on a full bar). /// private const float decay_per_milisecond = 0.0024f; @@ -161,7 +161,7 @@ namespace osu.Game.Screens.Menu private IShader shader; private Texture texture; - //Asuming the logo is a circle, we don't need a second dimension. + //Assuming the logo is a circle, we don't need a second dimension. private float size; private Color4 colour; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 0c5bf12bdb..d37cfe32db 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -229,7 +229,7 @@ namespace osu.Game.Screens.Menu } /// - /// Schedule a new extenral animation. Handled queueing and finishing previous animations in a sane way. + /// Schedule a new external animation. Handled queuing and finishing previous animations in a sane way. /// /// The animation to be performed /// If true, the new animation is delayed until all previous transforms finish. If false, existing transformed are cleared. From 5695bb670e62db544b536942bfd52db23554b461 Mon Sep 17 00:00:00 2001 From: pi1024e Date: Fri, 30 Aug 2019 13:48:45 -0400 Subject: [PATCH 565/645] change back to queuing --- osu.Game/Online/API/APIAccess.cs | 2 +- osu.Game/Screens/Menu/OsuLogo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 0303293c41..d722c7a98a 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -165,7 +165,7 @@ namespace osu.Game.Online.API } // The Success callback event is fired on the main thread, so we should wait for that to run before proceeding. - // Without this, we will end up circulating this Connecting loop multiple times and queuing up many web requests + // Without this, we will end up circulating this Connecting loop multiple times and queueing up many web requests // before actually going online. while (State > APIState.Offline && State < APIState.Online) Thread.Sleep(500); diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index d37cfe32db..534400e720 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -229,7 +229,7 @@ namespace osu.Game.Screens.Menu } /// - /// Schedule a new external animation. Handled queuing and finishing previous animations in a sane way. + /// Schedule a new external animation. Handled queueing and finishing previous animations in a sane way. /// /// The animation to be performed /// If true, the new animation is delayed until all previous transforms finish. If false, existing transformed are cleared. From a1c72db5f62001aa62f994f5f24c463032a8ddce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Aug 2019 17:01:12 +0200 Subject: [PATCH 566/645] Fix inconsistent sound effects on mod buttons Because HoverClickSounds.OnClick() does not fire upon right clicking on mod buttons, the sound effects that play on left and right click were inconsistent. Introduce HoverMouseUpSounds drawable that allows to play the click sound effect upon mouse up events for an arbitrary set of mouse buttons and use it on mod buttons. --- .../UserInterface/HoverMouseUpSounds.cs | 42 +++++++++++++++++++ osu.Game/Overlays/Mods/ModButton.cs | 3 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs diff --git a/osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs b/osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs new file mode 100644 index 0000000000..dcb443d5aa --- /dev/null +++ b/osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs @@ -0,0 +1,42 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Extensions; +using osu.Framework.Input.Events; +using osuTK.Input; + +namespace osu.Game.Graphics.UserInterface +{ + /// + /// Adds hover sounds to a drawable, as well as click sounds upon MouseUp events for selected mouse buttons. + /// Intended to be used for controls that can respond to clicks of buttons other than the left mouse button in place of . + /// + public class HoverMouseUpSounds : HoverSounds + { + private SampleChannel sampleClick; + private readonly List buttons; + + public HoverMouseUpSounds(List buttons, HoverSampleSet sampleSet = HoverSampleSet.Normal) + : base(sampleSet) + { + this.buttons = buttons; + } + + protected override bool OnMouseUp(MouseUpEvent e) + { + if (Contains(e.ScreenSpaceMousePosition) && buttons.Contains(e.Button)) + sampleClick?.Play(); + return base.OnMouseUp(e); + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleClick = audio.Samples.Get($@"UI/generic-select{SampleSet.GetDescription()}"); + } + } +} diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 7b8745cf42..ba39360102 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Events; @@ -283,7 +284,7 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Font = OsuFont.GetFont(size: 18) }, - new HoverClickSounds() + new HoverMouseUpSounds(new List { MouseButton.Left, MouseButton.Right }) }; Mod = mod; From 658e0edc3e7df2510953bc9acc11aac35b081590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Aug 2019 20:16:16 +0200 Subject: [PATCH 567/645] Handle other button clicks in HoverClickSounds As suggested in review, remove previously introduced HoverMouseUpSounds and instead change effect playing logic in HoverClickSounds by moving it out of OnClick() to OnMouseUp(). Users of the class can either use the existing constructor to play the effect only on left click or use the newly introduced constructor with the MouseButton[] parameter to specify which button clicks should trigger the sound. --- .../UserInterface/HoverClickSounds.cs | 32 ++++++++++++-- .../UserInterface/HoverMouseUpSounds.cs | 42 ------------------- osu.Game/Overlays/Mods/ModButton.cs | 3 +- 3 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 70d988f60e..8fe20e3566 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -1,11 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Extensions; using osu.Framework.Input.Events; +using osuTK.Input; namespace osu.Game.Graphics.UserInterface { @@ -16,16 +18,38 @@ namespace osu.Game.Graphics.UserInterface public class HoverClickSounds : HoverSounds { private SampleChannel sampleClick; + private readonly MouseButton[] buttons; + /// + /// Creates an instance that adds sounds on hover and left click only. + /// + /// Set of click samples to play. public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal) - : base(sampleSet) + : this(new[] { MouseButton.Left }, sampleSet) { } - protected override bool OnClick(ClickEvent e) + /// + /// Creates an instance that adds sounds on hover and on click for any of the buttons specified. + /// + /// Array of button codes which should trigger the click sound. + /// Set of click samples to play. + public HoverClickSounds(MouseButton[] buttons, HoverSampleSet sampleSet = HoverSampleSet.Normal) + : base(sampleSet) { - sampleClick?.Play(); - return base.OnClick(e); + this.buttons = buttons; + } + + protected override bool OnMouseUp(MouseUpEvent e) + { + var index = Array.IndexOf(buttons, e.Button); + bool shouldPlayEffect = index > -1 && index < buttons.Length; + + // examine the button pressed first for short-circuiting + // in most usages it is more likely that another button was pressed than that the cursor left the drawable bounds + if (shouldPlayEffect && Contains(e.ScreenSpaceMousePosition)) + sampleClick?.Play(); + return base.OnMouseUp(e); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs b/osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs deleted file mode 100644 index dcb443d5aa..0000000000 --- a/osu.Game/Graphics/UserInterface/HoverMouseUpSounds.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using osu.Framework.Extensions; -using osu.Framework.Input.Events; -using osuTK.Input; - -namespace osu.Game.Graphics.UserInterface -{ - /// - /// Adds hover sounds to a drawable, as well as click sounds upon MouseUp events for selected mouse buttons. - /// Intended to be used for controls that can respond to clicks of buttons other than the left mouse button in place of . - /// - public class HoverMouseUpSounds : HoverSounds - { - private SampleChannel sampleClick; - private readonly List buttons; - - public HoverMouseUpSounds(List buttons, HoverSampleSet sampleSet = HoverSampleSet.Normal) - : base(sampleSet) - { - this.buttons = buttons; - } - - protected override bool OnMouseUp(MouseUpEvent e) - { - if (Contains(e.ScreenSpaceMousePosition) && buttons.Contains(e.Button)) - sampleClick?.Play(); - return base.OnMouseUp(e); - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - sampleClick = audio.Samples.Get($@"UI/generic-select{SampleSet.GetDescription()}"); - } - } -} diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index ba39360102..f46555dc4b 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -11,7 +11,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using System; -using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Events; @@ -284,7 +283,7 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Font = OsuFont.GetFont(size: 18) }, - new HoverMouseUpSounds(new List { MouseButton.Left, MouseButton.Right }) + new HoverClickSounds(new[] { MouseButton.Left, MouseButton.Right }) }; Mod = mod; From aff4dab9aa342955a44e53335c6899fed8fbe3b3 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 1 Sep 2019 03:17:55 +0300 Subject: [PATCH 568/645] Ensure playing track of beatmap selected only if a track change occurred --- osu.Game/Screens/Select/SongSelect.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index edb0e6deb8..d0cb5986a8 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -414,7 +414,11 @@ namespace osu.Game.Screens.Select { Logger.Log($"beatmap changed from \"{Beatmap.Value.BeatmapInfo}\" to \"{beatmap}\""); - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); + WorkingBeatmap previous = Beatmap.Value; + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, previous); + + if (this.IsCurrentScreen() && Beatmap.Value?.Track != previous?.Track) + ensurePlayingSelected(); if (beatmap != null) { @@ -425,8 +429,6 @@ namespace osu.Game.Screens.Select } } - if (this.IsCurrentScreen()) - ensurePlayingSelected(); UpdateBeatmap(Beatmap.Value); } } From 7d955839be8fc02b466ab53000598e98c36afb9c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 1 Sep 2019 04:22:24 +0300 Subject: [PATCH 569/645] Instantly move rank graph tooltip --- .../Overlays/Profile/Header/Components/RankGraph.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 24ed0cc022..56405483af 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -283,18 +283,7 @@ namespace osu.Game.Overlays.Profile.Header.Components return true; } - private bool instantMove = true; - - public void Move(Vector2 pos) - { - if (instantMove) - { - Position = pos; - instantMove = false; - } - else - this.MoveTo(pos, 200, Easing.OutQuint); - } + public void Move(Vector2 pos) => Position = pos; protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); From a155814bc48b5547b63f50ea60a4ae67bc377bd8 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 1 Sep 2019 06:07:25 +0300 Subject: [PATCH 570/645] Implement instant movement properly --- .../Profile/Header/Components/RankGraph.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 56405483af..c6d96c5917 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -283,9 +283,24 @@ namespace osu.Game.Overlays.Profile.Header.Components return true; } - public void Move(Vector2 pos) => Position = pos; + private bool instantMove = true; - protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); + public void Move(Vector2 pos) + { + if (instantMove) + { + Position = pos; + instantMove = false; + } + else + this.MoveTo(pos, 200, Easing.OutQuint); + } + + protected override void PopIn() + { + instantMove |= !IsPresent; + this.FadeIn(200, Easing.OutQuint); + } protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); } From d1eafafa51b6632c5facea6e9b952e29fdef3441 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Sep 2019 19:57:12 +0900 Subject: [PATCH 571/645] Allow searching channels by topics Closes #5939 --- osu.Game/Overlays/Chat/Selection/ChannelListItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs index 4d77e5f93d..cb0639d85d 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Chat.Selection private Color4 topicColour; private Color4 hoverColour; - public IEnumerable FilterTerms => new[] { channel.Name }; + public IEnumerable FilterTerms => new[] { channel.Name, channel.Topic }; public bool MatchingFilter { From c4dc34eefde8740e12bd2ed974f81841d862c878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Sep 2019 13:10:11 +0200 Subject: [PATCH 572/645] Consolidate HoverClickSounds constructors As suggested in review, merge both HoverClickSounds constructors into one accepting optional arguments. Due to existing usages the parameter is added as second and supplied by name in ModButton. --- .../Graphics/UserInterface/HoverClickSounds.cs | 18 ++++++------------ osu.Game/Overlays/Mods/ModButton.cs | 2 +- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 8fe20e3566..7e6c0a0974 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -20,24 +20,18 @@ namespace osu.Game.Graphics.UserInterface private SampleChannel sampleClick; private readonly MouseButton[] buttons; - /// - /// Creates an instance that adds sounds on hover and left click only. - /// - /// Set of click samples to play. - public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal) - : this(new[] { MouseButton.Left }, sampleSet) - { - } - /// /// Creates an instance that adds sounds on hover and on click for any of the buttons specified. /// - /// Array of button codes which should trigger the click sound. /// Set of click samples to play. - public HoverClickSounds(MouseButton[] buttons, HoverSampleSet sampleSet = HoverSampleSet.Normal) + /// + /// Array of button codes which should trigger the click sound. + /// If this optional parameter is omitted or set to null, the click sound will also be added on left click. + /// + public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal, MouseButton[] buttons = null) : base(sampleSet) { - this.buttons = buttons; + this.buttons = buttons ?? new[] { MouseButton.Left }; } protected override bool OnMouseUp(MouseUpEvent e) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index f46555dc4b..58892cd0dd 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -283,7 +283,7 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Font = OsuFont.GetFont(size: 18) }, - new HoverClickSounds(new[] { MouseButton.Left, MouseButton.Right }) + new HoverClickSounds(buttons: new[] { MouseButton.Left, MouseButton.Right }) }; Mod = mod; From fc48b190fedb15f243e6087315567907cc80c166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Sep 2019 13:32:53 +0200 Subject: [PATCH 573/645] Fix inaccurate xmldoc --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 7e6c0a0974..050e5a2835 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -26,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface /// Set of click samples to play. /// /// Array of button codes which should trigger the click sound. - /// If this optional parameter is omitted or set to null, the click sound will also be added on left click. + /// If this optional parameter is omitted or set to null, the click sound will only be added on left click. /// public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal, MouseButton[] buttons = null) : base(sampleSet) From 7ca51d3866657302a2c30f90b5e7a757bdb3fe93 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 11:20:50 +0900 Subject: [PATCH 574/645] Fix resume overlay being drawn below cursor Closes #5905. --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 11 +++++++---- osu.Game/Screens/Play/Player.cs | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 021bd515b5..0ee9196fb8 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -215,10 +215,6 @@ namespace osu.Game.Rulesets.UI continueResume(); } - public ResumeOverlay ResumeOverlay { get; private set; } - - protected virtual ResumeOverlay CreateResumeOverlay() => null; - /// /// Creates and adds the visual representation of a to this . /// @@ -389,6 +385,13 @@ namespace osu.Game.Rulesets.UI /// public abstract GameplayCursorContainer Cursor { get; } + /// + /// An optional overlay used when resuming gameplay from a paused state. + /// + public ResumeOverlay ResumeOverlay { get; protected set; } + + protected virtual ResumeOverlay CreateResumeOverlay() => null; + /// /// Sets a replay to be used, overriding local input. /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index b487f3e61b..3f1603eabe 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -178,6 +178,7 @@ namespace osu.Game.Screens.Play }, // display the cursor above some HUD elements. DrawableRuleset.Cursor?.CreateProxy() ?? new Container(), + DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(), HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value) { HoldToQuit = From 2bd074883a834305efbf5a89610e2c442a08dc64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 12:36:08 +0900 Subject: [PATCH 575/645] Fix OsuLegacySkin fallback logic being incorrect Fixes skin fonts not being applied. This is a temporary fix as configuration retrieval from skins will see a complete rewrite over the coming days. --- osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs index 904064e2f0..ea7257d258 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkin.cs @@ -115,7 +115,13 @@ namespace osu.Game.Rulesets.Osu.Skinning public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration - => configuration.Value is TConfiguration conf ? query.Invoke(conf) : source.GetValue(query); + { + TValue val; + if (configuration.Value is TConfiguration conf && (val = query.Invoke(conf)) != null) + return val; + + return source.GetValue(query); + } private bool hasFont(string fontName) => source.GetTexture($"{fontName}-0") != null; } From cad68bb82fce1bfdaed3ca85b092b39f484cb222 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 12:54:59 +0900 Subject: [PATCH 576/645] Add autoplay helper property --- osu.Game/Tests/Visual/PlayerTestScene.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 1ab20ecd48..599cb060b1 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -3,6 +3,7 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Rulesets; @@ -40,6 +41,8 @@ namespace osu.Game.Tests.Visual protected virtual bool AllowFail => false; + protected virtual bool Autoplay => false; + private void loadPlayer() { var beatmap = CreateBeatmap(ruleset.RulesetInfo); @@ -53,6 +56,16 @@ namespace osu.Game.Tests.Visual LoadScreen(Player); } - protected virtual Player CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false); + protected virtual Player CreatePlayer(Ruleset ruleset) + { + if (Autoplay) + { + var mod = ruleset.GetAutoplayMod(); + if (mod != null) + Mods.Value = Mods.Value.Concat(mod.Yield()).ToArray(); + } + + return new TestPlayer(false, false); + } } } From 2945fef62d5afbd53ad3022bd9304d34d108fe0d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 13:04:30 +0900 Subject: [PATCH 577/645] Expose HasCompleted from ScoreProcessor --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index e47df6b473..3b7e457990 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Scoring /// /// Whether all s have been processed. /// - protected virtual bool HasCompleted => false; + public virtual bool HasCompleted => false; /// /// Whether this ScoreProcessor has already triggered the failed state. @@ -205,7 +205,7 @@ namespace osu.Game.Rulesets.Scoring private const double combo_portion = 0.7; private const double max_score = 1000000; - protected sealed override bool HasCompleted => JudgedHits == MaxHits; + public sealed override bool HasCompleted => JudgedHits == MaxHits; protected int MaxHits { get; private set; } protected int JudgedHits { get; private set; } From fc668d8a74898586c8a774fd1bd50f36032c7746 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 13:24:39 +0900 Subject: [PATCH 578/645] Move autoplay mod to a less overridable location --- osu.Game/Tests/Visual/PlayerTestScene.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 599cb060b1..ccd996098c 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -52,12 +52,6 @@ namespace osu.Game.Tests.Visual if (!AllowFail) Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; - Player = CreatePlayer(ruleset); - LoadScreen(Player); - } - - protected virtual Player CreatePlayer(Ruleset ruleset) - { if (Autoplay) { var mod = ruleset.GetAutoplayMod(); @@ -65,7 +59,10 @@ namespace osu.Game.Tests.Visual Mods.Value = Mods.Value.Concat(mod.Yield()).ToArray(); } - return new TestPlayer(false, false); + Player = CreatePlayer(ruleset); + LoadScreen(Player); } + + protected virtual Player CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false); } } From 5b685c4cd2929f759be82a973f3f187f1642d50f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 13:25:39 +0900 Subject: [PATCH 579/645] Fix swell ticks having non-zero time offsets --- .../TestSceneSwellJudgements.cs | 74 +++++++++++++++++++ .../Objects/Drawables/DrawableSwellTick.cs | 6 +- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs new file mode 100644 index 0000000000..f27e329e8e --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs @@ -0,0 +1,74 @@ +// 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 NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Taiko.Judgements; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Taiko.Tests +{ + public class TestSceneSwellJudgements : PlayerTestScene + { + protected new TestPlayer Player => (TestPlayer)base.Player; + + public TestSceneSwellJudgements() + : base(new TaikoRuleset()) + { + } + + [Test] + public void TestZeroTickTimeOffsets() + { + AddUntilStep("gameplay finished", () => Player.ScoreProcessor.HasCompleted); + AddAssert("all tick offsets are 0", () => Player.Results.Where(r => r.Judgement is TaikoSwellTickJudgement).All(r => r.TimeOffset == 0)); + } + + protected override bool Autoplay => true; + + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) + { + var beatmap = new Beatmap + { + BeatmapInfo = { Ruleset = new TaikoRuleset().RulesetInfo }, + HitObjects = + { + new Swell + { + StartTime = 1000, + Duration = 1000, + } + } + }; + + return beatmap; + } + + protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer(); + + protected class TestPlayer : Player + { + public readonly List Results = new List(); + + public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + + public TestPlayer() + : base(false, false) + { + } + + [BackgroundDependencyLoader] + private void load() + { + ScoreProcessor.NewJudgement += r => Results.Add(r); + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 8b27d78101..4833d420f7 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -14,7 +14,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { } - public void TriggerResult(HitResult type) => ApplyResult(r => r.Type = type); + public void TriggerResult(HitResult type) + { + HitObject.StartTime = Time.Current; + ApplyResult(r => r.Type = type); + } protected override void CheckForResult(bool userTriggered, double timeOffset) { From 1df422e59135964b243ac168ba15bf8fd843a722 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 13:30:08 +0900 Subject: [PATCH 580/645] Hide taiko swell ticks --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 8b27d78101..c2e8c08e7e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.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 osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -14,6 +15,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { } + protected override void UpdateInitialTransforms() => this.FadeOut(); + public void TriggerResult(HitResult type) => ApplyResult(r => r.Type = type); protected override void CheckForResult(bool userTriggered, double timeOffset) From 6603cbd74d2a5d4d0450af0953ea39452844ec89 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 13:41:14 +0900 Subject: [PATCH 581/645] No language doesn't mean "Other" --- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 72db03a5a6..df077a65a9 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.BeatmapSet source.Text = b.NewValue?.Metadata.Source ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? "Unspecified"; - language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? "Other"; + language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? "Unspecified"; }; } From d4c12881f5fd4417d6d108da0719001619fd0893 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 13:45:13 +0900 Subject: [PATCH 582/645] Remove unnecessary over-complication and fix transitions --- osu.Game/Overlays/BeatmapSet/Info.cs | 30 ++++++---------------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index df077a65a9..16d6236051 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -83,24 +83,12 @@ namespace osu.Game.Overlays.BeatmapSet { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - LayoutDuration = transition_duration, + Direction = FillDirection.Full, Children = new[] { source = new MetadataSection("Source"), - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Width = 0.5f, - FillMode = FillMode.Fit, - Children = new Drawable[] - { - genre = new MetadataSection("Genre"), - language = new MetadataSection("Language"), - } - }, + genre = new MetadataSection("Genre") { Width = 0.5f }, + language = new MetadataSection("Language") { Width = 0.5f }, tags = new MetadataSection("Tags"), }, }, @@ -132,8 +120,8 @@ namespace osu.Game.Overlays.BeatmapSet { source.Text = b.NewValue?.Metadata.Source ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; - genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? "Unspecified"; - language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? "Unspecified"; + genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty; + language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? string.Empty; }; } @@ -154,7 +142,7 @@ namespace osu.Game.Overlays.BeatmapSet { if (string.IsNullOrEmpty(value)) { - this.FadeOut(transition_duration); + Hide(); return; } @@ -164,12 +152,6 @@ namespace osu.Game.Overlays.BeatmapSet } } - public Color4 TextColour - { - get => textFlow.Colour; - set => textFlow.Colour = value; - } - public MetadataSection(string title) { RelativeSizeAxes = Axes.X; From 0f04357f1f0759c0560ed555f6e1071c1d4caef0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 14:41:14 +0900 Subject: [PATCH 583/645] Revert short name change for now --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index cd2f8d56af..5428b4eeb8 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); - public const string SHORT_NAME = "catch"; + public const string SHORT_NAME = "fruits"; public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { From 8f8d35bd15f27f5613bfb9506c96266288081dee Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 15:02:16 +0900 Subject: [PATCH 584/645] Delay initial hitobject state computation --- .../Objects/Drawables/DrawableHitObject.cs | 9 ++++++ .../Scrolling/ScrollingHitObjectContainer.cs | 29 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4a6f261905..a24476418c 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -9,6 +9,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Primitives; +using osu.Framework.Threading; using osu.Game.Audio; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; @@ -278,6 +279,14 @@ namespace osu.Game.Rulesets.Objects.Drawables UpdateResult(false); } + /// + /// Schedules an to this . + /// + /// + /// Only provided temporarily until hitobject pooling is implemented. + /// + protected internal new ScheduledDelegate Schedule(Action action) => base.Schedule(action); + private double? lifetimeStart; public override double LifetimeStart diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 1df8c8218f..107d55ff0d 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.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.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Caching; @@ -86,13 +87,34 @@ namespace osu.Game.Rulesets.UI.Scrolling scrollingInfo.Algorithm.Reset(); foreach (var obj in Objects) + { + computeLifetimeStartRecursive(obj); computeInitialStateRecursive(obj); + } + initialStateCache.Validate(); } } - private void computeInitialStateRecursive(DrawableHitObject hitObject) + private void computeLifetimeStartRecursive(DrawableHitObject hitObject) { + hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value); + + foreach (var obj in hitObject.NestedHitObjects) + computeLifetimeStartRecursive(obj); + } + + private readonly Dictionary hitObjectInitialStateCache = new Dictionary(); + + // Cant use AddOnce() since the delegate is re-constructed every invocation + private void computeInitialStateRecursive(DrawableHitObject hitObject) => hitObject.Schedule(() => + { + if (!hitObjectInitialStateCache.TryGetValue(hitObject, out var cached)) + cached = hitObjectInitialStateCache[hitObject] = new Cached(); + + if (cached.IsValid) + return; + double endTime = hitObject.HitObject.StartTime; if (hitObject.HitObject is IHasEndTime e) @@ -113,7 +135,6 @@ namespace osu.Game.Rulesets.UI.Scrolling } } - hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value); hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime, timeRange.Value, scrollLength); foreach (var obj in hitObject.NestedHitObjects) @@ -123,7 +144,9 @@ namespace osu.Game.Rulesets.UI.Scrolling // Nested hitobjects don't need to scroll, but they do need accurate positions updatePosition(obj, hitObject.HitObject.StartTime); } - } + + cached.Validate(); + }); protected override void UpdateAfterChildrenLife() { From d74e1b9b6473613784be40adcf3202ae3f3908f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 15:06:43 +0900 Subject: [PATCH 585/645] Remove from dictionary on Remove() --- .../Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 107d55ff0d..bd1f496dfa 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -51,8 +51,13 @@ namespace osu.Game.Rulesets.UI.Scrolling public override bool Remove(DrawableHitObject hitObject) { var result = base.Remove(hitObject); + if (result) + { initialStateCache.Invalidate(); + hitObjectInitialStateCache.Remove(hitObject); + } + return result; } From c06908adf7c653f98fddda7d08f55e50a290b642 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 15:37:38 +0900 Subject: [PATCH 586/645] Fix spacing specifications --- .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 408468fa73..9b81e8c573 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Spacing = new Vector2(3), + Spacing = new Vector2(0, 3), }, date = new DrawableDate(historyItem.CreatedAt) { @@ -59,14 +59,15 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu if (!string.IsNullOrEmpty(prefix)) { linkFlowContainer.AddText(prefix); - linkFlowContainer.AddText($@"{Math.Abs(historyItem.Amount)} kudosu", t => + linkFlowContainer.AddText($@" {Math.Abs(historyItem.Amount)} kudosu ", t => { t.Font = t.Font.With(italics: true); t.Colour = colours.Blue; }); } - linkFlowContainer.AddLinks(formattedSource.Text + " ", formattedSource.Links); + linkFlowContainer.AddLinks(formattedSource.Text, formattedSource.Links); + linkFlowContainer.AddText(" "); linkFlowContainer.AddLink(historyItem.Post.Title, historyItem.Post.Url); } From da4507037333adcda31a9512f101b667cddb77ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 15:44:21 +0900 Subject: [PATCH 587/645] Group common prefixes together --- .../Kudosu/DrawableKudosuHistoryItem.cs | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 9b81e8c573..ff64ea5648 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -120,29 +120,17 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu switch (historyItem.Action) { case KudosuAction.VoteGive: - return @"Received"; - case KudosuAction.Give: + case KudosuAction.AllowKudosuGive: + case KudosuAction.RestoreGive: + case KudosuAction.RecalculateGive: return @"Received"; - case KudosuAction.VoteReset: - return @"Lost"; - case KudosuAction.DenyKudosuReset: return @"Denied"; - case KudosuAction.AllowKudosuGive: - return @"Received"; - case KudosuAction.DeleteReset: - return @"Lost"; - - case KudosuAction.RestoreGive: - return @"Received"; - - case KudosuAction.RecalculateGive: - return @"Received"; - + case KudosuAction.VoteReset: case KudosuAction.RecalculateReset: return @"Lost"; From 3d551b08a96a1d9be3130a9b5bf27613fced44bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 15:57:23 +0900 Subject: [PATCH 588/645] Rename legacy actions --- .../Visual/Online/TestSceneKudosuHistory.cs | 6 +++--- .../API/Requests/GetUserKudosuHistoryRequest.cs | 16 ++++++++-------- .../Sections/Kudosu/DrawableKudosuHistoryItem.cs | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index 8badfeaa23..a4f3bf65e6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual.Online { Amount = 5, CreatedAt = new DateTimeOffset(new DateTime(2012, 10, 11)), - Action = KudosuAction.Give, + Action = KudosuAction.ForumGive, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 2", @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.Online { Amount = 8, CreatedAt = new DateTimeOffset(new DateTime(2013, 9, 11)), - Action = KudosuAction.Reset, + Action = KudosuAction.ForumReset, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 3", @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.Online { Amount = 7, CreatedAt = new DateTimeOffset(new DateTime(2014, 8, 11)), - Action = KudosuAction.Revoke, + Action = KudosuAction.ForumRevoke, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 4", diff --git a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs index dd6f2ccf22..32aa0c15fa 100644 --- a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs @@ -21,16 +21,16 @@ namespace osu.Game.Online.API.Requests public enum KudosuAction { - Give, - VoteGive, - Reset, - VoteReset, - DenyKudosuReset, - Revoke, AllowKudosuGive, DeleteReset, - RestoreGive, + DenyKudosuReset, + ForumGive, + ForumReset, + ForumRevoke, RecalculateGive, - RecalculateReset + RecalculateReset, + RestoreGive, + VoteGive, + VoteReset, } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index ff64ea5648..5229269def 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -80,10 +80,10 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu case KudosuAction.VoteGive: return @"from obtaining votes in modding post of"; - case KudosuAction.Give: + case KudosuAction.ForumGive: return $@"from {userLink()} for a post at"; - case KudosuAction.Reset: + case KudosuAction.ForumReset: return $@"Kudosu reset by {userLink()} for the post"; case KudosuAction.VoteReset: @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu case KudosuAction.DenyKudosuReset: return @"from modding post"; - case KudosuAction.Revoke: + case KudosuAction.ForumRevoke: return $@"Denied kudosu by {userLink()} for the post"; case KudosuAction.AllowKudosuGive: @@ -120,7 +120,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu switch (historyItem.Action) { case KudosuAction.VoteGive: - case KudosuAction.Give: + case KudosuAction.ForumGive: case KudosuAction.AllowKudosuGive: case KudosuAction.RestoreGive: case KudosuAction.RecalculateGive: From 0985b1679f86de6a4a96d34edb0e84cb30a55dac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 15:57:55 +0900 Subject: [PATCH 589/645] Move enum to response class --- .../Visual/Online/TestSceneKudosuHistory.cs | 1 - .../API/Requests/GetUserKudosuHistoryRequest.cs | 15 --------------- .../API/Requests/Responses/APIKudosuHistory.cs | 15 +++++++++++++++ .../Sections/Kudosu/DrawableKudosuHistoryItem.cs | 1 - 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index a4f3bf65e6..84152e40fa 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Online.API.Requests; using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Tests.Visual.Online diff --git a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs index 32aa0c15fa..e90e297672 100644 --- a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs @@ -18,19 +18,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $"users/{userId}/kudosu"; } - - public enum KudosuAction - { - AllowKudosuGive, - DeleteReset, - DenyKudosuReset, - ForumGive, - ForumReset, - ForumRevoke, - RecalculateGive, - RecalculateReset, - RestoreGive, - VoteGive, - VoteReset, - } } diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index f2297f7a10..25b11a6cf9 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -53,4 +53,19 @@ namespace osu.Game.Online.API.Requests.Responses public KudosuAction Action; } + + public enum KudosuAction + { + AllowKudosuGive, + DeleteReset, + DenyKudosuReset, + ForumGive, + ForumReset, + ForumRevoke, + RecalculateGive, + RecalculateReset, + RestoreGive, + VoteGive, + VoteReset, + } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 5229269def..6efe9825ec 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; using System; using osuTK; From 0a89603e79871ffa10c7858759ce231a6113f2b5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 16:07:16 +0900 Subject: [PATCH 590/645] Fix hit error potentially not displaying with null hitwindows --- osu.Game/Screens/Play/HUDOverlay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 8e642ea552..eac45f9214 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -259,7 +259,9 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.FirstOrDefault()?.HitWindows); + protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay( + scoreProcessor, + drawableRuleset.Objects.Concat(drawableRuleset.Objects.SelectMany(h => h.NestedHitObjects)).FirstOrDefault(h => h.HitWindows != null)?.HitWindows); protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From f3656475de102de8379409868d63aecc321ebe9f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 16:10:30 +0900 Subject: [PATCH 591/645] Return null hitwindows for non-time-based objects --- osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 3 +++ osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs | 3 +++ osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 ++ osu.Game.Rulesets.Osu/Objects/SliderTick.cs | 3 +++ osu.Game.Rulesets.Osu/Objects/Spinner.cs | 3 +++ osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 3 +++ osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs | 3 +++ osu.Game.Rulesets.Taiko/Objects/StrongHitObject.cs | 3 +++ osu.Game.Rulesets.Taiko/Objects/Swell.cs | 3 +++ osu.Game.Rulesets.Taiko/Objects/SwellTick.cs | 3 +++ 10 files changed, 29 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index 5e9f46d9c7..d28d04b3c1 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -5,6 +5,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Mania.Objects @@ -99,5 +100,7 @@ namespace osu.Game.Rulesets.Mania.Objects } public override Judgement CreateJudgement() => new HoldNoteJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs index c133ee73b1..6bb21633b6 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs @@ -3,6 +3,7 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mania.Objects { @@ -12,5 +13,7 @@ namespace osu.Game.Rulesets.Mania.Objects public class HoldNoteTick : ManiaHitObject { public override Judgement CreateJudgement() => new HoldNoteTickJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index d3279652c7..93231844bb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -229,5 +229,7 @@ namespace osu.Game.Rulesets.Osu.Objects nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples; public override Judgement CreateJudgement() => new OsuJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs index 85439699dd..60e9084ed3 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs @@ -4,6 +4,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects @@ -30,5 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects } public override Judgement CreateJudgement() => new OsuJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index 8a2fd3b7aa..69c779a182 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -6,6 +6,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects @@ -31,5 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects } public override Judgement CreateJudgement() => new OsuJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 1d25735fe3..3ed52f21f0 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -6,6 +6,7 @@ using System; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects @@ -86,5 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Objects } public override Judgement CreateJudgement() => new TaikoDrumRollJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs index 8448036f76..39e2b45e24 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects @@ -25,5 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Objects public double HitWindow => TickSpacing / 2; public override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/StrongHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/StrongHitObject.cs index 2a03c23934..830e640242 100644 --- a/osu.Game.Rulesets.Taiko/Objects/StrongHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/StrongHitObject.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects @@ -9,5 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Objects public class StrongHitObject : TaikoHitObject { public override Judgement CreateJudgement() => new TaikoStrongJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index befa728570..e7812841bf 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -4,6 +4,7 @@ using System; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects @@ -33,5 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects } public override Judgement CreateJudgement() => new TaikoSwellJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs index c2ae784b2a..049fa7de5f 100644 --- a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects @@ -9,5 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Objects public class SwellTick : TaikoHitObject { public override Judgement CreateJudgement() => new TaikoSwellTickJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } From f2bdf94a1dda65e33a45ce3007b03c4d95f649ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 16:28:14 +0900 Subject: [PATCH 592/645] Add HitWindows to JudgementResult to indicate timing errors --- .../TestSceneDrawableJudgement.cs | 3 ++- .../Judgements/OsuJudgementResult.cs | 5 +++-- .../Objects/Drawables/DrawableOsuHitObject.cs | 3 ++- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 +- .../TestSceneTaikoPlayfield.cs | 8 ++++---- .../Visual/Gameplay/TestSceneBarHitErrorMeter.cs | 2 +- osu.Game/Rulesets/Judgements/JudgementResult.cs | 14 +++++++++++++- .../Objects/Drawables/DrawableHitObject.cs | 6 ++++-- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 3 +++ 10 files changed, 34 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs index 82a8d0e5e6..6d240ee009 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Scoring; @@ -24,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests { foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) AddStep("Show " + result.GetDescription(), () => SetContents(() => - new DrawableOsuJudgement(new JudgementResult(null) { Type = result }, null) + new DrawableOsuJudgement(new JudgementResult(null, new HitWindows()) { Type = result }, null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs index c7661bddb1..367c2c8f14 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Osu.Judgements { @@ -9,8 +10,8 @@ namespace osu.Game.Rulesets.Osu.Judgements { public ComboResult ComboType; - public OsuJudgementResult(Judgement judgement) - : base(judgement) + public OsuJudgementResult(Judgement judgement, HitWindows hitWindows) + : base(judgement, hitWindows) { } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index b4f5642f45..02b6a932d3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -41,6 +42,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength); - protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement); + protected override JudgementResult CreateResult(Judgement judgement, HitWindows hitWindows) => new OsuJudgementResult(judgement, hitWindows); } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index cf0565c6da..08dc355bcf 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Scoring } } - protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement); + protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement, null); public override HitWindows CreateHitWindows() => new OsuHitWindows(); } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index 3c84d900a6..2db1e3e70a 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = hitResult }); } private void addStrongHitJudgement(bool kiai) @@ -159,13 +159,13 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement()) { Type = hitResult }); - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new TaikoStrongJudgement()) { Type = HitResult.Great }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new TaikoStrongJudgement(), new TaikoHitWindows()) { Type = HitResult.Great }); } private void addMissJudgement() { - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new TaikoJudgement()) { Type = HitResult.Miss }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = HitResult.Miss }); } private void addBarLine(bool major, double delay = scroll_time) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index f20440249b..0376e775bc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void newJudgement(double offset = 0) { - var judgement = new JudgementResult(new Judgement()) + var judgement = new JudgementResult(new Judgement(), hitWindows) { TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, diff --git a/osu.Game/Rulesets/Judgements/JudgementResult.cs b/osu.Game/Rulesets/Judgements/JudgementResult.cs index 195fe316ac..aea3c9085b 100644 --- a/osu.Game/Rulesets/Judgements/JudgementResult.cs +++ b/osu.Game/Rulesets/Judgements/JudgementResult.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 JetBrains.Annotations; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; @@ -21,6 +23,13 @@ namespace osu.Game.Rulesets.Judgements /// public readonly Judgement Judgement; + /// + /// The which the was judged against. + /// May be null to indicate that the timing error should not be displayed to the user. + /// + [CanBeNull] + public readonly HitWindows HitWindows; + /// /// The offset from a perfect hit at which this occurred. /// Populated when this is applied via . @@ -56,9 +65,12 @@ namespace osu.Game.Rulesets.Judgements /// Creates a new . /// /// The to refer to for scoring information. - public JudgementResult(Judgement judgement) + /// The which the was judged against. + /// May be null to indicate that the timing error should not be displayed to the user. + public JudgementResult([NotNull] Judgement judgement, [CanBeNull] HitWindows hitWindows) { Judgement = judgement; + HitWindows = hitWindows; } public override string ToString() => $"{Type} (Score:{Judgement.NumericResultFor(this)} HP:{Judgement.HealthIncreaseFor(this)} {Judgement})"; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4a6f261905..4106f8320f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (judgement != null) { - Result = CreateResult(judgement); + Result = CreateResult(judgement, HitObject.HitWindows); if (Result == null) throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); } @@ -401,7 +401,9 @@ namespace osu.Game.Rulesets.Objects.Drawables /// Creates the that represents the scoring result for this . /// /// The that provides the scoring information. - protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement); + /// The which the was judged against. + /// May be null to indicate that the timing error should not be displayed to the user. + protected virtual JudgementResult CreateResult(Judgement judgement, HitWindows hitWindows) => new JudgementResult(judgement, hitWindows); } public abstract class DrawableHitObject : DrawableHitObject diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 3b7e457990..3230551386 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -442,7 +442,7 @@ namespace osu.Game.Rulesets.Scoring /// Creates the that represents the scoring result for a . /// /// The that provides the scoring information. - protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement); + protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement, null); } public enum ScoringMode diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index cdfa0e993b..3e925a5a50 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -49,6 +49,9 @@ namespace osu.Game.Screens.Play.HUD private void onNewJudgement(JudgementResult result) { + if (result.HitWindows == null) + return; + foreach (var c in Children) c.OnNewJudgement(result); } From d21d68b36c4271d611db888c1917e09ee93b95ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 16:34:11 +0900 Subject: [PATCH 593/645] Refactor to match web implementation 1:1 --- .../Visual/Online/TestSceneKudosuHistory.cs | 33 +++-- .../Requests/Responses/APIKudosuHistory.cs | 44 ++++-- .../Kudosu/DrawableKudosuHistoryItem.cs | 138 +++++++++--------- 3 files changed, 122 insertions(+), 93 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index 84152e40fa..325d657f0e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -58,7 +58,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 10, CreatedAt = new DateTimeOffset(new DateTime(2011, 11, 11)), - Action = KudosuAction.DenyKudosuReset, + Source = KudosuSource.DenyKudosu, + Action = KudosuAction.Reset, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 1", @@ -74,7 +75,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 5, CreatedAt = new DateTimeOffset(new DateTime(2012, 10, 11)), - Action = KudosuAction.ForumGive, + Source = KudosuSource.Forum, + Action = KudosuAction.Give, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 2", @@ -90,7 +92,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 8, CreatedAt = new DateTimeOffset(new DateTime(2013, 9, 11)), - Action = KudosuAction.ForumReset, + Source = KudosuSource.Forum, + Action = KudosuAction.Reset, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 3", @@ -106,7 +109,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 7, CreatedAt = new DateTimeOffset(new DateTime(2014, 8, 11)), - Action = KudosuAction.ForumRevoke, + Source = KudosuSource.Forum, + Action = KudosuAction.Revoke, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 4", @@ -122,7 +126,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 100, CreatedAt = new DateTimeOffset(new DateTime(2015, 7, 11)), - Action = KudosuAction.VoteGive, + Source = KudosuSource.Vote, + Action = KudosuAction.Give, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 5", @@ -138,7 +143,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 20, CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)), - Action = KudosuAction.VoteReset, + Source = KudosuSource.Vote, + Action = KudosuAction.Reset, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 6", @@ -154,7 +160,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 11, CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)), - Action = KudosuAction.AllowKudosuGive, + Source = KudosuSource.AllowKudosu, + Action = KudosuAction.Give, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 7", @@ -170,7 +177,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 24, CreatedAt = new DateTimeOffset(new DateTime(2014, 6, 11)), - Action = KudosuAction.DeleteReset, + Source = KudosuSource.Delete, + Action = KudosuAction.Reset, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 8", @@ -186,7 +194,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 12, CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)), - Action = KudosuAction.RestoreGive, + Source = KudosuSource.Restore, + Action = KudosuAction.Give, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 9", @@ -202,7 +211,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 2, CreatedAt = new DateTimeOffset(new DateTime(2012, 6, 11)), - Action = KudosuAction.RecalculateGive, + Source = KudosuSource.Recalculate, + Action = KudosuAction.Give, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 10", @@ -218,7 +228,8 @@ namespace osu.Game.Tests.Visual.Online { Amount = 32, CreatedAt = new DateTimeOffset(new DateTime(2019, 8, 11)), - Action = KudosuAction.RecalculateReset, + Source = KudosuSource.Recalculate, + Action = KudosuAction.Reset, Post = new APIKudosuHistory.ModdingPost { Title = @"Random post 11", diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index 25b11a6cf9..d596ddc560 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -2,7 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using Humanizer; +using System.Linq; using Newtonsoft.Json; namespace osu.Game.Online.API.Requests.Responses @@ -39,33 +39,45 @@ namespace osu.Game.Online.API.Requests.Responses public string Username; } + public KudosuSource Source; + + public KudosuAction Action; + [JsonProperty("action")] private string action { set { - //We will receive something like "event.action" or just "action" - string parsed = value.Contains(".") ? value.Split('.')[0].Pascalize() + value.Split('.')[1].Pascalize() : value.Pascalize(); + // incoming action may contain a prefix. if it doesn't, it's a legacy forum event. - Action = (KudosuAction)Enum.Parse(typeof(KudosuAction), parsed); + string[] split = value.Split('.'); + + if (split.Length > 1) + Enum.TryParse(split.First().Replace("_", ""), true, out Source); + else + Source = KudosuSource.Forum; + + Enum.TryParse(split.Last(), true, out Action); } } + } - public KudosuAction Action; + public enum KudosuSource + { + Unknown, + AllowKudosu, + Delete, + DenyKudosu, + Forum, + Recalculate, + Restore, + Vote } public enum KudosuAction { - AllowKudosuGive, - DeleteReset, - DenyKudosuReset, - ForumGive, - ForumReset, - ForumRevoke, - RecalculateGive, - RecalculateReset, - RestoreGive, - VoteGive, - VoteReset, + Give, + Reset, + Revoke, } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 6efe9825ec..d0cfe9fa54 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -51,91 +51,97 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu private void load() { date.Colour = colours.GreySeafoamLighter; - - string prefix = getPrefix(historyItem); - var formattedSource = MessageFormatter.FormatText(getSource(historyItem)); - - if (!string.IsNullOrEmpty(prefix)) - { - linkFlowContainer.AddText(prefix); - linkFlowContainer.AddText($@" {Math.Abs(historyItem.Amount)} kudosu ", t => - { - t.Font = t.Font.With(italics: true); - t.Colour = colours.Blue; - }); - } - + var formattedSource = MessageFormatter.FormatText(getString(historyItem)); linkFlowContainer.AddLinks(formattedSource.Text, formattedSource.Links); - linkFlowContainer.AddText(" "); - linkFlowContainer.AddLink(historyItem.Post.Title, historyItem.Post.Url); } - private string getSource(APIKudosuHistory historyItem) + private string getString(APIKudosuHistory item) { - string userLink() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; + string amount = $"{Math.Abs(item.Amount)} kudosu"; + string post = $"[{item.Post.Title}]({item.Post.Url})"; - switch (historyItem.Action) + switch (item.Source) { - case KudosuAction.VoteGive: - return @"from obtaining votes in modding post of"; + case KudosuSource.AllowKudosu: + switch (item.Action) + { + case KudosuAction.Give: + return $"Received {amount} from kudosu deny repeal of modding post {post}"; + } - case KudosuAction.ForumGive: - return $@"from {userLink()} for a post at"; + break; - case KudosuAction.ForumReset: - return $@"Kudosu reset by {userLink()} for the post"; + case KudosuSource.DenyKudosu: + switch (item.Action) + { + case KudosuAction.Reset: + return $"Denied {amount} from modding post {post}"; + } - case KudosuAction.VoteReset: - return @"from losing votes in modding post of"; + break; - case KudosuAction.DenyKudosuReset: - return @"from modding post"; + case KudosuSource.Delete: + switch (item.Action) + { + case KudosuAction.Reset: + return $"Lost {amount} from modding post deletion of {post}"; + } - case KudosuAction.ForumRevoke: - return $@"Denied kudosu by {userLink()} for the post"; + break; - case KudosuAction.AllowKudosuGive: - return @"from kudosu deny repeal of modding post"; + case KudosuSource.Restore: + switch (item.Action) + { + case KudosuAction.Give: + return $"Received {amount} from modding post restoration of {post}"; + } - case KudosuAction.DeleteReset: - return @"from modding post deletion of"; + break; - case KudosuAction.RestoreGive: - return @"from modding post restoration of"; + case KudosuSource.Vote: + switch (item.Action) + { + case KudosuAction.Give: + return $"Received {amount} from obtaining votes in modding post of {post}"; - case KudosuAction.RecalculateGive: - return @"from votes recalculation in modding post of"; + case KudosuAction.Reset: + return $"Lost {amount} from losing votes in modding post of {post}"; + } - case KudosuAction.RecalculateReset: - return @"from votes recalculation in modding post of"; + break; - default: - return @"from unknown event"; + case KudosuSource.Recalculate: + switch (item.Action) + { + case KudosuAction.Give: + return $"Received {amount} from votes recalculation in modding post of {post}"; + + case KudosuAction.Reset: + return $"Lost {amount} from votes recalculation in modding post of {post}"; + } + + break; + + case KudosuSource.Forum: + + string giver = $"[{item.Giver?.Username}]({item.Giver?.Url})"; + + switch (historyItem.Action) + { + case KudosuAction.Give: + return $"Received {amount} from {giver} for a post at {post}"; + + case KudosuAction.Reset: + return $"Kudosu reset by {giver} for the post {post}"; + + case KudosuAction.Revoke: + return $"Denied kudosu by {giver} for the post {post}"; + } + + break; } - } - private string getPrefix(APIKudosuHistory historyItem) - { - switch (historyItem.Action) - { - case KudosuAction.VoteGive: - case KudosuAction.ForumGive: - case KudosuAction.AllowKudosuGive: - case KudosuAction.RestoreGive: - case KudosuAction.RecalculateGive: - return @"Received"; - - case KudosuAction.DenyKudosuReset: - return @"Denied"; - - case KudosuAction.DeleteReset: - case KudosuAction.VoteReset: - case KudosuAction.RecalculateReset: - return @"Lost"; - - default: - return null; - } + return $"Unknown event ({amount} change)"; } } } From 841da7d69147ce0c1490eae4c500cbd802d1805b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 17:12:32 +0900 Subject: [PATCH 594/645] Fix potential null reference on DirectPanel unbind --- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 641423f21f..a9b6633864 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Direct private BeatmapSetOverlay beatmapSetOverlay; public PreviewTrack Preview => PlayButton.Preview; - public Bindable PreviewPlaying => PlayButton.Playing; + public Bindable PreviewPlaying => PlayButton?.Playing; protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } From 0c73c5acf3b104ebfe5b13832946be6752c5de1c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 17:14:40 +0900 Subject: [PATCH 595/645] Expose full hitobject rather than hit windows --- .../TestSceneDrawableJudgement.cs | 2 +- .../Judgements/OsuJudgementResult.cs | 4 ++-- .../Objects/Drawables/DrawableOsuHitObject.cs | 3 +-- .../Scoring/OsuScoreProcessor.cs | 2 +- .../TestSceneTaikoPlayfield.cs | 8 ++++---- .../Gameplay/TestSceneBarHitErrorMeter.cs | 2 +- .../Rulesets/Judgements/JudgementResult.cs | 19 +++++++++---------- .../Objects/Drawables/DrawableHitObject.cs | 6 ++---- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 5 +++-- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 2 +- 10 files changed, 25 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs index 6d240ee009..433ec6bd25 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests { foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) AddStep("Show " + result.GetDescription(), () => SetContents(() => - new DrawableOsuJudgement(new JudgementResult(null, new HitWindows()) { Type = result }, null) + new DrawableOsuJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs index 367c2c8f14..15444b847b 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgementResult.cs @@ -10,8 +10,8 @@ namespace osu.Game.Rulesets.Osu.Judgements { public ComboResult ComboType; - public OsuJudgementResult(Judgement judgement, HitWindows hitWindows) - : base(judgement, hitWindows) + public OsuJudgementResult(HitObject hitObject, Judgement judgement) + : base(hitObject, judgement) { } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 02b6a932d3..fcd42314fc 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Graphics.Containers; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -42,6 +41,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength); - protected override JudgementResult CreateResult(Judgement judgement, HitWindows hitWindows) => new OsuJudgementResult(judgement, hitWindows); + protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement); } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 08dc355bcf..66ef020d09 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Scoring } } - protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement, null); + protected override JudgementResult CreateResult(HitObject hitObject, Judgement judgement) => new OsuJudgementResult(hitObject, judgement); public override HitWindows CreateHitWindows() => new OsuHitWindows(); } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index 2db1e3e70a..6fd16c213b 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult }); } private void addStrongHitJudgement(bool kiai) @@ -159,13 +159,13 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = hitResult }); - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new TaikoStrongJudgement(), new TaikoHitWindows()) { Type = HitResult.Great }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new HitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great }); } private void addMissJudgement() { - ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = HitResult.Miss }); + ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = HitResult.Miss }); } private void addBarLine(bool major, double delay = scroll_time) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs index 0376e775bc..e9c15dab9b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void newJudgement(double offset = 0) { - var judgement = new JudgementResult(new Judgement(), hitWindows) + var judgement = new JudgementResult(new HitObject(), new Judgement()) { TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, Type = HitResult.Perfect, diff --git a/osu.Game/Rulesets/Judgements/JudgementResult.cs b/osu.Game/Rulesets/Judgements/JudgementResult.cs index aea3c9085b..56dc121b17 100644 --- a/osu.Game/Rulesets/Judgements/JudgementResult.cs +++ b/osu.Game/Rulesets/Judgements/JudgementResult.cs @@ -19,16 +19,16 @@ namespace osu.Game.Rulesets.Judgements public HitResult Type; /// - /// The which this applies for. + /// The which was judged. /// - public readonly Judgement Judgement; + [NotNull] + public readonly HitObject HitObject; /// - /// The which the was judged against. - /// May be null to indicate that the timing error should not be displayed to the user. + /// The which this applies for. /// - [CanBeNull] - public readonly HitWindows HitWindows; + [NotNull] + public readonly Judgement Judgement; /// /// The offset from a perfect hit at which this occurred. @@ -64,13 +64,12 @@ namespace osu.Game.Rulesets.Judgements /// /// Creates a new . /// + /// The which was judged. /// The to refer to for scoring information. - /// The which the was judged against. - /// May be null to indicate that the timing error should not be displayed to the user. - public JudgementResult([NotNull] Judgement judgement, [CanBeNull] HitWindows hitWindows) + public JudgementResult([NotNull] HitObject hitObject, [NotNull] Judgement judgement) { + HitObject = hitObject; Judgement = judgement; - HitWindows = hitWindows; } public override string ToString() => $"{Type} (Score:{Judgement.NumericResultFor(this)} HP:{Judgement.HealthIncreaseFor(this)} {Judgement})"; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4106f8320f..4073bd53ab 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (judgement != null) { - Result = CreateResult(judgement, HitObject.HitWindows); + Result = CreateResult(judgement); if (Result == null) throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); } @@ -401,9 +401,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// Creates the that represents the scoring result for this . /// /// The that provides the scoring information. - /// The which the was judged against. - /// May be null to indicate that the timing error should not be displayed to the user. - protected virtual JudgementResult CreateResult(Judgement judgement, HitWindows hitWindows) => new JudgementResult(judgement, hitWindows); + protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(HitObject, judgement); } public abstract class DrawableHitObject : DrawableHitObject diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 3230551386..86c2c07f2a 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -275,7 +275,7 @@ namespace osu.Game.Rulesets.Scoring if (judgement == null) return; - var result = CreateResult(judgement); + var result = CreateResult(obj, judgement); if (result == null) throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); @@ -441,8 +441,9 @@ namespace osu.Game.Rulesets.Scoring /// /// Creates the that represents the scoring result for a . /// + /// The which was judged. /// The that provides the scoring information. - protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement, null); + protected virtual JudgementResult CreateResult(HitObject hitObject, Judgement judgement) => new JudgementResult(hitObject, judgement); } public enum ScoringMode diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 3e925a5a50..adda94d629 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Play.HUD private void onNewJudgement(JudgementResult result) { - if (result.HitWindows == null) + if (result.HitObject.HitWindows == null) return; foreach (var c in Children) From f6102b4d920ca15ade9af87434ceac6e856d7f9c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 17:15:36 +0900 Subject: [PATCH 596/645] Adjust xmldoc --- osu.Game/Rulesets/Objects/HitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index bf04963b76..f0547550e0 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Objects /// /// Creates the for this . - /// This can be null to indicate that the has no . + /// This can be null to indicate that the has no and timing errors should not be displayed to the user. /// /// This will only be invoked if hasn't been set externally (e.g. from a . /// From 4c150839c0de41487da978017ec4d496e1663417 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 17:38:52 +0900 Subject: [PATCH 597/645] Fix potential diffcalc hitwindow nullref --- .../Difficulty/ManiaDifficultyCalculator.cs | 7 ++++++- .../Difficulty/OsuDifficultyCalculator.cs | 6 +++++- .../Difficulty/TaikoDifficultyCalculator.cs | 6 +++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index 4a9c22d339..d945abdb04 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -11,7 +11,9 @@ using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Difficulty.Preprocessing; using osu.Game.Rulesets.Mania.Difficulty.Skills; using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mania.Difficulty { @@ -32,12 +34,15 @@ namespace osu.Game.Rulesets.Mania.Difficulty if (beatmap.HitObjects.Count == 0) return new ManiaDifficultyAttributes { Mods = mods, Skills = skills }; + HitWindows hitWindows = new ManiaHitWindows(); + hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); + return new ManiaDifficultyAttributes { StarRating = difficultyValue(skills) * star_scaling_factor, Mods = mods, // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future - GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate, + GreatHitWindow = (int)(hitWindows.Great / 2) / clockRate, Skills = skills }; } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index c197933233..61e9f60cdd 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; using osu.Game.Rulesets.Osu.Difficulty.Skills; using osu.Game.Rulesets.Osu.Mods; @@ -34,8 +35,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; + HitWindows hitWindows = new OsuHitWindows(); + hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); + // Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be removed in the future - double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate; + double hitWindowGreat = (int)(hitWindows.Great / 2) / clockRate; double preempt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate; int maxCombo = beatmap.HitObjects.Count; diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index c8f3e18911..fc93bccb94 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing; using osu.Game.Rulesets.Taiko.Difficulty.Skills; using osu.Game.Rulesets.Taiko.Mods; @@ -29,12 +30,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (beatmap.HitObjects.Count == 0) return new TaikoDifficultyAttributes { Mods = mods, Skills = skills }; + HitWindows hitWindows = new TaikoHitWindows(); + hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); + return new TaikoDifficultyAttributes { StarRating = skills.Single().DifficultyValue() * star_scaling_factor, Mods = mods, // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future - GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate, + GreatHitWindow = (int)(hitWindows.Great / 2) / clockRate, MaxCombo = beatmap.HitObjects.Count(h => h is Hit), Skills = skills }; From f20e07136a842f2b23bd52f9a45039757fbcb084 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 17:48:41 +0900 Subject: [PATCH 598/645] Add attribute to catch potential future nullrefs --- osu.Game/Rulesets/Objects/HitObject.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index f0547550e0..5e029139d9 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using JetBrains.Annotations; using Newtonsoft.Json; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -56,6 +57,7 @@ namespace osu.Game.Rulesets.Objects /// /// The hit windows for this . /// + [CanBeNull] public HitWindows HitWindows { get; set; } private readonly List nestedHitObjects = new List(); @@ -116,6 +118,7 @@ namespace osu.Game.Rulesets.Objects /// This will only be invoked if hasn't been set externally (e.g. from a . /// /// + [CanBeNull] protected virtual HitWindows CreateHitWindows() => new HitWindows(); } } From 9c53430a0f7ac80f7d9a4786a7b58c0000f4803a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 18:18:59 +0900 Subject: [PATCH 599/645] Only initialise when required --- osu.Game/Skinning/SkinnableSound.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index bf647baeec..c402df1bde 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -16,7 +16,7 @@ namespace osu.Game.Skinning { private readonly ISampleInfo[] hitSamples; - private readonly List<(AdjustableProperty, BindableDouble)> adjustments = new List<(AdjustableProperty, BindableDouble)>(); + private List<(AdjustableProperty, BindableDouble)> adjustments; private SampleChannel[] channels; @@ -56,13 +56,15 @@ namespace osu.Game.Skinning public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) { + if (adjustments == null) adjustments = new List<(AdjustableProperty, BindableDouble)>(); + adjustments.Add((type, adjustBindable)); channels?.ForEach(c => c.AddAdjustment(type, adjustBindable)); } public void RemoveAdjustment(AdjustableProperty type, BindableDouble adjustBindable) { - adjustments.Remove((type, adjustBindable)); + adjustments?.Remove((type, adjustBindable)); channels?.ForEach(c => c.RemoveAdjustment(type, adjustBindable)); } @@ -84,8 +86,9 @@ namespace osu.Game.Skinning ch.Looping = looping; ch.Volume.Value = s.Volume / 100.0; - foreach (var adjustment in adjustments) - ch.AddAdjustment(adjustment.Item1, adjustment.Item2); + if (adjustments != null) + foreach (var adjustment in adjustments) + ch.AddAdjustment(adjustment.Item1, adjustment.Item2); } return ch; From f08b523abf9b9296f241dd32b841da15549eb3bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 18:20:30 +0900 Subject: [PATCH 600/645] Name tuple items --- osu.Game/Skinning/SkinnableSound.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index c402df1bde..07ffbb8a51 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -16,7 +16,7 @@ namespace osu.Game.Skinning { private readonly ISampleInfo[] hitSamples; - private List<(AdjustableProperty, BindableDouble)> adjustments; + private List<(AdjustableProperty property, BindableDouble bindable)> adjustments; private SampleChannel[] channels; @@ -88,7 +88,7 @@ namespace osu.Game.Skinning if (adjustments != null) foreach (var adjustment in adjustments) - ch.AddAdjustment(adjustment.Item1, adjustment.Item2); + ch.AddAdjustment(adjustment.property, adjustment.bindable); } return ch; From 8302658186b7ff64f63a9c72190d0fa1603d14ad Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 18:31:33 +0900 Subject: [PATCH 601/645] Fix other potential nullref cases that rider missed --- .../Objects/Drawables/DrawableHoldNote.cs | 3 +++ .../Objects/Drawables/DrawableNote.cs | 3 +++ .../TestSceneShaking.cs | 7 +++++-- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 8 +++++++- .../Objects/Drawables/DrawableHitCircle.cs | 5 +++++ .../Replays/OsuAutoGenerator.cs | 18 +++++++++--------- .../Replays/OsuAutoGeneratorBase.cs | 10 ++++++++++ .../Objects/Drawables/DrawableHit.cs | 5 +++++ 8 files changed, 47 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index fc3b6885d7..c5c157608f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.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.Diagnostics; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; @@ -209,6 +210,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { + Debug.Assert(HitObject.HitWindows != null); + // Factor in the release lenience timeOffset /= release_window_lenience; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index dccff7f6ac..2cd81104a3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.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.Diagnostics; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -52,6 +53,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { + Debug.Assert(HitObject.HitWindows != null); + if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs index 84a73c7cfc..585fdb9cb4 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.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.Diagnostics; using osu.Framework.MathUtils; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; @@ -13,8 +14,10 @@ namespace osu.Game.Rulesets.Osu.Tests { var drawableHitObject = base.CreateDrawableHitCircle(circle, auto); - Scheduler.AddDelayed(() => drawableHitObject.TriggerJudgement(), - drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.HalfWindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current); + Debug.Assert(drawableHitObject.HitObject.HitWindows != null); + + double delay = drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.HalfWindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current; + Scheduler.AddDelayed(() => drawableHitObject.TriggerJudgement(), delay); return drawableHitObject; } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 5625028707..649b01c132 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Types; @@ -38,7 +39,12 @@ namespace osu.Game.Rulesets.Osu.Mods if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit) continue; - requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime); + if (osuHit is DrawableHitCircle && osuHit.IsHovered) + { + Debug.Assert(osuHit.HitObject.HitWindows != null); + requiresHit |= osuHit.HitObject.HitWindows.CanBeHit(relativetime); + } + requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner; } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 0af278f6a4..1c40e37262 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -87,6 +88,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { + Debug.Assert(HitObject.HitWindows != null); + if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) @@ -119,6 +122,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdateStateTransforms(ArmedState state) { + Debug.Assert(HitObject.HitWindows != null); + switch (state) { case ArmedState.Idle: diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 690263c6a0..e1614984de 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -92,20 +92,20 @@ namespace osu.Game.Rulesets.Osu.Replays double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime; // Make the cursor stay at a hitObject as long as possible (mainly for autopilot). - if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Miss) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50) + if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Miss) > endTime + HitWindows.HalfWindowFor(HitResult.Meh) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); - if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); + if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); } - else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50) + else if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Meh) > endTime + HitWindows.HalfWindowFor(HitResult.Meh) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); - if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); + if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); } - else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Good) > endTime + h.HitWindows.HalfWindowFor(HitResult.Good) + 50) + else if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Good) > endTime + HitWindows.HalfWindowFor(HitResult.Good) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); - if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); + if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); } } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 9ab358ee12..7c94027c28 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -6,6 +6,8 @@ using osu.Game.Beatmaps; using System; using System.Collections.Generic; using osu.Game.Replays; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Replays; @@ -27,6 +29,11 @@ namespace osu.Game.Rulesets.Osu.Replays /// protected readonly double FrameDelay; + /// + /// The hit windows. + /// + protected readonly HitWindows HitWindows; + #endregion #region Construction / Initialisation @@ -41,6 +48,9 @@ namespace osu.Game.Rulesets.Osu.Replays // We are using ApplyModsToRate and not ApplyModsToTime to counteract the speed up / slow down from HalfTime / DoubleTime so that we remain at a constant framerate of 60 fps. FrameDelay = ApplyModsToRate(1000.0 / 60.0); + + HitWindows = new OsuHitWindows(); + HitWindows.SetDifficulty(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); } #endregion diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index fa45067210..0942b37f58 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using System.Linq; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; @@ -34,6 +35,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override void CheckForResult(bool userTriggered, double timeOffset) { + Debug.Assert(HitObject.HitWindows != null); + if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) @@ -94,6 +97,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override void UpdateStateTransforms(ArmedState state) { + Debug.Assert(HitObject.HitWindows != null); + switch (state) { case ArmedState.Idle: From 90671e061715b3c7458e3d2d1f8d32e2bb033ec5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Sep 2019 18:58:13 +0900 Subject: [PATCH 602/645] Attempt to not break per-hitobject hitwindows --- .../Replays/OsuAutoGenerator.cs | 53 +++++++++++++++---- .../Replays/OsuAutoGeneratorBase.cs | 8 --- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index e1614984de..e5fa571d4d 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -6,9 +6,11 @@ using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using System; +using System.Diagnostics; using System.Linq; using osu.Framework.Graphics; using osu.Game.Replays; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Scoring; @@ -36,6 +38,8 @@ namespace osu.Game.Rulesets.Osu.Replays /// private readonly double reactionTime; + private readonly HitWindows defaultHitWindows; + /// /// What easing to use when moving between hitobjects /// @@ -50,6 +54,9 @@ namespace osu.Game.Rulesets.Osu.Replays { // Already superhuman, but still somewhat realistic reactionTime = ApplyModsToRate(100); + + defaultHitWindows = new OsuHitWindows(); + defaultHitWindows.SetDifficulty(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); } #endregion @@ -91,21 +98,49 @@ namespace osu.Game.Rulesets.Osu.Replays { double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime; + HitWindows hitWindows = null; + + switch (h) + { + case HitCircle hitCircle: + hitWindows = hitCircle.HitWindows; + break; + + case Slider slider: + hitWindows = slider.TailCircle.HitWindows; + break; + + case Spinner _: + hitWindows = defaultHitWindows; + break; + } + + Debug.Assert(hitWindows != null); + // Make the cursor stay at a hitObject as long as possible (mainly for autopilot). - if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Miss) > endTime + HitWindows.HalfWindowFor(HitResult.Meh) + 50) + if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Miss) > endTime + hitWindows.HalfWindowFor(HitResult.Meh) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); - if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) + AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); + + if (!(h is Spinner)) + AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); } - else if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Meh) > endTime + HitWindows.HalfWindowFor(HitResult.Meh) + 50) + else if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Meh) > endTime + hitWindows.HalfWindowFor(HitResult.Meh) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); - if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) + AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); + + if (!(h is Spinner)) + AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); } - else if (h.StartTime - HitWindows.HalfWindowFor(HitResult.Good) > endTime + HitWindows.HalfWindowFor(HitResult.Good) + 50) + else if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Good) > endTime + hitWindows.HalfWindowFor(HitResult.Good) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + HitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); - if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - HitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) + AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y))); + + if (!(h is Spinner)) + AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y))); } } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 7c94027c28..3c889d1f52 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -29,11 +29,6 @@ namespace osu.Game.Rulesets.Osu.Replays /// protected readonly double FrameDelay; - /// - /// The hit windows. - /// - protected readonly HitWindows HitWindows; - #endregion #region Construction / Initialisation @@ -48,9 +43,6 @@ namespace osu.Game.Rulesets.Osu.Replays // We are using ApplyModsToRate and not ApplyModsToTime to counteract the speed up / slow down from HalfTime / DoubleTime so that we remain at a constant framerate of 60 fps. FrameDelay = ApplyModsToRate(1000.0 / 60.0); - - HitWindows = new OsuHitWindows(); - HitWindows.SetDifficulty(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); } #endregion From 0bfe4650c3da9796c112de5abbca281817ddbccf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 19:01:17 +0900 Subject: [PATCH 603/645] Early return if no change occurred in looping value --- osu.Game/Skinning/SkinnableSound.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 07ffbb8a51..8012500280 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -45,6 +45,8 @@ namespace osu.Game.Skinning get => looping; set { + if (value == looping) return; + looping = value; channels?.ForEach(c => c.Looping = looping); From b460f76fa6ad54a9098babe7bef500caa938923e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 19:01:43 +0900 Subject: [PATCH 604/645] Adjust file spacing slightly --- osu.Game/Skinning/SkinnableSound.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8012500280..3d0219ed93 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -54,6 +54,7 @@ namespace osu.Game.Skinning } public void Play() => channels?.ForEach(c => c.Play()); + public void Stop() => channels?.ForEach(c => c.Stop()); public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) From 0ee0184e01c5fd055d20744b998426e8f4d44ecb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Sep 2019 19:13:06 +0900 Subject: [PATCH 605/645] Remove unnecessary usings --- osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 3c889d1f52..9ab358ee12 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -6,8 +6,6 @@ using osu.Game.Beatmaps; using System; using System.Collections.Generic; using osu.Game.Replays; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Replays; From 53c254c6a5ca0b59f1471a670beaf81d083f0450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 2 Sep 2019 19:01:36 +0200 Subject: [PATCH 606/645] Replace Array.IndexOf() with Contains() --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 050e5a2835..e64b9259f1 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -1,7 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -36,9 +36,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnMouseUp(MouseUpEvent e) { - var index = Array.IndexOf(buttons, e.Button); - bool shouldPlayEffect = index > -1 && index < buttons.Length; - + bool shouldPlayEffect = buttons.Contains(e.Button); // examine the button pressed first for short-circuiting // in most usages it is more likely that another button was pressed than that the cursor left the drawable bounds if (shouldPlayEffect && Contains(e.ScreenSpaceMousePosition)) From 6ca17bdfd5106815ae2bbdd544302bf821679fed Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 2 Sep 2019 10:42:21 -0700 Subject: [PATCH 607/645] Center icon and text using anchor and origin instead of margin --- osu.Game/Overlays/Chat/Selection/ChannelListItem.cs | 3 ++- osu.Game/Overlays/Direct/DirectPanel.cs | 3 ++- osu.Game/Overlays/Music/PlaylistItem.cs | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs index cb0639d85d..31c48deee0 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs @@ -121,10 +121,11 @@ namespace osu.Game.Overlays.Chat.Selection { new SpriteIcon { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, Icon = FontAwesome.Solid.User, Size = new Vector2(text_size - 2), Shadow = false, - Margin = new MarginPadding { Top = 1 }, }, new OsuSpriteText { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index a9b6633864..6074aa16a5 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -190,10 +190,11 @@ namespace osu.Game.Overlays.Direct text = new OsuSpriteText { Font = OsuFont.GetFont(weight: FontWeight.SemiBold, italics: true) }, new SpriteIcon { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, Icon = icon, Shadow = true, Size = new Vector2(14), - Margin = new MarginPadding { Top = 1 }, }, }; diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index df37a1b2c7..29b6ae00f3 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -161,12 +161,12 @@ namespace osu.Game.Overlays.Music { public PlaylistItemHandle() { - Anchor = Anchor.TopLeft; - Origin = Anchor.TopLeft; + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; Size = new Vector2(12); Icon = FontAwesome.Solid.Bars; Alpha = 0f; - Margin = new MarginPadding { Left = 5, Top = 2 }; + Margin = new MarginPadding { Left = 5 }; } public override bool HandlePositionalInput => IsPresent; From 5d3f3b7cc2376d925e4269de7f982ba7a58d8897 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 2 Sep 2019 10:59:43 -0700 Subject: [PATCH 608/645] Add spacing to diff icons on direct panels --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 1 + osu.Game/Overlays/Direct/DirectListPanel.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 7bf94c1483..2528ccec41 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -151,6 +151,7 @@ namespace osu.Game.Overlays.Direct AutoSizeAxes = Axes.X, Height = 20, Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, + Spacing = new Vector2(3), Children = GetDifficultyIcons(colours), }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 158ff648dd..b64142dfe7 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -129,6 +129,7 @@ namespace osu.Game.Overlays.Direct AutoSizeAxes = Axes.X, Height = 20, Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding }, + Spacing = new Vector2(3), Children = GetDifficultyIcons(colours), }, }, From ce446826e8f9c87e63b8c9483c2fc057114ab345 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 2 Sep 2019 11:00:12 -0700 Subject: [PATCH 609/645] Match web's max diff icon number --- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index a9b6633864..c911a521b9 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Direct public readonly BeatmapSetInfo SetInfo; private const double hover_transition_time = 400; - private const int maximum_difficulty_icons = 15; + private const int maximum_difficulty_icons = 10; private Container content; From 3d1f051437650be239c1af83f253ea942248fbd1 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 2 Sep 2019 11:13:34 -0700 Subject: [PATCH 610/645] Move hover tests after key tests --- .../Gameplay/TestSceneGameplayMenuOverlay.cs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs index 4727140d99..0d8a84fa51 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs @@ -56,17 +56,14 @@ namespace osu.Game.Tests.Visual.Gameplay pauseOverlay.Retries = failOverlay.Retries = retryCount; }); - AddToggleStep("Toggle pause overlay", t => pauseOverlay.ToggleVisibility()); - AddToggleStep("Toggle fail overlay", t => failOverlay.ToggleVisibility()); - - testHideResets(); - testEnterWithoutSelection(); testKeyUpFromInitial(); testKeyDownFromInitial(); testKeyUpWrapping(); testKeyDownWrapping(); + testHideResets(); + testMouseSelectionAfterKeySelection(); testKeySelectionAfterMouseSelection(); @@ -76,19 +73,6 @@ namespace osu.Game.Tests.Visual.Gameplay testEnterKeySelection(); } - /// - /// Test that hiding the overlay after hovering a button will reset the overlay to the initial state with no buttons selected. - /// - private void testHideResets() - { - AddStep("Show overlay", () => failOverlay.Show()); - - AddStep("Hover first button", () => InputManager.MoveMouseTo(failOverlay.Buttons.First())); - AddStep("Hide overlay", () => failOverlay.Hide()); - - AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected.Value)); - } - /// /// Tests that pressing enter after an overlay shows doesn't trigger an event because a selection hasn't occurred. /// @@ -162,6 +146,19 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Hide overlay", () => failOverlay.Hide()); } + /// + /// Test that hiding the overlay after hovering a button will reset the overlay to the initial state with no buttons selected. + /// + private void testHideResets() + { + AddStep("Show overlay", () => failOverlay.Show()); + + AddStep("Hover first button", () => InputManager.MoveMouseTo(failOverlay.Buttons.First())); + AddStep("Hide overlay", () => failOverlay.Hide()); + + AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected.Value)); + } + /// /// Tests that hovering a button that was previously selected with the keyboard correctly selects the new button and deselects the previous button. /// From 3b769128a82c8f9cb0e588208a7d5f7eee3938d6 Mon Sep 17 00:00:00 2001 From: jorolf Date: Tue, 3 Sep 2019 00:57:29 +0200 Subject: [PATCH 611/645] Add a 60bpm beat when no beatmap is playing --- .../TestSceneBeatSyncedContainer.cs | 10 ++- .../Containers/BeatSyncedContainer.cs | 64 +++++++++++++++---- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 94228e22f0..d84ffa0d93 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -2,6 +2,7 @@ // 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.Audio.Track; @@ -25,6 +26,11 @@ namespace osu.Game.Tests.Visual.UserInterface { private readonly NowPlayingOverlay np; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BeatSyncedContainer) + }; + [Cached] private MusicController musicController = new MusicController(); @@ -154,7 +160,9 @@ namespace osu.Game.Tests.Visual.UserInterface if (timingPoints[timingPoints.Count - 1] == current) return current; - return timingPoints[timingPoints.IndexOf(current) + 1]; + int index = timingPoints.IndexOf(current); // -1 means that this is a "default beat" + + return index == -1 ? current : timingPoints[index + 1]; } private int calculateBeatCount(TimingControlPoint current) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 621eeea2b7..f6d950c414 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -33,23 +33,46 @@ namespace osu.Game.Graphics.Containers /// public double TimeSinceLastBeat { get; private set; } + /// + /// Default length of a beat in milliseconds. Used whenever there is no beatmap or track playing. + /// + private const double default_beat_length = 60000.0 / 60.0; + + private TimingControlPoint defaultTiming; + private EffectControlPoint defaultEffect; + private TrackAmplitudes defaultAmplitudes; + protected override void Update() { - if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.BeatmapLoaded) return; + Track track = null; + IBeatmap beatmap = null; - var track = Beatmap.Value.Track; - var beatmap = Beatmap.Value.Beatmap; + double currentTrackTime; + TimingControlPoint timingPoint; + EffectControlPoint effectPoint; - if (track == null || beatmap == null) - return; + if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded) + { + track = Beatmap.Value.Track; + beatmap = Beatmap.Value.Beatmap; + } - double currentTrackTime = track.Length > 0 ? track.CurrentTime + EarlyActivationMilliseconds : Clock.CurrentTime; + if (track != null && beatmap != null && track.IsRunning) + { + currentTrackTime = track.Length > 0 ? track.CurrentTime + EarlyActivationMilliseconds : Clock.CurrentTime; - TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); - EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); + timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); + effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); - if (timingPoint.BeatLength == 0) - return; + if (timingPoint.BeatLength == 0) + return; + } + else + { + currentTrackTime = Clock.CurrentTime; + timingPoint = defaultTiming; + effectPoint = defaultEffect; + } int beatIndex = (int)((currentTrackTime - timingPoint.Time) / timingPoint.BeatLength); @@ -67,7 +90,7 @@ namespace osu.Game.Graphics.Containers return; using (BeginDelayedSequence(-TimeSinceLastBeat, true)) - OnNewBeat(beatIndex, timingPoint, effectPoint, track.CurrentAmplitudes); + OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? defaultAmplitudes); lastBeat = beatIndex; lastTimingPoint = timingPoint; @@ -77,6 +100,25 @@ namespace osu.Game.Graphics.Containers private void load(IBindable beatmap) { Beatmap.BindTo(beatmap); + defaultTiming = new TimingControlPoint + { + BeatLength = default_beat_length, + AutoGenerated = true, + Time = 0 + }; + defaultEffect = new EffectControlPoint + { + Time = 0, + AutoGenerated = true, + KiaiMode = false, + OmitFirstBarLine = false + }; + defaultAmplitudes = new TrackAmplitudes + { + FrequencyAmplitudes = new float[256], + LeftChannel = 0, + RightChannel = 0 + }; } protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) From eab06995d0378d8e984937acd34e3009c9dc0156 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Sep 2019 11:37:56 +0900 Subject: [PATCH 612/645] Add some whitespace --- osu.Game/Graphics/Containers/BeatSyncedContainer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index f6d950c414..370d044ba4 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -100,12 +100,14 @@ namespace osu.Game.Graphics.Containers private void load(IBindable beatmap) { Beatmap.BindTo(beatmap); + defaultTiming = new TimingControlPoint { BeatLength = default_beat_length, AutoGenerated = true, Time = 0 }; + defaultEffect = new EffectControlPoint { Time = 0, @@ -113,6 +115,7 @@ namespace osu.Game.Graphics.Containers KiaiMode = false, OmitFirstBarLine = false }; + defaultAmplitudes = new TrackAmplitudes { FrequencyAmplitudes = new float[256], From 444419b2e6f99fcab6775245a346dd6f6db0c092 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 12:04:49 +0900 Subject: [PATCH 613/645] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 93a9a073a4..743508baf8 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 330018d5cb..03207dfdf7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9f8d82ad1e..ec76ceaf95 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 11dfdc33d519673df52de4a6e09434d0c83d9634 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2019 03:05:45 +0000 Subject: [PATCH 614/645] Bump ppy.osu.Game.Resources from 2019.830.0 to 2019.903.0 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.830.0 to 2019.903.0. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.830.0...2019.903.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 93a9a073a4..743508baf8 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 330018d5cb..03207dfdf7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9f8d82ad1e..ec76ceaf95 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 4f3511e8e9637fded836e3f0080b5ba28958ecd8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 12:32:10 +0900 Subject: [PATCH 615/645] Fix ring glow lookup being incorrect --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs index 00188689dd..30937313fd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Texture = textures.Get("ring-glow"), + Texture = textures.Get("Gameplay/osu/ring-glow"), Blending = BlendingParameters.Additive, Alpha = 0.5f }; From 4cad55cee6a73bb010d0838afeecfa63d38b17a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 13:05:03 +0900 Subject: [PATCH 616/645] Move hit windows lookup to DrawableRuleset --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 23 +++++++++++++++++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 5 +---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 0ee9196fb8..a32407d180 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading; +using JetBrains.Annotations; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; @@ -390,6 +391,28 @@ namespace osu.Game.Rulesets.UI /// public ResumeOverlay ResumeOverlay { get; protected set; } + /// + /// Returns first available provided by a . + /// + [CanBeNull] + public HitWindows FirstAvailableHitWindows + { + get + { + foreach (var h in Objects) + { + if (h.HitWindows != null) + return h.HitWindows; + + foreach (var n in h.NestedHitObjects) + if (n.HitWindows != null) + return n.HitWindows; + } + + return null; + } + } + protected virtual ResumeOverlay CreateResumeOverlay() => null; /// diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index eac45f9214..eee7235a6e 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -259,9 +258,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay( - scoreProcessor, - drawableRuleset.Objects.Concat(drawableRuleset.Objects.SelectMany(h => h.NestedHitObjects)).FirstOrDefault(h => h.HitWindows != null)?.HitWindows); + protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.FirstAvailableHitWindows); protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From d1cdf49dd51a6d5b66f006abb2afc5417e04c3e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 14:21:54 +0900 Subject: [PATCH 617/645] Revert SkinnableSprite lookups to old behaviour --- osu.Game.Rulesets.Catch/CatchSkinComponent.cs | 2 +- osu.Game.Rulesets.Catch/CatchSkinComponents.cs | 1 - osu.Game.Rulesets.Catch/UI/CatcherSprite.cs | 2 +- .../Objects/Drawables/Pieces/ApproachCircle.cs | 2 +- osu.Game/Skinning/SkinnableSprite.cs | 16 ++++++++++++++-- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs index 0a3e43dcfc..8bf53e53e3 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch { } - protected override string RulesetPrefix => CatchRuleset.SHORT_NAME; + protected override string RulesetPrefix => "catch"; // todo: use CatchRuleset.SHORT_NAME; protected override string ComponentName => Component.ToString().ToLower(); } diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs index c03fe42af7..7e482d4045 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs @@ -5,6 +5,5 @@ namespace osu.Game.Rulesets.Catch { public enum CatchSkinComponents { - Catcher } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs b/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs index 1c2fe3517a..e3c6c93d01 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.UI [BackgroundDependencyLoader] private void load() { - InternalChild = new SkinnableSprite(new CatchSkinComponent(CatchSkinComponents.Catcher)) + InternalChild = new SkinnableSprite("Gameplay/catch/fruit-catcher-idle") { RelativeSizeAxes = Axes.Both, Anchor = Anchor.TopCentre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs index c17c276205..1b474f265c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private class SkinnableApproachCircle : SkinnableSprite { public SkinnableApproachCircle() - : base(new OsuSkinComponent(OsuSkinComponents.ApproachCircle)) + : base("Gameplay/osu/approachcircle") { } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 0081aef520..4b78493e97 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -19,11 +19,23 @@ namespace osu.Game.Skinning [Resolved] private TextureStore textures { get; set; } - public SkinnableSprite(ISkinComponent component, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) - : base(component, allowFallback, confineMode) + public SkinnableSprite(string textureName, Func allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) + : base(new SpriteComponent(textureName), allowFallback, confineMode) { } protected override Drawable CreateDefault(ISkinComponent component) => new Sprite { Texture = textures.Get(component.LookupName) }; + + private class SpriteComponent : ISkinComponent + { + private readonly string textureName; + + public SpriteComponent(string textureName) + { + this.textureName = textureName; + } + + public string LookupName => textureName; + } } } From 352fd3efdaa1fcddd2a19bc87287134b02ebed97 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2019 09:18:24 +0000 Subject: [PATCH 618/645] Bump ppy.osu.Game.Resources from 2019.903.0 to 2019.903.1 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.903.0 to 2019.903.1. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.903.0...2019.903.1) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 743508baf8..96706f2bdc 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 03207dfdf7..ca69bb2295 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index ec76ceaf95..86a2a40940 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 2f74ef513140bfcd0e8b69c16a4d0731f87b5790 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 18:21:57 +0900 Subject: [PATCH 619/645] Add test for changing of a source --- .../Gameplay/TestSceneSkinnableDrawable.cs | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index ee5552c6e0..80015099cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -5,6 +5,7 @@ using System; using System.Globalization; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -133,6 +134,48 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1); } + [Test] + public void TestSwitchOff() + { + SkinConsumer consumer = null; + SwitchableSkinProvidingContainer target = null; + + AddStep("setup layout", () => + { + Child = new SkinSourceContainer + { + RelativeSizeAxes = Axes.Both, + Child = target = new SwitchableSkinProvidingContainer(new SecondarySource()) + { + RelativeSizeAxes = Axes.Both, + } + }; + }); + + AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true))); + AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox); + AddStep("disable", () => target.Disable()); + AddAssert("consumer using base source", () => consumer.Drawable is BaseSourceBox); + } + + private class SwitchableSkinProvidingContainer : SkinProvidingContainer + { + private bool allow = true; + + protected override bool AllowDrawableLookup(ISkinComponent component) => allow; + + public void Disable() + { + allow = false; + TriggerSourceChanged(); + } + + public SwitchableSkinProvidingContainer(ISkin skin) + : base(skin) + { + } + } + private class ExposedSkinnableDrawable : SkinnableDrawable { public new Drawable Drawable => base.Drawable; @@ -270,7 +313,8 @@ namespace osu.Game.Tests.Visual.Gameplay public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); } - private class SkinSourceContainer : Container, ISkin + [Cached(typeof(ISkinSource))] + private class SkinSourceContainer : Container, ISkinSource { public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox(); @@ -279,6 +323,8 @@ namespace osu.Game.Tests.Visual.Gameplay public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException(); public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); + + public event Action SourceChanged; } private class TestSkinComponent : ISkinComponent From 299d528654f823689e14ffc6fb56c9f2db55ae5f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 19:20:23 +0900 Subject: [PATCH 620/645] Simplify implementation --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index e64b9259f1..38e6a82bab 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -36,11 +36,9 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnMouseUp(MouseUpEvent e) { - bool shouldPlayEffect = buttons.Contains(e.Button); - // examine the button pressed first for short-circuiting - // in most usages it is more likely that another button was pressed than that the cursor left the drawable bounds - if (shouldPlayEffect && Contains(e.ScreenSpaceMousePosition)) + if (buttons.Contains(e.Button) && Contains(e.ScreenSpaceMousePosition)) sampleClick?.Play(); + return base.OnMouseUp(e); } From e98059267d4348a92e4d16fe6b75d9ebe45e3912 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 19:21:24 +0900 Subject: [PATCH 621/645] Improve xmldoc --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 38e6a82bab..1fb73efa65 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -21,12 +21,12 @@ namespace osu.Game.Graphics.UserInterface private readonly MouseButton[] buttons; /// - /// Creates an instance that adds sounds on hover and on click for any of the buttons specified. + /// a container which plays sounds on hover and click for any specified s. /// /// Set of click samples to play. /// /// Array of button codes which should trigger the click sound. - /// If this optional parameter is omitted or set to null, the click sound will only be added on left click. + /// If this optional parameter is omitted or set to null, the click sound will only be played on left click. /// public HoverClickSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal, MouseButton[] buttons = null) : base(sampleSet) From 4b2cb8854e06735d859568ba1b22e4ceb3a71541 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 19:28:10 +0900 Subject: [PATCH 622/645] Fix storyboard samples not stopping on exit --- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index b04f1d4518..f3f8308964 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -64,5 +64,11 @@ namespace osu.Game.Storyboards.Drawables LifetimeEnd = sampleInfo.StartTime; } } + + protected override void Dispose(bool isDisposing) + { + channel?.Stop(); + base.Dispose(isDisposing); + } } } From f8c1afa539e47e6ea8ee5bef22f3c4df35a4a053 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Sep 2019 20:17:39 +0900 Subject: [PATCH 623/645] Fix two more cases of judgements appearing on hit error display when they shouldn't --- osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs | 3 +++ osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs index 63713541b4..5bd480c0ff 100644 --- a/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/RepeatPoint.cs @@ -5,6 +5,7 @@ using System; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects @@ -28,5 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects } public override Judgement CreateJudgement() => new OsuJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs index 4f2af64161..c53a88337e 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs @@ -23,5 +23,7 @@ namespace osu.Game.Rulesets.Osu.Objects } public override Judgement CreateJudgement() => new OsuSliderTailJudgement(); + + protected override HitWindows CreateHitWindows() => null; } } From a8f16503e2faa8dcfe98d1f28297e32149f2cd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 3 Sep 2019 23:18:39 +0200 Subject: [PATCH 624/645] Add backslash escaping to new link format For users to be able to add square brackets inside of links using the new format, the regular expression used for parsing those links contained a balancing group, which can be used for matching pairs of tokens (in this case, opening and closing brackets, in that order). However, this means that users could not post links with unmatched brackets inside of them (ie. ones that contain single brackets, or a closing bracket and then an opening one). Allow for escaping opening and closing brackets using the backslash character. The change substitutes this old fragment of the regex in the display text group: [^\[\]]* // any character other than closing/opening bracket for this one: (((?<=\\)[\[\]])|[^\[\]])* The second pattern in the alternative remains the same; the first one performs the escaping, as follows: ( (?<=\\) // positive lookbehind expression: // this match will succeed, if the next expression // is preceded by a single backslash [\[\]] // either an opening or closing brace ) Since the entire display group is matched, unfortunately the lookbehind expression does not actually strip the backslashes, so they are manually stripped in handleMatches. As demonstrated in the unit tests attached, this also allows balanced brackets to be mixed with escaped ones. --- osu.Game.Tests/Chat/MessageFormatterTests.cs | 36 +++++++++++++++++++ .../Visual/Online/TestSceneChatLink.cs | 1 + osu.Game/Online/Chat/MessageFormatter.cs | 11 ++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Chat/MessageFormatterTests.cs b/osu.Game.Tests/Chat/MessageFormatterTests.cs index 0d6ed67767..1de6280531 100644 --- a/osu.Game.Tests/Chat/MessageFormatterTests.cs +++ b/osu.Game.Tests/Chat/MessageFormatterTests.cs @@ -131,6 +131,42 @@ namespace osu.Game.Tests.Chat Assert.AreEqual(11, result.Links[0].Length); } + [Test] + public void TestNewFormatLinkWithEscapedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [https://osu.ppy.sh nasty link with escaped brackets: \\] and \\[]" }); + + Assert.AreEqual("This is a nasty link with escaped brackets: ] and [", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(41, result.Links[0].Length); + } + + [Test] + public void TestNewFormatLinkWithBackslashesInside() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [https://osu.ppy.sh link \\ with \\ backslashes \\]" }); + + Assert.AreEqual("This is a link \\ with \\ backslashes \\", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(27, result.Links[0].Length); + } + + [Test] + public void TestNewFormatLinkWithEscapedAndBalancedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [https://osu.ppy.sh [link [with \\] too many brackets \\[ ]]]" }); + + Assert.AreEqual("This is a [link [with ] too many brackets [ ]]", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(36, result.Links[0].Length); + } + [Test] public void TestMarkdownFormatLink() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index c18e0e3064..056ccafe79 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -127,6 +127,7 @@ namespace osu.Game.Tests.Visual.Online addMessageWithChecks("is now playing [https://osu.ppy.sh/b/252238 IMAGE -MATERIAL- ]", 1, true, expectedActions: LinkAction.OpenBeatmap); addMessageWithChecks("Let's (try)[https://osu.ppy.sh/home] [https://osu.ppy.sh/b/252238 multiple links] https://osu.ppy.sh/home", 3, expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External }); + addMessageWithChecks("[https://osu.ppy.sh/home New link format with escaped [and \\[ paired] braces]", expectedActions: LinkAction.External); // note that there's 0 links here (they get removed if a channel is not found) addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present)."); addMessageWithChecks("I am important!", 0, false, true); diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index db26945ef3..a9fffc196c 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.RegularExpressions; namespace osu.Game.Online.Chat @@ -16,7 +17,7 @@ namespace osu.Game.Online.Chat private static readonly Regex old_link_regex = new Regex(@"\(([^\)]*)\)\[([a-z]+://[^ ]+)\]"); // [https://osu.ppy.sh/b/1234 Beatmap [Hard] (poop)] -> Beatmap [hard] (poop) (https://osu.ppy.sh/b/1234) - private static readonly Regex new_link_regex = new Regex(@"\[([a-z]+://[^ ]+) ([^\[\]]*(((?\[)[^\[\]]*)+((?\])[^\[\]]*)+)*(?(open)(?!)))\]"); + private static readonly Regex new_link_regex = new Regex(@"\[([a-z]+://[^ ]+) ((((?<=\\)[\[\]])|[^\[\]])*(((?\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]"); // [test](https://osu.ppy.sh/b/1234) -> test (https://osu.ppy.sh/b/1234) aka correct markdown format private static readonly Regex markdown_link_regex = new Regex(@"\[([^\]]*)\]\(([a-z]+://[^ ]+)\)"); @@ -48,7 +49,7 @@ namespace osu.Game.Online.Chat // Unicode emojis private static readonly Regex emoji_regex = new Regex(@"(\uD83D[\uDC00-\uDE4F])"); - private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null) + private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[] escapeChars = null) { int captureOffset = 0; @@ -68,6 +69,10 @@ namespace osu.Game.Online.Chat if (displayText.Length == 0 || linkText.Length == 0) continue; + // Remove backslash escapes in front of the characters provided in escapeChars + if (escapeChars != null) + displayText = escapeChars.Aggregate(displayText, (current, c) => current.Replace($"\\{c}", c.ToString())); + // Check for encapsulated links if (result.Links.Find(l => (l.Index <= index && l.Index + l.Length >= index + m.Length) || (index <= l.Index && index + m.Length >= l.Index + l.Length)) == null) { @@ -183,7 +188,7 @@ namespace osu.Game.Online.Chat var result = new MessageFormatterResult(toFormat); // handle the [link display] format - handleMatches(new_link_regex, "{2}", "{1}", result, startIndex); + handleMatches(new_link_regex, "{2}", "{1}", result, startIndex, escapeChars: new[] { '[', ']' }); // handle the standard markdown []() format handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex); From 24d4f0372c851280eb017553101712ad86731133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 3 Sep 2019 23:56:07 +0200 Subject: [PATCH 625/645] Refactor link parsing regexes to use named groups For the sake of readability, consistency and to make further changes easier, introduce named groups (?) and (?) to all link parsing regexes which have parts containing the desired link text and (optionally) URL. The introduction of the named groups additionally simplifies handleMatches() and makes all calls to it consistent. --- osu.Game/Online/Chat/MessageFormatter.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index a9fffc196c..23b5cdc0a6 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -11,16 +11,16 @@ namespace osu.Game.Online.Chat public static class MessageFormatter { // [[Performance Points]] -> wiki:Performance Points (https://osu.ppy.sh/wiki/Performance_Points) - private static readonly Regex wiki_regex = new Regex(@"\[\[([^\]]+)\]\]"); + private static readonly Regex wiki_regex = new Regex(@"\[\[(?[^\]]+)\]\]"); // (test)[https://osu.ppy.sh/b/1234] -> test (https://osu.ppy.sh/b/1234) - private static readonly Regex old_link_regex = new Regex(@"\(([^\)]*)\)\[([a-z]+://[^ ]+)\]"); + private static readonly Regex old_link_regex = new Regex(@"\((?[^\)]*)\)\[(?[a-z]+://[^ ]+)\]"); // [https://osu.ppy.sh/b/1234 Beatmap [Hard] (poop)] -> Beatmap [hard] (poop) (https://osu.ppy.sh/b/1234) - private static readonly Regex new_link_regex = new Regex(@"\[([a-z]+://[^ ]+) ((((?<=\\)[\[\]])|[^\[\]])*(((?\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]"); + private static readonly Regex new_link_regex = new Regex(@"\[(?[a-z]+://[^ ]+) (?(((?<=\\)[\[\]])|[^\[\]])*(((?\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]"); // [test](https://osu.ppy.sh/b/1234) -> test (https://osu.ppy.sh/b/1234) aka correct markdown format - private static readonly Regex markdown_link_regex = new Regex(@"\[([^\]]*)\]\(([a-z]+://[^ ]+)\)"); + private static readonly Regex markdown_link_regex = new Regex(@"\[(?[^\]]*)\]\((?[a-z]+://[^ ]+)\)"); // advanced, RFC-compatible regular expression that matches any possible URL, *but* allows certain invalid characters that are widely used // This is in the format (, [optional]): @@ -59,13 +59,13 @@ namespace osu.Game.Online.Chat var displayText = string.Format(display, m.Groups[0], - m.Groups.Count > 1 ? m.Groups[1].Value : "", - m.Groups.Count > 2 ? m.Groups[2].Value : "").Trim(); + m.Groups["text"].Value, + m.Groups["url"].Value).Trim(); var linkText = string.Format(link, m.Groups[0], - m.Groups.Count > 1 ? m.Groups[1].Value : "", - m.Groups.Count > 2 ? m.Groups[2].Value : "").Trim(); + m.Groups["text"].Value, + m.Groups["url"].Value).Trim(); if (displayText.Length == 0 || linkText.Length == 0) continue; @@ -188,7 +188,7 @@ namespace osu.Game.Online.Chat var result = new MessageFormatterResult(toFormat); // handle the [link display] format - handleMatches(new_link_regex, "{2}", "{1}", result, startIndex, escapeChars: new[] { '[', ']' }); + handleMatches(new_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' }); // handle the standard markdown []() format handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex); From f04add6d9edda7bbdf080adc7e6959ee16e6f222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 4 Sep 2019 00:01:26 +0200 Subject: [PATCH 626/645] Add bracket handling to Markdown link format Allow users to put both balanced brackets, as well as unbalanced escaped ones, in Markdown link text. The implementation is the exact same as in the case of new format links. For completion's sake, tests also included. --- osu.Game.Tests/Chat/MessageFormatterTests.cs | 47 +++++++++++++++++++ .../Visual/Online/TestSceneChatLink.cs | 1 + osu.Game/Online/Chat/MessageFormatter.cs | 4 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Chat/MessageFormatterTests.cs b/osu.Game.Tests/Chat/MessageFormatterTests.cs index 1de6280531..198267d78a 100644 --- a/osu.Game.Tests/Chat/MessageFormatterTests.cs +++ b/osu.Game.Tests/Chat/MessageFormatterTests.cs @@ -179,6 +179,53 @@ namespace osu.Game.Tests.Chat Assert.AreEqual(11, result.Links[0].Length); } + [Test] + public void TestMarkdownFormatLinkWithBalancedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [tricky [one]](https://osu.ppy.sh)!" }); + + Assert.AreEqual("This is a tricky [one]!", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(12, result.Links[0].Length); + } + + [Test] + public void TestMarkdownFormatLinkWithEscapedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is [another loose bracket \\]](https://osu.ppy.sh)." }); + + Assert.AreEqual("This is another loose bracket ].", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(8, result.Links[0].Index); + Assert.AreEqual(23, result.Links[0].Length); + } + + [Test] + public void TestMarkdownFormatWithBackslashes() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This link [should end with a backslash \\](https://osu.ppy.sh)." }); + Assert.AreEqual("This link should end with a backslash \\.", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(29, result.Links[0].Length); + } + + [Test] + public void TestMarkdownFormatLinkWithEscapedAndBalancedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [\\]super\\[\\[ tricky [one]](https://osu.ppy.sh)!" }); + + Assert.AreEqual("This is a ]super[[ tricky [one]!", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(21, result.Links[0].Length); + } + [Test] public void TestChannelLink() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 056ccafe79..61c7d3f5b6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -128,6 +128,7 @@ namespace osu.Game.Tests.Visual.Online addMessageWithChecks("Let's (try)[https://osu.ppy.sh/home] [https://osu.ppy.sh/b/252238 multiple links] https://osu.ppy.sh/home", 3, expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External }); addMessageWithChecks("[https://osu.ppy.sh/home New link format with escaped [and \\[ paired] braces]", expectedActions: LinkAction.External); + addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://osu.ppy.sh/home)", expectedActions: LinkAction.External); // note that there's 0 links here (they get removed if a channel is not found) addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present)."); addMessageWithChecks("I am important!", 0, false, true); diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 23b5cdc0a6..e40bb05381 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -20,7 +20,7 @@ namespace osu.Game.Online.Chat private static readonly Regex new_link_regex = new Regex(@"\[(?[a-z]+://[^ ]+) (?(((?<=\\)[\[\]])|[^\[\]])*(((?\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]"); // [test](https://osu.ppy.sh/b/1234) -> test (https://osu.ppy.sh/b/1234) aka correct markdown format - private static readonly Regex markdown_link_regex = new Regex(@"\[(?[^\]]*)\]\((?[a-z]+://[^ ]+)\)"); + private static readonly Regex markdown_link_regex = new Regex(@"\[(?(((?<=\\)[\[\]])|[^\[\]])*(((?\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]\((?[a-z]+://[^ ]+)\)"); // advanced, RFC-compatible regular expression that matches any possible URL, *but* allows certain invalid characters that are widely used // This is in the format (, [optional]): @@ -191,7 +191,7 @@ namespace osu.Game.Online.Chat handleMatches(new_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' }); // handle the standard markdown []() format - handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex); + handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' }); // handle the ()[] link format handleMatches(old_link_regex, "{1}", "{2}", result, startIndex); From 08350a1acaf4c3bb70176e384c845fc83735d497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 4 Sep 2019 00:17:52 +0200 Subject: [PATCH 627/645] Add parenthesis handling to old link format Allow users to put both balanced round parentheses, as well as unbalanced escaped ones, in old style link text. The implementation is the same as for Markdown and new style links, except for swapping all instances of \[\] to \(\) for obvious reasons (different type of parenthesis requiring escaping). Tests also included. --- osu.Game.Tests/Chat/MessageFormatterTests.cs | 47 +++++++++++++++++++ .../Visual/Online/TestSceneChatLink.cs | 5 +- osu.Game/Online/Chat/MessageFormatter.cs | 4 +- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Chat/MessageFormatterTests.cs b/osu.Game.Tests/Chat/MessageFormatterTests.cs index 198267d78a..9b4a90e9a9 100644 --- a/osu.Game.Tests/Chat/MessageFormatterTests.cs +++ b/osu.Game.Tests/Chat/MessageFormatterTests.cs @@ -119,6 +119,53 @@ namespace osu.Game.Tests.Chat Assert.AreEqual(11, result.Links[0].Length); } + [Test] + public void TestOldFormatLinkWithBalancedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a (tricky (one))[https://osu.ppy.sh]!" }); + + Assert.AreEqual("This is a tricky (one)!", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(12, result.Links[0].Length); + } + + [Test] + public void TestOldFormatLinkWithEscapedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is (another loose bracket \\))[https://osu.ppy.sh]." }); + + Assert.AreEqual("This is another loose bracket ).", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(8, result.Links[0].Index); + Assert.AreEqual(23, result.Links[0].Length); + } + + [Test] + public void TestOldFormatWithBackslashes() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This link (should end with a backslash \\)[https://osu.ppy.sh]." }); + Assert.AreEqual("This link should end with a backslash \\.", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(29, result.Links[0].Length); + } + + [Test] + public void TestOldFormatLinkWithEscapedAndBalancedBrackets() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a (\\)super\\(\\( tricky (one))[https://osu.ppy.sh]!" }); + + Assert.AreEqual("This is a )super(( tricky (one)!", result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url); + Assert.AreEqual(10, result.Links[0].Index); + Assert.AreEqual(21, result.Links[0].Length); + } + [Test] public void TestNewFormatLink() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 61c7d3f5b6..a1c77e2db0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -127,8 +127,9 @@ namespace osu.Game.Tests.Visual.Online addMessageWithChecks("is now playing [https://osu.ppy.sh/b/252238 IMAGE -MATERIAL- ]", 1, true, expectedActions: LinkAction.OpenBeatmap); addMessageWithChecks("Let's (try)[https://osu.ppy.sh/home] [https://osu.ppy.sh/b/252238 multiple links] https://osu.ppy.sh/home", 3, expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External }); - addMessageWithChecks("[https://osu.ppy.sh/home New link format with escaped [and \\[ paired] braces]", expectedActions: LinkAction.External); - addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://osu.ppy.sh/home)", expectedActions: LinkAction.External); + addMessageWithChecks("[https://osu.ppy.sh/home New link format with escaped [and \\[ paired] braces]", 1, expectedActions: LinkAction.External); + addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://osu.ppy.sh/home)", 1, expectedActions: LinkAction.External); + addMessageWithChecks("(Old link format with escaped (and \\( paired) parentheses)[https://osu.ppy.sh/home] and [[also a rogue wiki link]]", 2, expectedActions: new[] { LinkAction.External, LinkAction.External }); // note that there's 0 links here (they get removed if a channel is not found) addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present)."); addMessageWithChecks("I am important!", 0, false, true); diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index e40bb05381..24d17612ee 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -14,7 +14,7 @@ namespace osu.Game.Online.Chat private static readonly Regex wiki_regex = new Regex(@"\[\[(?[^\]]+)\]\]"); // (test)[https://osu.ppy.sh/b/1234] -> test (https://osu.ppy.sh/b/1234) - private static readonly Regex old_link_regex = new Regex(@"\((?[^\)]*)\)\[(?[a-z]+://[^ ]+)\]"); + private static readonly Regex old_link_regex = new Regex(@"\((?(((?<=\\)[\(\)])|[^\(\)])*(((?\()(((?<=\\)[\(\)])|[^\(\)])*)+((?\))(((?<=\\)[\(\)])|[^\(\)])*)+)*(?(open)(?!)))\)\[(?[a-z]+://[^ ]+)\]"); // [https://osu.ppy.sh/b/1234 Beatmap [Hard] (poop)] -> Beatmap [hard] (poop) (https://osu.ppy.sh/b/1234) private static readonly Regex new_link_regex = new Regex(@"\[(?[a-z]+://[^ ]+) (?(((?<=\\)[\[\]])|[^\[\]])*(((?\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]"); @@ -194,7 +194,7 @@ namespace osu.Game.Online.Chat handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' }); // handle the ()[] link format - handleMatches(old_link_regex, "{1}", "{2}", result, startIndex); + handleMatches(old_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '(', ')' }); // handle wiki links handleMatches(wiki_regex, "{1}", "https://osu.ppy.sh/wiki/{1}", result, startIndex); From 9ec16bc2b260fd35a7d0b2722432cb5636c6f4f2 Mon Sep 17 00:00:00 2001 From: Joehu Date: Tue, 3 Sep 2019 16:56:45 -0700 Subject: [PATCH 628/645] Add test for initial button hover --- .../Gameplay/TestSceneGameplayMenuOverlay.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs index 0d8a84fa51..ef7345bda7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs @@ -63,6 +63,7 @@ namespace osu.Game.Tests.Visual.Gameplay testKeyDownWrapping(); testHideResets(); + testInitialButtonHover(); testMouseSelectionAfterKeySelection(); testKeySelectionAfterMouseSelection(); @@ -159,6 +160,25 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected.Value)); } + /// + /// Tests that entering menu with cursor initially on button selects it. + /// + private void testInitialButtonHover() + { + AddStep("Show overlay", () => pauseOverlay.Show()); + + var firstButton = pauseOverlay.Buttons.First(); + + AddStep("Hover first button", () => InputManager.MoveMouseTo(firstButton)); + + AddStep("Hide overlay", () => pauseOverlay.Hide()); + AddStep("Show overlay", () => pauseOverlay.Show()); + + AddAssert("First button selected", () => firstButton.Selected.Value); + + AddStep("Hide overlay", () => pauseOverlay.Hide()); + } + /// /// Tests that hovering a button that was previously selected with the keyboard correctly selects the new button and deselects the previous button. /// From 5c10a228771ba0f3bb5459ff80b5d6f74a8e586f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 10:34:56 +0900 Subject: [PATCH 629/645] Update tests to use [Test] attributes --- .../Gameplay/TestSceneGameplayMenuOverlay.cs | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs index ef7345bda7..8b2fbe8aae 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs @@ -3,8 +3,8 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,7 +16,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - [Description("player pause/fail screens")] + [System.ComponentModel.Description("player pause/fail screens")] public class TestSceneGameplayMenuOverlay : ManualInputManagerTestScene { public override IReadOnlyList RequiredTypes => new[] { typeof(FailOverlay), typeof(PauseOverlay) }; @@ -55,29 +55,13 @@ namespace osu.Game.Tests.Visual.Gameplay retryCount++; pauseOverlay.Retries = failOverlay.Retries = retryCount; }); - - testEnterWithoutSelection(); - testKeyUpFromInitial(); - testKeyDownFromInitial(); - testKeyUpWrapping(); - testKeyDownWrapping(); - - testHideResets(); - testInitialButtonHover(); - - testMouseSelectionAfterKeySelection(); - testKeySelectionAfterMouseSelection(); - - testMouseDeselectionResets(); - - testClickSelection(); - testEnterKeySelection(); } /// /// Tests that pressing enter after an overlay shows doesn't trigger an event because a selection hasn't occurred. /// - private void testEnterWithoutSelection() + [Test] + public void TestEnterWithoutSelection() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -90,7 +74,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that pressing the up arrow from the initial state selects the last button. /// - private void testKeyUpFromInitial() + [Test] + public void TestKeyUpFromInitial() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -103,7 +88,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that pressing the down arrow from the initial state selects the first button. /// - private void testKeyDownFromInitial() + [Test] + public void TestKeyDownFromInitial() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -116,7 +102,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that pressing the up arrow repeatedly causes the selected button to wrap correctly. /// - private void testKeyUpWrapping() + [Test] + public void TestKeyUpWrapping() { AddStep("Show overlay", () => failOverlay.Show()); @@ -133,7 +120,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that pressing the down arrow repeatedly causes the selected button to wrap correctly. /// - private void testKeyDownWrapping() + [Test] + public void TestKeyDownWrapping() { AddStep("Show overlay", () => failOverlay.Show()); @@ -150,7 +138,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Test that hiding the overlay after hovering a button will reset the overlay to the initial state with no buttons selected. /// - private void testHideResets() + [Test] + public void TestHideResets() { AddStep("Show overlay", () => failOverlay.Show()); @@ -163,7 +152,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that entering menu with cursor initially on button selects it. /// - private void testInitialButtonHover() + [Test] + public void TestInitialButtonHover() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -182,7 +172,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that hovering a button that was previously selected with the keyboard correctly selects the new button and deselects the previous button. /// - private void testMouseSelectionAfterKeySelection() + [Test] + public void TestMouseSelectionAfterKeySelection() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -199,7 +190,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that pressing a key after selecting a button with a hover event correctly selects a new button and deselects the previous button. /// - private void testKeySelectionAfterMouseSelection() + [Test] + public void TestKeySelectionAfterMouseSelection() { AddStep("Show overlay", () => { @@ -220,7 +212,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that deselecting with the mouse by losing hover will reset the overlay to the initial state. /// - private void testMouseDeselectionResets() + [Test] + public void TestMouseDeselectionResets() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -237,7 +230,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that clicking on a button correctly causes a click event for that button. /// - private void testClickSelection() + [Test] + public void TestClickSelection() { AddStep("Show overlay", () => pauseOverlay.Show()); @@ -260,7 +254,8 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Tests that pressing the enter key with a button selected correctly causes a click event for that button. /// - private void testEnterKeySelection() + [Test] + public void TestEnterKeySelection() { AddStep("Show overlay", () => pauseOverlay.Show()); From 40c61894effd9afcc1dc2db5393f4b37058c1076 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 10:44:24 +0900 Subject: [PATCH 630/645] Update some case sensitive resources lookups in-line with resources --- osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index c89cd95f36..e96c7d8f92 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Tests { switch (component.LookupName) { - case "Gameplay/Catch/fruit-catcher-idle": + case "Gameplay/catch/fruit-catcher-idle": return new CatcherCustomSkin(); } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 9766da9a24..5234ae1f69 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -132,10 +132,10 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(TextureStore textures, OsuColour colours) { - rim.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer"); - rimHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer-hit"); - centre.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner"); - centreHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner-hit"); + rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer"); + rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit"); + centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner"); + centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit"); rimHit.Colour = colours.Blue; centreHit.Colour = colours.Pink; From 7cbcc7b9069178bc07c38bdf8802fbf3eaf7333b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 11:36:09 +0900 Subject: [PATCH 631/645] Further test refactors --- .../Gameplay/TestSceneGameplayMenuOverlay.cs | 121 ++++++++---------- 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs index 8b2fbe8aae..cc275009ba 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Logging; +using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Screens.Play; using osuTK; @@ -29,32 +30,43 @@ namespace osu.Game.Tests.Visual.Gameplay [BackgroundDependencyLoader] private void load(OsuGameBase game) { - Child = globalActionContainer = new GlobalActionContainer(game) - { - Children = new Drawable[] - { - pauseOverlay = new PauseOverlay - { - OnResume = () => Logger.Log(@"Resume"), - OnRetry = () => Logger.Log(@"Retry"), - OnQuit = () => Logger.Log(@"Quit"), - }, - failOverlay = new FailOverlay + Child = globalActionContainer = new GlobalActionContainer(game); + } - { - OnRetry = () => Logger.Log(@"Retry"), - OnQuit = () => Logger.Log(@"Quit"), - } + [SetUp] + public void SetUp() => Schedule(() => + { + globalActionContainer.Children = new Drawable[] + { + pauseOverlay = new PauseOverlay + { + OnResume = () => Logger.Log(@"Resume"), + OnRetry = () => Logger.Log(@"Retry"), + OnQuit = () => Logger.Log(@"Quit"), + }, + failOverlay = new FailOverlay + + { + OnRetry = () => Logger.Log(@"Retry"), + OnQuit = () => Logger.Log(@"Quit"), } }; + InputManager.MoveMouseTo(Vector2.Zero); + }); + + [Test] + public void TestAdjustRetryCount() + { + showOverlay(); + var retryCount = 0; - AddStep("Add retry", () => + AddRepeatStep("Add retry", () => { retryCount++; pauseOverlay.Retries = failOverlay.Retries = retryCount; - }); + }, 10); } /// @@ -63,12 +75,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestEnterWithoutSelection() { - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); AddStep("Press select", () => press(GlobalAction.Select)); AddAssert("Overlay still open", () => pauseOverlay.State.Value == Visibility.Visible); - - AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// @@ -77,12 +87,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestKeyUpFromInitial() { - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); AddStep("Up arrow", () => press(Key.Up)); AddAssert("Last button selected", () => pauseOverlay.Buttons.Last().Selected.Value); - - AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// @@ -91,12 +99,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestKeyDownFromInitial() { - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); AddStep("Down arrow", () => press(Key.Down)); - AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected.Value); - - AddStep("Hide overlay", () => pauseOverlay.Hide()); + AddAssert("First button selected", () => getButton(0).Selected.Value); } /// @@ -113,8 +119,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value); AddStep("Up arrow", () => press(Key.Up)); AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value); - - AddStep("Hide overlay", () => failOverlay.Hide()); } /// @@ -131,8 +135,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value); AddStep("Down arrow", () => press(Key.Down)); AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value); - - AddStep("Hide overlay", () => failOverlay.Hide()); } /// @@ -155,18 +157,14 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestInitialButtonHover() { - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); - var firstButton = pauseOverlay.Buttons.First(); - - AddStep("Hover first button", () => InputManager.MoveMouseTo(firstButton)); + AddStep("Hover first button", () => InputManager.MoveMouseTo(getButton(0))); AddStep("Hide overlay", () => pauseOverlay.Hide()); - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); - AddAssert("First button selected", () => firstButton.Selected.Value); - - AddStep("Hide overlay", () => pauseOverlay.Hide()); + AddAssert("First button selected", () => getButton(0).Selected.Value); } /// @@ -175,16 +173,12 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestMouseSelectionAfterKeySelection() { - AddStep("Show overlay", () => pauseOverlay.Show()); - - var secondButton = pauseOverlay.Buttons.Skip(1).First(); + showOverlay(); AddStep("Down arrow", () => press(Key.Down)); - AddStep("Hover second button", () => InputManager.MoveMouseTo(secondButton)); - AddAssert("First button not selected", () => !pauseOverlay.Buttons.First().Selected.Value); - AddAssert("Second button selected", () => secondButton.Selected.Value); - - AddStep("Hide overlay", () => pauseOverlay.Hide()); + AddStep("Hover second button", () => InputManager.MoveMouseTo(getButton(1))); + AddAssert("First button not selected", () => !getButton(0).Selected.Value); + AddAssert("Second button selected", () => getButton(1).Selected.Value); } /// @@ -196,17 +190,12 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Show overlay", () => { pauseOverlay.Show(); - InputManager.MoveMouseTo(Vector2.Zero); }); - var secondButton = pauseOverlay.Buttons.Skip(1).First(); - - AddStep("Hover second button", () => InputManager.MoveMouseTo(secondButton)); + AddStep("Hover second button", () => InputManager.MoveMouseTo(getButton(1))); AddStep("Up arrow", () => press(Key.Up)); - AddAssert("Second button not selected", () => !secondButton.Selected.Value); - AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected.Value); - - AddStep("Hide overlay", () => pauseOverlay.Hide()); + AddAssert("Second button not selected", () => !getButton(1).Selected.Value); + AddAssert("First button selected", () => getButton(0).Selected.Value); } /// @@ -215,16 +204,12 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestMouseDeselectionResets() { - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); - var secondButton = pauseOverlay.Buttons.Skip(1).First(); - - AddStep("Hover second button", () => InputManager.MoveMouseTo(secondButton)); + AddStep("Hover second button", () => InputManager.MoveMouseTo(getButton(1))); AddStep("Unhover second button", () => InputManager.MoveMouseTo(Vector2.Zero)); AddStep("Down arrow", () => press(Key.Down)); - AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected.Value); // Initial state condition - - AddStep("Hide overlay", () => pauseOverlay.Hide()); + AddAssert("First button selected", () => getButton(0).Selected.Value); // Initial state condition } /// @@ -233,9 +218,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestClickSelection() { - AddStep("Show overlay", () => pauseOverlay.Show()); - - var retryButton = pauseOverlay.Buttons.Skip(1).First(); + showOverlay(); bool triggered = false; AddStep("Click retry button", () => @@ -243,7 +226,7 @@ namespace osu.Game.Tests.Visual.Gameplay var lastAction = pauseOverlay.OnRetry; pauseOverlay.OnRetry = () => triggered = true; - retryButton.Click(); + getButton(1).Click(); pauseOverlay.OnRetry = lastAction; }); @@ -257,7 +240,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestEnterKeySelection() { - AddStep("Show overlay", () => pauseOverlay.Show()); + showOverlay(); AddStep("Select second button", () => { @@ -287,6 +270,10 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden); } + private void showOverlay() => AddStep("Show overlay", () => pauseOverlay.Show()); + + private DialogButton getButton(int index) => pauseOverlay.Buttons.Skip(index).First(); + private void press(Key key) { InputManager.PressKey(key); From 4c563232d627b17a6f1c31350b156673c7befb7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 11:37:02 +0900 Subject: [PATCH 632/645] HoverClickSounds should handle click event instead of MouseUp --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 1fb73efa65..4f678b7218 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -34,12 +34,12 @@ namespace osu.Game.Graphics.UserInterface this.buttons = buttons ?? new[] { MouseButton.Left }; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override bool OnClick(ClickEvent e) { if (buttons.Contains(e.Button) && Contains(e.ScreenSpaceMousePosition)) sampleClick?.Play(); - return base.OnMouseUp(e); + return base.OnClick(e); } [BackgroundDependencyLoader] From 5efd455ce4821e48919eb462531325db12d54f65 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Sep 2019 12:47:10 +0900 Subject: [PATCH 633/645] Fix taiko sample namespace --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 5424ccb4de..423f65b2d3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // Normal and clap samples are handled by the drum protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP); - protected override string SampleNamespace => "Taiko"; + protected override string SampleNamespace => "taiko"; protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); From 024aa4dd7b3ea19e04cd59cf8e66a26f74a62cc2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Sep 2019 13:05:05 +0900 Subject: [PATCH 634/645] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 96706f2bdc..90d1854c39 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ca69bb2295..7d106f0484 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 86a2a40940..8390a2229b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 9edfe6800f7a7157b3a0b8902a2a9ad57b599814 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2019 04:20:46 +0000 Subject: [PATCH 635/645] Bump ppy.osu.Game.Resources from 2019.903.1 to 2019.904.0 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.903.1 to 2019.904.0. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.903.1...2019.904.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 96706f2bdc..90d1854c39 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -60,7 +60,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ca69bb2295..7d106f0484 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 86a2a40940..8390a2229b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -117,7 +117,7 @@ - + From 69b9d70a35c2c1f42214d16f083b6e73f43ddc4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 15:56:18 +0900 Subject: [PATCH 636/645] Add minimal configuration to support nuget package creation --- osu.Game/osu.Game.csproj | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7d106f0484..3147ca749f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -6,6 +6,17 @@ AnyCPU true + + osu! + ppy.osu.Game + ppy Pty Ltd + https://github.com/ppy/osu/blob/master/LICENCE.md + https://github.com/ppy/osu + https://github.com/ppy/osu + Automated release. + Copyright (c) 2019 ppy Pty Ltd + osu game + @@ -15,7 +26,7 @@ - + From b80a8296cd591db9dd34b8746fdbb85570694be2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 20:27:27 +0900 Subject: [PATCH 637/645] Fix unavailable rulesets crashing at song select --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 +- osu.Game/Rulesets/RulesetInfo.cs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 81f517dd86..8014631eca 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Drawables Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) - Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } + Icon = ruleset?.CreateInstance()?.CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } } }; } diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index d9cff86265..c982ef7be1 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics.CodeAnalysis; +using JetBrains.Annotations; using Newtonsoft.Json; namespace osu.Game.Rulesets @@ -20,7 +21,13 @@ namespace osu.Game.Rulesets [JsonIgnore] public bool Available { get; set; } - public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this); + [CanBeNull] + public virtual Ruleset CreateInstance() + { + if (!Available) return null; + + return (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this); + } public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo; From c59a2bf9bb6bce70906c6fd3b3e99417ff314249 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 20:28:04 +0900 Subject: [PATCH 638/645] Fix tests crashing if a ruleset doesn't provide a NoFail mod --- osu.Game/Tests/Visual/PlayerTestScene.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index ccd996098c..2c5a51ca02 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -50,7 +50,11 @@ namespace osu.Game.Tests.Visual Beatmap.Value = CreateWorkingBeatmap(beatmap); if (!AllowFail) - Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; + { + var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail); + if (noFailMod != null) + Mods.Value = new[] { noFailMod }; + } if (Autoplay) { From 6197c7fd31d3edcbae5a07c1b06d7157b3eb25b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 20:28:21 +0900 Subject: [PATCH 639/645] Add automatic resource mapping for rulesets to their own dll --- osu.Game/Rulesets/Ruleset.cs | 3 +++ osu.Game/Rulesets/UI/DrawableRuleset.cs | 20 ++++++++++++++++++++ osu.Game/Skinning/SkinnableSound.cs | 14 ++++++++------ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index b63292757d..197c089f71 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; +using osu.Framework.IO.Stores; using osu.Game.Beatmaps; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Edit; @@ -83,6 +84,8 @@ namespace osu.Game.Rulesets public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.Solid.QuestionCircle }; + public virtual IResourceStore CreateReourceStore() => new NamespacedResourceStore(new DllResourceStore(GetType().Assembly.Location), @"Resources"); + public abstract string Description { get; } public virtual RulesetSettingsSubsection CreateSettings() => null; diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index a32407d180..562b2c4667 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -14,10 +14,14 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using JetBrains.Annotations; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Events; +using osu.Framework.IO.Stores; using osu.Game.Configuration; using osu.Game.Graphics.Cursor; using osu.Game.Input.Handlers; @@ -51,6 +55,10 @@ namespace osu.Game.Rulesets.UI private readonly Lazy playfield; + private TextureStore textureStore; + + private ISampleStore sampleStore; + /// /// The playfield. /// @@ -142,6 +150,18 @@ namespace osu.Game.Rulesets.UI { var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + var resources = Ruleset.CreateReourceStore(); + + if (resources != null) + { + textureStore = new TextureStore(new TextureLoaderStore(new NamespacedResourceStore(resources, "Textures"))); + textureStore.AddStore(dependencies.Get()); + dependencies.Cache(textureStore); + + sampleStore = dependencies.Get().GetSampleStore(new NamespacedResourceStore(resources, "Samples")); + dependencies.CacheAs(sampleStore); + } + onScreenDisplay = dependencies.Get(); Config = dependencies.Get().GetConfigFor(Ruleset); diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 3d0219ed93..bdf8be773b 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Audio; @@ -20,7 +21,7 @@ namespace osu.Game.Skinning private SampleChannel[] channels; - private AudioManager audio; + private ISampleStore samples; public SkinnableSound(IEnumerable hitSamples) { @@ -33,9 +34,9 @@ namespace osu.Game.Skinning } [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(ISampleStore samples) { - this.audio = audio; + this.samples = samples; } private bool looping; @@ -81,7 +82,7 @@ namespace osu.Game.Skinning if (ch == null && allowFallback) foreach (var lookup in s.LookupNames) - if ((ch = audio.Samples.Get($"Gameplay/{lookup}")) != null) + if ((ch = samples.Get($"Gameplay/{lookup}")) != null) break; if (ch != null) @@ -102,8 +103,9 @@ namespace osu.Game.Skinning { base.Dispose(isDisposing); - foreach (var c in channels) - c.Dispose(); + if (channels != null) + foreach (var c in channels) + c.Dispose(); } } } From 8e8f33ec7b5fb0a24f279692c76ba3d214997bc2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 21:35:59 +0900 Subject: [PATCH 640/645] Remove null hinting for now --- osu.Game/Rulesets/RulesetInfo.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index c982ef7be1..6a69fd8dd0 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics.CodeAnalysis; -using JetBrains.Annotations; using Newtonsoft.Json; namespace osu.Game.Rulesets @@ -21,7 +20,6 @@ namespace osu.Game.Rulesets [JsonIgnore] public bool Available { get; set; } - [CanBeNull] public virtual Ruleset CreateInstance() { if (!Available) return null; From f9fa5988e69a679a7a344baa0a1855703d7f7caf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Sep 2019 23:16:56 +0900 Subject: [PATCH 641/645] Add basic nuget deploy support --- appveyor.yml | 2 -- appveyor_deploy.yml | 10 ++++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 appveyor_deploy.yml diff --git a/appveyor.yml b/appveyor.yml index 4dcaa7b45e..be1727e7d7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,5 @@ clone_depth: 1 version: '{branch}-{build}' image: Previous Visual Studio 2017 test: off -install: - - cmd: git submodule update --init --recursive --depth=5 build_script: - cmd: PowerShell -Version 2.0 .\build.ps1 diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml new file mode 100644 index 0000000000..d36298175b --- /dev/null +++ b/appveyor_deploy.yml @@ -0,0 +1,10 @@ +clone_depth: 1 +version: '{build}' +image: Previous Visual Studio 2017 +test: off +skip_non_tags: true +build_script: + - cmd: PowerShell -Version 2.0 .\build.ps1 +deploy: + - provider: Environment + name: nuget From 50de4d1a3a4569da2532c52b3b74371f28f46ae7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Sep 2019 01:11:53 +0900 Subject: [PATCH 642/645] Remove PrivateAssets changes for now --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3147ca749f..f2a605e7a7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -26,7 +26,7 @@ - + From afac512a1bfd09d115fc60b9dcfc5d8c0b7e776e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Sep 2019 02:12:17 +0900 Subject: [PATCH 643/645] Fix databased config save performance Adds proper save debounce logic. Closes #5991. --- .../Configuration/DatabasedConfigManager.cs | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index d5cdd7e4bc..6aa89cdd69 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -16,11 +16,11 @@ namespace osu.Game.Configuration private readonly int? variant; - private readonly List databasedSettings; + private List databasedSettings; private readonly RulesetInfo ruleset; - private readonly bool legacySettingsExist; + private bool legacySettingsExist; protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int? variant = null) { @@ -28,21 +28,34 @@ namespace osu.Game.Configuration this.ruleset = ruleset; this.variant = variant; - databasedSettings = settings.Query(ruleset?.ID, variant); - legacySettingsExist = databasedSettings.Any(s => int.TryParse(s.Key, out var _)); + Load(); InitialiseDefaults(); } protected override void PerformLoad() { + databasedSettings = settings.Query(ruleset?.ID, variant); + legacySettingsExist = databasedSettings.Any(s => int.TryParse(s.Key, out var _)); } protected override bool PerformSave() { + lock (dirtySettings) + { + if (dirtySettings.Count > 0) + { + foreach (var setting in dirtySettings) + settings.Update(setting); + dirtySettings.Clear(); + } + } + return true; } + private readonly List dirtySettings = new List(); + protected override void AddBindable(T lookup, Bindable bindable) { base.AddBindable(lookup, bindable); @@ -80,7 +93,9 @@ namespace osu.Game.Configuration bindable.ValueChanged += b => { setting.Value = b.NewValue; - settings.Update(setting); + lock (dirtySettings) + if (!dirtySettings.Contains(setting)) + dirtySettings.Add(setting); }; } } From d40129aabe9a8947add0a28b6a51fa85b7017365 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Sep 2019 13:36:37 +0900 Subject: [PATCH 644/645] Remove unnecessary count check --- osu.Game/Configuration/DatabasedConfigManager.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index 6aa89cdd69..0046f4fa7f 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -43,12 +43,9 @@ namespace osu.Game.Configuration { lock (dirtySettings) { - if (dirtySettings.Count > 0) - { - foreach (var setting in dirtySettings) - settings.Update(setting); - dirtySettings.Clear(); - } + foreach (var setting in dirtySettings) + settings.Update(setting); + dirtySettings.Clear(); } return true; From 070a005294668614deaf2779450eed7b1e90051e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Sep 2019 13:37:11 +0900 Subject: [PATCH 645/645] Add braces to lock() Personal preference, I want to be sure that everything is wrapped correctly. --- osu.Game/Configuration/DatabasedConfigManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index 0046f4fa7f..02382cfd2b 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -90,9 +90,12 @@ namespace osu.Game.Configuration bindable.ValueChanged += b => { setting.Value = b.NewValue; + lock (dirtySettings) + { if (!dirtySettings.Contains(setting)) dirtySettings.Add(setting); + } }; } } /// Creates the conversion value for a . A conversion value stores information about the converted . @@ -176,6 +184,32 @@ namespace osu.Game.Tests.Beatmaps [JsonProperty] public List Mappings = new List(); } + + private class ConversionWorkingBeatmap : WorkingBeatmap + { + public Action, IBeatmapConverter> ConversionGenerated; + + private readonly IBeatmap beatmap; + + public ConversionWorkingBeatmap(IBeatmap beatmap) + : base(beatmap.BeatmapInfo, null) + { + this.beatmap = beatmap; + } + + protected override IBeatmap GetBeatmap() => beatmap; + + protected override Texture GetBackground() => throw new NotImplementedException(); + + protected override Track GetTrack() => throw new NotImplementedException(); + + protected override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) + { + var converter = base.CreateBeatmapConverter(beatmap, ruleset); + converter.ObjectConverted += (orig, converted) => ConversionGenerated?.Invoke(orig, converted, converter); + return converter; + } + } } public abstract class BeatmapConversionTest : BeatmapConversionTest, TConvertValue> From ed4dda19363a1a112b4d55b6719c4d456073a459 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 31 Jul 2019 19:49:25 +0900 Subject: [PATCH 071/645] Support beatmap conversion tests with mods --- .../CatchBeatmapConversionTest.cs | 2 +- .../ManiaBeatmapConversionTest.cs | 2 +- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 2 +- .../TaikoBeatmapConversionTest.cs | 2 +- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index e45ed8c6f4..3a695ca179 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("spinner")] [TestCase("spinner-and-circles")] [TestCase("slider")] - public new void Test(string name) + public void Test(string name) { base.Test(name); } diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 51c7ba029a..3ca9dcc42c 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; [TestCase("basic")] - public new void Test(string name) + public void Test(string name) { base.Test(name); } diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index f98d63e6c7..6a6d0abe24 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests [TestCase("basic")] [TestCase("colinear-perfect-curve")] [TestCase("slider-ticks")] - public new void Test(string name) + public void Test(string name) { base.Test(name); } diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 68ae7544c2..bafa814582 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Tests [NonParallelizable] [TestCase("basic")] [TestCase("slider-generating-drumroll")] - public new void Test(string name) + public void Test(string name) { base.Test(name); } diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 1f2d457624..a555a52e42 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -28,9 +28,9 @@ namespace osu.Game.Tests.Beatmaps protected abstract string ResourceAssembly { get; } - protected void Test(string name) + protected void Test(string name, params Type[] mods) { - var ourResult = convert(name); + var ourResult = convert(name, mods.Select(m => (Mod)Activator.CreateInstance(m)).ToArray()); var expectedResult = read(name); Assert.Multiple(() => @@ -92,7 +92,7 @@ namespace osu.Game.Tests.Beatmaps }); } - private ConvertResult convert(string name) + private ConvertResult convert(string name, Mod[] mods) { var beatmap = getBeatmap(name); @@ -110,7 +110,7 @@ namespace osu.Game.Tests.Beatmaps } }; - working.GetPlayableBeatmap(rulesetInstance.RulesetInfo, Array.Empty()); + working.GetPlayableBeatmap(rulesetInstance.RulesetInfo, mods); return new ConvertResult { From fdc6a3958d3655e799420469c1fe17f4cecd11a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 31 Jul 2019 18:44:01 +0900 Subject: [PATCH 072/645] Make catch HR properly utilise the RNG --- .../Beatmaps/CatchBeatmapProcessor.cs | 119 +++++++++++++++++- .../MathUtils/FastRandom.cs | 8 ++ .../Mods/CatchModHardRock.cs | 112 +---------------- 3 files changed, 127 insertions(+), 112 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 645cb5701a..343f48f15c 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -10,6 +10,8 @@ using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects.Types; using osuTK; using osu.Game.Rulesets.Catch.MathUtils; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Catch.Beatmaps { @@ -26,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { base.PostProcess(); - applyPositionOffsets(); + ApplyPositionOffsets(Beatmap); initialiseHyperDash((List)Beatmap.HitObjects); @@ -40,15 +42,23 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } - private void applyPositionOffsets() + public static void ApplyPositionOffsets(IBeatmap beatmap, params Mod[] mods) { var rng = new FastRandom(RNG_SEED); - // todo: HardRock displacement should be applied here - foreach (var obj in Beatmap.HitObjects) + bool shouldApplyHardRockOffset = mods.Any(m => m is ModHardRock); + float? lastPosition = null; + double lastStartTime = 0; + + foreach (var obj in beatmap.HitObjects) { switch (obj) { + case Fruit fruit: + if (shouldApplyHardRockOffset) + applyHardRockOffset(fruit, ref lastPosition, ref lastStartTime, rng); + break; + case BananaShower bananaShower: foreach (var banana in bananaShower.NestedHitObjects.OfType()) { @@ -76,6 +86,107 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } + private static void applyHardRockOffset(HitObject 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; + + var catchObject = (CatchHitObject)hitObject; + + float position = catchObject.X; + double startTime = hitObject.StartTime; + + if (lastPosition == null) + { + lastPosition = position; + lastStartTime = startTime; + + return; + } + + float positionDiff = position - lastPosition.Value; + double timeDiff = startTime - lastStartTime; + + if (timeDiff > 1000) + { + lastPosition = position; + lastStartTime = startTime; + return; + } + + if (positionDiff == 0) + { + applyRandomOffset(ref position, timeDiff / 4d, rng); + catchObject.X = position; + return; + } + + if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d) + applyOffset(ref position, positionDiff); + + catchObject.X = position; + + lastPosition = position; + lastStartTime = startTime; + } + + /// + /// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield. + /// + /// The position which the offset should be applied to. + /// The maximum offset, cannot exceed 20px. + /// The random number generator. + private static void applyRandomOffset(ref float position, double maxOffset, FastRandom rng) + { + bool right = rng.NextBool(); + float rand = Math.Min(20, (float)rng.Next(0, Math.Max(0, maxOffset))) / CatchPlayfield.BASE_WIDTH; + + if (right) + { + // Clamp to the right bound + if (position + rand <= 1) + position += rand; + else + position -= rand; + } + else + { + // Clamp to the left bound + if (position - rand >= 0) + position -= rand; + else + position += rand; + } + } + + /// + /// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield. + /// + /// The position which the offset should be applied to. + /// The amount to offset by. + private static void applyOffset(ref float position, float amount) + { + if (amount > 0) + { + // Clamp to the right bound + if (position + amount < 1) + position += amount; + } + else + { + // Clamp to the left bound + if (position + amount > 0) + position += amount; + } + } + private void initialiseHyperDash(List objects) { List objectWithDroplets = new List(); diff --git a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs index b3605b013b..c721ff862a 100644 --- a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs +++ b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs @@ -61,6 +61,14 @@ namespace osu.Game.Rulesets.Catch.MathUtils /// The random value. public int Next(int lowerBound, int upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound)); + /// + /// Generates a random integer value within the range [, ). + /// + /// The lower bound of the range. + /// The upper bound of the range. + /// The random value. + public int Next(double lowerBound, double upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound)); + /// /// Generates a random double value within the range [0, 1). /// diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs index 060e51e31d..ced1900ba9 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs @@ -1,121 +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.Framework.MathUtils; -using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; -using System; -using osu.Game.Rulesets.Objects; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Beatmaps; namespace osu.Game.Rulesets.Catch.Mods { - public class CatchModHardRock : ModHardRock, IApplicableToHitObject + public class CatchModHardRock : ModHardRock, IApplicableToBeatmap { public override double ScoreMultiplier => 1.12; public override bool Ranked => true; - private float? lastPosition; - private double lastStartTime; - - public void ApplyToHitObject(HitObject hitObject) - { - if (hitObject is JuiceStream stream) - { - lastPosition = stream.EndX; - lastStartTime = stream.EndTime; - return; - } - - if (!(hitObject is Fruit)) - return; - - var catchObject = (CatchHitObject)hitObject; - - float position = catchObject.X; - double startTime = hitObject.StartTime; - - if (lastPosition == null) - { - lastPosition = position; - lastStartTime = startTime; - - return; - } - - float positionDiff = position - lastPosition.Value; - double timeDiff = startTime - lastStartTime; - - if (timeDiff > 1000) - { - lastPosition = position; - lastStartTime = startTime; - return; - } - - if (positionDiff == 0) - { - applyRandomOffset(ref position, timeDiff / 4d); - catchObject.X = position; - return; - } - - if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d) - applyOffset(ref position, positionDiff); - - catchObject.X = position; - - lastPosition = position; - lastStartTime = startTime; - } - - /// - /// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield. - /// - /// The position which the offset should be applied to. - /// The maximum offset, cannot exceed 20px. - private void applyRandomOffset(ref float position, double maxOffset) - { - bool right = RNG.NextBool(); - float rand = Math.Min(20, (float)RNG.NextDouble(0, Math.Max(0, maxOffset))) / CatchPlayfield.BASE_WIDTH; - - if (right) - { - // Clamp to the right bound - if (position + rand <= 1) - position += rand; - else - position -= rand; - } - else - { - // Clamp to the left bound - if (position - rand >= 0) - position -= rand; - else - position += rand; - } - } - - /// - /// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield. - /// - /// The position which the offset should be applied to. - /// The amount to offset by. - private void applyOffset(ref float position, float amount) - { - if (amount > 0) - { - // Clamp to the right bound - if (position + amount < 1) - position += amount; - } - else - { - // Clamp to the left bound - if (position + amount > 0) - position += amount; - } - } + public void ApplyToBeatmap(IBeatmap beatmap) => CatchBeatmapProcessor.ApplyPositionOffsets(beatmap, this); } } From 38a2b9d92b5af230ee315f6e223f4a6da3f46373 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 13:33:00 +0900 Subject: [PATCH 073/645] Fix multiple invocations by using a separate variable --- .../Beatmaps/CatchBeatmapProcessor.cs | 32 +++++++++---------- .../Objects/CatchHitObject.cs | 14 +++++++- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 343f48f15c..ffff9b854d 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -11,7 +11,6 @@ using osu.Game.Rulesets.Objects.Types; using osuTK; using osu.Game.Rulesets.Catch.MathUtils; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Catch.Beatmaps { @@ -50,8 +49,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps float? lastPosition = null; double lastStartTime = 0; - foreach (var obj in beatmap.HitObjects) + foreach (var obj in beatmap.HitObjects.OfType()) { + obj.XOffset = 0; + switch (obj) { case Fruit fruit: @@ -62,7 +63,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps case BananaShower bananaShower: foreach (var banana in bananaShower.NestedHitObjects.OfType()) { - banana.X = (float)rng.NextDouble(); + banana.XOffset = (float)rng.NextDouble(); rng.Next(); // osu!stable retrieved a random banana type rng.Next(); // osu!stable retrieved a random banana rotation rng.Next(); // osu!stable retrieved a random banana colour @@ -75,10 +76,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { var hitObject = (CatchHitObject)nested; if (hitObject is TinyDroplet) - hitObject.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; + hitObject.XOffset = MathHelper.Clamp(rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, -hitObject.X, 1 - hitObject.X); else if (hitObject is Droplet) rng.Next(); // osu!stable retrieved a random droplet rotation - hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1); } break; @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } - private static void applyHardRockOffset(HitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng) + private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng) { if (hitObject is JuiceStream stream) { @@ -98,42 +98,40 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (!(hitObject is Fruit)) return; - var catchObject = (CatchHitObject)hitObject; - - float position = catchObject.X; + float offsetPosition = hitObject.X; double startTime = hitObject.StartTime; if (lastPosition == null) { - lastPosition = position; + lastPosition = offsetPosition; lastStartTime = startTime; return; } - float positionDiff = position - lastPosition.Value; + float positionDiff = offsetPosition - lastPosition.Value; double timeDiff = startTime - lastStartTime; if (timeDiff > 1000) { - lastPosition = position; + lastPosition = offsetPosition; lastStartTime = startTime; return; } if (positionDiff == 0) { - applyRandomOffset(ref position, timeDiff / 4d, rng); - catchObject.X = position; + applyRandomOffset(ref offsetPosition, timeDiff / 4d, rng); + hitObject.XOffset = hitObject.X - offsetPosition; return; } if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d) - applyOffset(ref position, positionDiff); + applyOffset(ref offsetPosition, positionDiff); - catchObject.X = position; + hitObject.XOffset = hitObject.X - offsetPosition; - lastPosition = position; + lastPosition = offsetPosition; lastStartTime = startTime; } diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index be76edc01b..19a1b59752 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -3,6 +3,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -12,7 +13,18 @@ namespace osu.Game.Rulesets.Catch.Objects { public const double OBJECT_RADIUS = 44; - public float X { get; set; } + private float x; + + public float X + { + get => x + XOffset; + set => x = value; + } + + /// + /// A random offset applied to , set by the . + /// + internal float XOffset { get; set; } public double TimePreempt = 1000; From e2420af10c844d9459fd906b3035086c949e3266 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 13:37:40 +0900 Subject: [PATCH 074/645] Fix applying mods to the wrong beatmap --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index baf921ddfc..c6105f6566 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -142,7 +142,7 @@ namespace osu.Game.Beatmaps processor?.PostProcess(); foreach (var mod in mods.OfType()) - mod.ApplyToBeatmap(Beatmap); + mod.ApplyToBeatmap(converted); return converted; } From 423857f403581907eef4c44cc97199e5d84546f3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 14:57:07 +0900 Subject: [PATCH 075/645] Fix inverted offset --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index ffff9b854d..3ee2928573 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -122,14 +122,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (positionDiff == 0) { applyRandomOffset(ref offsetPosition, timeDiff / 4d, rng); - hitObject.XOffset = hitObject.X - offsetPosition; + hitObject.XOffset = offsetPosition - hitObject.X; return; } if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d) applyOffset(ref offsetPosition, positionDiff); - hitObject.XOffset = hitObject.X - offsetPosition; + hitObject.XOffset = offsetPosition - hitObject.X; lastPosition = offsetPosition; lastStartTime = startTime; From 8a1d690011665ab19aceb2bd6ada65185517e7d2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 14:57:17 +0900 Subject: [PATCH 076/645] Reset tick offsets --- .../Beatmaps/CatchBeatmapProcessor.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 3ee2928573..5ab47c1611 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -74,10 +74,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps case JuiceStream juiceStream: foreach (var nested in juiceStream.NestedHitObjects) { - var hitObject = (CatchHitObject)nested; - if (hitObject is TinyDroplet) - hitObject.XOffset = MathHelper.Clamp(rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, -hitObject.X, 1 - hitObject.X); - else if (hitObject is Droplet) + var catchObject = (CatchHitObject)nested; + catchObject.XOffset = 0; + + if (catchObject is TinyDroplet) + catchObject.XOffset = MathHelper.Clamp(rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, -catchObject.X, 1 - catchObject.X); + else if (catchObject is Droplet) rng.Next(); // osu!stable retrieved a random droplet rotation } From b978727422b8a163aaa7402ba91951a6dc303e80 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 14:58:17 +0900 Subject: [PATCH 077/645] Add stream + repeat slider tests --- .../CatchBeatmapConversionTest.cs | 7 +- ...ock-repeat-slider-expected-conversion.json | 150 +++++++++++ .../Beatmaps/hardrock-repeat-slider.osu | 18 ++ .../hardrock-stream-expected-conversion.json | 234 ++++++++++++++++++ .../Testing/Beatmaps/hardrock-stream.osu | 107 ++++++++ 5 files changed, 514 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider-expected-conversion.json create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider.osu create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream-expected-conversion.json create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 3a695ca179..80ac64c5f9 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using Newtonsoft.Json; using NUnit.Framework; using osu.Framework.MathUtils; +using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; @@ -22,9 +23,11 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("spinner")] [TestCase("spinner-and-circles")] [TestCase("slider")] - public void Test(string name) + [TestCase("hardrock-stream", new[] { typeof(CatchModHardRock) })] + [TestCase("hardrock-repeat-slider", new[] { typeof(CatchModHardRock) })] + public new void Test(string name, params Type[] mods) { - base.Test(name); + base.Test(name, mods); } protected override IEnumerable CreateConvertValue(HitObject hitObject) diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider-expected-conversion.json new file mode 100644 index 0000000000..83f9e30800 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider-expected-conversion.json @@ -0,0 +1,150 @@ +{ + "Mappings": [{ + "StartTime": 369, + "Objects": [{ + "StartTime": 369, + "Position": 177 + }, + { + "StartTime": 450, + "Position": 216.539276 + }, + { + "StartTime": 532, + "Position": 256.5667 + }, + { + "StartTime": 614, + "Position": 296.594116 + }, + { + "StartTime": 696, + "Position": 336.621521 + }, + { + "StartTime": 778, + "Position": 376.99762 + }, + { + "StartTime": 860, + "Position": 337.318878 + }, + { + "StartTime": 942, + "Position": 297.291443 + }, + { + "StartTime": 1024, + "Position": 257.264038 + }, + { + "StartTime": 1106, + "Position": 217.2366 + }, + { + "StartTime": 1188, + "Position": 177 + }, + { + "StartTime": 1270, + "Position": 216.818192 + }, + { + "StartTime": 1352, + "Position": 256.8456 + }, + { + "StartTime": 1434, + "Position": 296.873047 + }, + { + "StartTime": 1516, + "Position": 336.900452 + }, + { + "StartTime": 1598, + "Position": 376.99762 + }, + { + "StartTime": 1680, + "Position": 337.039948 + }, + { + "StartTime": 1762, + "Position": 297.0125 + }, + { + "StartTime": 1844, + "Position": 256.9851 + }, + { + "StartTime": 1926, + "Position": 216.957672 + }, + { + "StartTime": 2008, + "Position": 177 + }, + { + "StartTime": 2090, + "Position": 217.097137 + }, + { + "StartTime": 2172, + "Position": 257.124573 + }, + { + "StartTime": 2254, + "Position": 297.152 + }, + { + "StartTime": 2336, + "Position": 337.179443 + }, + { + "StartTime": 2418, + "Position": 376.99762 + }, + { + "StartTime": 2500, + "Position": 336.760956 + }, + { + "StartTime": 2582, + "Position": 296.733643 + }, + { + "StartTime": 2664, + "Position": 256.7062 + }, + { + "StartTime": 2746, + "Position": 216.678772 + }, + { + "StartTime": 2828, + "Position": 177 + }, + { + "StartTime": 2909, + "Position": 216.887909 + }, + { + "StartTime": 2991, + "Position": 256.915344 + }, + { + "StartTime": 3073, + "Position": 296.942749 + }, + { + "StartTime": 3155, + "Position": 336.970184 + }, + { + "StartTime": 3237, + "Position": 376.99762 + } + ] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider.osu new file mode 100644 index 0000000000..c1971edf2c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-repeat-slider.osu @@ -0,0 +1,18 @@ +osu file format v14 + +[General] +StackLeniency: 0.4 +Mode: 0 + +[Difficulty] +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8 +SliderMultiplier:1.6 +SliderTickRate:4 + +[TimingPoints] +369,327.868852459016,4,2,2,32,1,0 + +[HitObjects] +177,191,369,6,0,L|382:192,7,200 diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream-expected-conversion.json new file mode 100644 index 0000000000..bbc16ab912 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream-expected-conversion.json @@ -0,0 +1,234 @@ +{ + "Mappings": [{ + "StartTime": 369, + "Objects": [{ + "StartTime": 369, + "Position": 258 + }] + }, + { + "StartTime": 450, + "Objects": [{ + "StartTime": 450, + "Position": 254 + }] + }, + { + "StartTime": 532, + "Objects": [{ + "StartTime": 532, + "Position": 241 + }] + }, + { + "StartTime": 614, + "Objects": [{ + "StartTime": 614, + "Position": 238 + }] + }, + { + "StartTime": 696, + "Objects": [{ + "StartTime": 696, + "Position": 238 + }] + }, + { + "StartTime": 778, + "Objects": [{ + "StartTime": 778, + "Position": 278 + }] + }, + { + "StartTime": 860, + "Objects": [{ + "StartTime": 860, + "Position": 238 + }] + }, + { + "StartTime": 942, + "Objects": [{ + "StartTime": 942, + "Position": 278 + }] + }, + { + "StartTime": 1024, + "Objects": [{ + "StartTime": 1024, + "Position": 238 + }] + }, + { + "StartTime": 1106, + "Objects": [{ + "StartTime": 1106, + "Position": 278 + }] + }, + { + "StartTime": 1188, + "Objects": [{ + "StartTime": 1188, + "Position": 278 + }] + }, + { + "StartTime": 1270, + "Objects": [{ + "StartTime": 1270, + "Position": 278 + }] + }, + { + "StartTime": 1352, + "Objects": [{ + "StartTime": 1352, + "Position": 238 + }] + }, + { + "StartTime": 1434, + "Objects": [{ + "StartTime": 1434, + "Position": 258 + }] + }, + { + "StartTime": 1516, + "Objects": [{ + "StartTime": 1516, + "Position": 253 + }] + }, + { + "StartTime": 1598, + "Objects": [{ + "StartTime": 1598, + "Position": 238 + }] + }, + { + "StartTime": 1680, + "Objects": [{ + "StartTime": 1680, + "Position": 260 + }] + }, + { + "StartTime": 1762, + "Objects": [{ + "StartTime": 1762, + "Position": 238 + }] + }, + { + "StartTime": 1844, + "Objects": [{ + "StartTime": 1844, + "Position": 278 + }] + }, + { + "StartTime": 1926, + "Objects": [{ + "StartTime": 1926, + "Position": 278 + }] + }, + { + "StartTime": 2008, + "Objects": [{ + "StartTime": 2008, + "Position": 238 + }] + }, + { + "StartTime": 2090, + "Objects": [{ + "StartTime": 2090, + "Position": 238 + }] + }, + { + "StartTime": 2172, + "Objects": [{ + "StartTime": 2172, + "Position": 243 + }] + }, + { + "StartTime": 2254, + "Objects": [{ + "StartTime": 2254, + "Position": 278 + }] + }, + { + "StartTime": 2336, + "Objects": [{ + "StartTime": 2336, + "Position": 278 + }] + }, + { + "StartTime": 2418, + "Objects": [{ + "StartTime": 2418, + "Position": 238 + }] + }, + { + "StartTime": 2500, + "Objects": [{ + "StartTime": 2500, + "Position": 258 + }] + }, + { + "StartTime": 2582, + "Objects": [{ + "StartTime": 2582, + "Position": 256 + }] + }, + { + "StartTime": 2664, + "Objects": [{ + "StartTime": 2664, + "Position": 242 + }] + }, + { + "StartTime": 2746, + "Objects": [{ + "StartTime": 2746, + "Position": 238 + }] + }, + { + "StartTime": 2828, + "Objects": [{ + "StartTime": 2828, + "Position": 238 + }] + }, + { + "StartTime": 2909, + "Objects": [{ + "StartTime": 2909, + "Position": 271 + }] + }, + { + "StartTime": 2991, + "Objects": [{ + "StartTime": 2991, + "Position": 254 + }] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu new file mode 100644 index 0000000000..62835135df --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu @@ -0,0 +1,107 @@ +osu file format v14 + +[General] +AudioFilename: audio.mp3 +AudioLeadIn: 0 +PreviewTime: 53483 +Countdown: 0 +SampleSet: Soft +StackLeniency: 0.4 +Mode: 0 +LetterboxInBreaks: 0 +WidescreenStoryboard: 0 + +[Editor] +Bookmarks: 369,1680,12172,22664,33155,43647,54139,64631,75123,85614,96106,103975,114467,124959,135287 +DistanceSpacing: 1 +BeatDivisor: 4 +GridSize: 8 +TimelineZoom: 2.899999 + +[Metadata] +Title:Silhouette +TitleUnicode:シルエット +Artist:KANA-BOON +ArtistUnicode:KANA-BOON +Creator:Nevo +Version:lit120's Hard +Source:NARUTO-ナルト-疾風伝 +Tags:shippuuden shipuuden shippuden nine tails opening 16 kage cut ver version naotoshi nao tomori shunao shogunmoon sotarks pika [[pika]] frostwich lit120 shiratoi armin a_r_m_i_n +BeatmapID:1653115 +BeatmapSetID:780952 + +[Difficulty] +HPDrainRate:6 +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8 +SliderMultiplier:1.6 +SliderTickRate:1 + +[Events] +//Background and Video events +0,0,"OSpGdEP.png",0,0 +//Break Periods +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples + +[TimingPoints] +369,327.868852459016,4,2,2,32,1,0 +1680,-100,4,2,2,42,0,0 +6926,-100,4,2,2,52,0,0 +11844,-100,4,2,2,5,0,0 +12172,-100,4,2,2,62,0,0 +22664,-100,4,2,2,52,0,0 +43647,-100,4,2,2,52,0,0 +53483,-100,4,2,2,32,0,0 +54139,-100,4,2,2,72,0,1 +96106,-100,4,2,2,52,0,0 +103975,-100,4,2,2,82,0,1 +124959,-100,4,2,2,62,0,0 +130205,-100,4,2,2,72,0,0 +132991,-100,4,2,2,82,0,0 + + +[Colours] +Combo1 : 154,53,255 +Combo2 : 253,211,47 +Combo3 : 86,168,250 +Combo4 : 192,192,192 + +[HitObjects] +258,189,369,1,0,0:0:0:0: +258,189,450,1,0,0:0:0:0: +258,189,532,1,0,0:0:0:0: +258,189,614,1,0,0:0:0:0: +258,189,696,1,0,0:0:0:0: +258,189,778,1,0,0:0:0:0: +258,189,860,1,0,0:0:0:0: +258,189,942,1,0,0:0:0:0: +258,189,1024,1,0,0:0:0:0: +258,189,1106,1,0,0:0:0:0: +258,189,1188,1,0,0:0:0:0: +258,189,1270,1,0,0:0:0:0: +258,189,1352,1,0,0:0:0:0: +258,189,1434,1,0,0:0:0:0: +258,189,1516,1,0,0:0:0:0: +258,189,1598,1,0,0:0:0:0: +258,189,1680,1,0,0:0:0:0: +258,189,1762,1,0,0:0:0:0: +258,189,1844,1,0,0:0:0:0: +258,189,1926,1,0,0:0:0:0: +258,189,2008,1,0,0:0:0:0: +258,189,2090,1,0,0:0:0:0: +258,189,2172,1,0,0:0:0:0: +258,189,2254,1,0,0:0:0:0: +258,189,2336,1,0,0:0:0:0: +258,189,2418,1,0,0:0:0:0: +258,189,2500,1,0,0:0:0:0: +258,189,2582,1,0,0:0:0:0: +258,189,2664,1,0,0:0:0:0: +258,189,2746,1,0,0:0:0:0: +258,189,2828,1,0,0:0:0:0: +258,189,2909,1,0,0:0:0:0: +258,189,2991,1,0,0:0:0:0: From d772bbaf8c77bae4a280a8facca67832b208d007 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 1 Aug 2019 10:04:04 +0300 Subject: [PATCH 078/645] Simplify disposing --- osu.Game/OsuGame.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 431e6c91f9..b9e2b79b05 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,11 +307,10 @@ namespace osu.Game if (nextBeatmap?.Track != null) nextBeatmap.Track.Completed += currentTrackCompleted; - var oldBeatmap = beatmap.OldValue; - if (oldBeatmap?.Track != null) - oldBeatmap.Track.Completed -= currentTrackCompleted; + using (var oldBeatmap = beatmap.OldValue) + if (oldBeatmap?.Track != null) + oldBeatmap.Track.Completed -= currentTrackCompleted; - oldBeatmap?.Dispose(); nextBeatmap?.LoadBeatmapAsync(); } From 0f36088ef894f0f94869d0c5df3d7bddfbb00151 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 11:06:29 +0300 Subject: [PATCH 079/645] Add loved section --- osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs | 1 + osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs index f3384163b8..fb1385793f 100644 --- a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs @@ -27,6 +27,7 @@ namespace osu.Game.Online.API.Requests { Favourite, RankedAndApproved, + Loved, Unranked, Graveyard } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index ae91837d29..37f017277f 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,6 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections { new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, "Favourite Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.RankedAndApproved, User, "Ranked & Approved Beatmaps"), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, "Loved Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.Unranked, User, "Pending Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, "Graveyarded Beatmaps"), }; From a2468e599b292d1c4d4da4cc5d49b87d38c01d98 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 17:31:26 +0900 Subject: [PATCH 080/645] Fix ticks in repeat spans being returned in reverse order --- .../Rulesets/Objects/SliderEventGenerator.cs | 60 ++++++++++++++----- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs index 7cda7485f9..9047d338aa 100644 --- a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs +++ b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs @@ -3,13 +3,15 @@ using System; using System.Collections.Generic; +using System.Linq; using osuTK; namespace osu.Game.Rulesets.Objects { public static class SliderEventGenerator { - public static IEnumerable Generate(double startTime, double spanDuration, double velocity, double tickDistance, double totalDistance, int spanCount, double? legacyLastTickOffset) + public static IEnumerable Generate(double startTime, double spanDuration, double velocity, double tickDistance, double totalDistance, int spanCount, + double? legacyLastTickOffset) { // A very lenient maximum length of a slider for ticks to be generated. // This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. @@ -36,24 +38,17 @@ namespace osu.Game.Rulesets.Objects var spanStartTime = startTime + span * spanDuration; var reversed = span % 2 == 1; - for (var d = tickDistance; d <= length; d += tickDistance) + var ticks = generateTicks(span, spanStartTime, spanDuration, reversed, length, tickDistance, minDistanceFromEnd); + + if (reversed) { - if (d >= length - minDistanceFromEnd) - break; - - var pathProgress = d / length; - var timeProgress = reversed ? 1 - pathProgress : pathProgress; - - yield return new SliderEventDescriptor - { - Type = SliderEventType.Tick, - SpanIndex = span, - SpanStartTime = spanStartTime, - Time = spanStartTime + timeProgress * spanDuration, - PathProgress = pathProgress, - }; + // For repeat spans, ticks are returned in reverse-StartTime order, which is undesirable for some rulesets + ticks = ticks.Reverse(); } + foreach (var e in ticks) + yield return e; + if (span < spanCount - 1) { yield return new SliderEventDescriptor @@ -103,6 +98,39 @@ namespace osu.Game.Rulesets.Objects PathProgress = spanCount % 2, }; } + + /// + /// Generates the ticks for a span of the slider. + /// + /// The span index. + /// The start time of the span. + /// The duration of the span. + /// Whether the span is reversed. + /// The length of the path. + /// The distance between each tick. + /// The distance from the end of the path at which ticks are not allowed to be added. + /// A for each tick. If is true, the ticks will be returned in reverse-StartTime order. + private static IEnumerable generateTicks(int spanIndex, double spanStartTime, double spanDuration, bool reversed, double length, double tickDistance, + double minDistanceFromEnd) + { + for (var d = tickDistance; d <= length; d += tickDistance) + { + if (d >= length - minDistanceFromEnd) + break; + + var pathProgress = d / length; + var timeProgress = reversed ? 1 - pathProgress : pathProgress; + + yield return new SliderEventDescriptor + { + Type = SliderEventType.Tick, + SpanIndex = spanIndex, + SpanStartTime = spanStartTime, + Time = spanStartTime + timeProgress * spanDuration, + PathProgress = pathProgress, + }; + } + } } /// From f2b940f930a89ebd14370eff3d231f402579197e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 17:31:08 +0900 Subject: [PATCH 081/645] Add tests --- .../OsuBeatmapConversionTest.cs | 2 + .../repeat-slider-expected-conversion.json | 222 +++++++++++ .../Testing/Beatmaps/repeat-slider.osu | 18 + ...ven-repeat-slider-expected-conversion.json | 348 ++++++++++++++++++ .../Testing/Beatmaps/uneven-repeat-slider.osu | 19 + .../Beatmaps/SliderEventGenerationTest.cs | 116 ++++++ 6 files changed, 725 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider-expected-conversion.json create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider.osu create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider-expected-conversion.json create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider.osu create mode 100644 osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index f98d63e6c7..451ecf97ea 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Osu.Tests [TestCase("basic")] [TestCase("colinear-perfect-curve")] [TestCase("slider-ticks")] + [TestCase("repeat-slider")] + [TestCase("uneven-repeat-slider")] public new void Test(string name) { base.Test(name); diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider-expected-conversion.json b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider-expected-conversion.json new file mode 100644 index 0000000000..fb4050963f --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider-expected-conversion.json @@ -0,0 +1,222 @@ +{ + "Mappings": [{ + "StartTime": 369, + "Objects": [{ + "StartTime": 369, + "EndTime": 369, + "X": 177, + "Y": 191 + }, + { + "StartTime": 450, + "EndTime": 450, + "X": 216.539276, + "Y": 191.192871 + }, + { + "StartTime": 532, + "EndTime": 532, + "X": 256.5667, + "Y": 191.388138 + }, + { + "StartTime": 614, + "EndTime": 614, + "X": 296.594116, + "Y": 191.583389 + }, + { + "StartTime": 696, + "EndTime": 696, + "X": 336.621521, + "Y": 191.778641 + }, + { + "StartTime": 778, + "EndTime": 778, + "X": 376.648926, + "Y": 191.9739 + }, + { + "StartTime": 860, + "EndTime": 860, + "X": 337.318878, + "Y": 191.782043 + }, + { + "StartTime": 942, + "EndTime": 942, + "X": 297.291443, + "Y": 191.586792 + }, + { + "StartTime": 1024, + "EndTime": 1024, + "X": 257.264038, + "Y": 191.391541 + }, + { + "StartTime": 1106, + "EndTime": 1106, + "X": 217.2366, + "Y": 191.196274 + }, + { + "StartTime": 1188, + "EndTime": 1188, + "X": 177.209213, + "Y": 191.001022 + }, + { + "StartTime": 1270, + "EndTime": 1270, + "X": 216.818192, + "Y": 191.194229 + }, + { + "StartTime": 1352, + "EndTime": 1352, + "X": 256.8456, + "Y": 191.3895 + }, + { + "StartTime": 1434, + "EndTime": 1434, + "X": 296.873047, + "Y": 191.584747 + }, + { + "StartTime": 1516, + "EndTime": 1516, + "X": 336.900452, + "Y": 191.78 + }, + { + "StartTime": 1598, + "EndTime": 1598, + "X": 376.927917, + "Y": 191.975266 + }, + { + "StartTime": 1680, + "EndTime": 1680, + "X": 337.039948, + "Y": 191.780685 + }, + { + "StartTime": 1762, + "EndTime": 1762, + "X": 297.0125, + "Y": 191.585434 + }, + { + "StartTime": 1844, + "EndTime": 1844, + "X": 256.9851, + "Y": 191.390167 + }, + { + "StartTime": 1926, + "EndTime": 1926, + "X": 216.957672, + "Y": 191.194916 + }, + { + "StartTime": 2008, + "EndTime": 2008, + "X": 177.069717, + "Y": 191.000336 + }, + { + "StartTime": 2090, + "EndTime": 2090, + "X": 217.097137, + "Y": 191.1956 + }, + { + "StartTime": 2172, + "EndTime": 2172, + "X": 257.124573, + "Y": 191.390854 + }, + { + "StartTime": 2254, + "EndTime": 2254, + "X": 297.152, + "Y": 191.5861 + }, + { + "StartTime": 2336, + "EndTime": 2336, + "X": 337.179443, + "Y": 191.781372 + }, + { + "StartTime": 2418, + "EndTime": 2418, + "X": 376.7884, + "Y": 191.974579 + }, + { + "StartTime": 2500, + "EndTime": 2500, + "X": 336.760956, + "Y": 191.779327 + }, + { + "StartTime": 2582, + "EndTime": 2582, + "X": 296.733643, + "Y": 191.584076 + }, + { + "StartTime": 2664, + "EndTime": 2664, + "X": 256.7062, + "Y": 191.388809 + }, + { + "StartTime": 2746, + "EndTime": 2746, + "X": 216.678772, + "Y": 191.193558 + }, + { + "StartTime": 2828, + "EndTime": 2828, + "X": 177.348663, + "Y": 191.0017 + }, + { + "StartTime": 2909, + "EndTime": 2909, + "X": 216.887909, + "Y": 191.19458 + }, + { + "StartTime": 2991, + "EndTime": 2991, + "X": 256.915344, + "Y": 191.389832 + }, + { + "StartTime": 3073, + "EndTime": 3073, + "X": 296.942749, + "Y": 191.585083 + }, + { + "StartTime": 3155, + "EndTime": 3155, + "X": 336.970184, + "Y": 191.78035 + }, + { + "StartTime": 3201, + "EndTime": 3201, + "X": 376.99762, + "Y": 191.9756 + } + ] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider.osu b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider.osu new file mode 100644 index 0000000000..624d905384 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/repeat-slider.osu @@ -0,0 +1,18 @@ +osu file format v14 + +[General] +StackLeniency: 0.4 +Mode: 0 + +[Difficulty] +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8 +SliderMultiplier:1.6 +SliderTickRate:4 + +[TimingPoints] +369,327.868852459016,4,2,2,32,1,0 + +[HitObjects] +177,191,369,6,0,L|382:192,7,200 \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider-expected-conversion.json b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider-expected-conversion.json new file mode 100644 index 0000000000..12d1645c04 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider-expected-conversion.json @@ -0,0 +1,348 @@ +{ + "Mappings": [{ + "StartTime": 369, + "Objects": [{ + "StartTime": 369, + "EndTime": 369, + "X": 127, + "Y": 194 + }, + { + "StartTime": 450, + "EndTime": 450, + "X": 166.53389, + "Y": 193.8691 + }, + { + "StartTime": 532, + "EndTime": 532, + "X": 206.555847, + "Y": 193.736572 + }, + { + "StartTime": 614, + "EndTime": 614, + "X": 246.57782, + "Y": 193.60405 + }, + { + "StartTime": 696, + "EndTime": 696, + "X": 286.5998, + "Y": 193.471527 + }, + { + "StartTime": 778, + "EndTime": 778, + "X": 326.621765, + "Y": 193.339 + }, + { + "StartTime": 860, + "EndTime": 860, + "X": 366.6437, + "Y": 193.206482 + }, + { + "StartTime": 942, + "EndTime": 942, + "X": 406.66568, + "Y": 193.073959 + }, + { + "StartTime": 970, + "EndTime": 970, + "X": 420.331726, + "Y": 193.0287 + }, + { + "StartTime": 997, + "EndTime": 997, + "X": 407.153748, + "Y": 193.072342 + }, + { + "StartTime": 1079, + "EndTime": 1079, + "X": 367.131775, + "Y": 193.204865 + }, + { + "StartTime": 1161, + "EndTime": 1161, + "X": 327.1098, + "Y": 193.337387 + }, + { + "StartTime": 1243, + "EndTime": 1243, + "X": 287.08783, + "Y": 193.46991 + }, + { + "StartTime": 1325, + "EndTime": 1325, + "X": 247.0659, + "Y": 193.602432 + }, + { + "StartTime": 1407, + "EndTime": 1407, + "X": 207.043915, + "Y": 193.734955 + }, + { + "StartTime": 1489, + "EndTime": 1489, + "X": 167.021988, + "Y": 193.867477 + }, + { + "StartTime": 1571, + "EndTime": 1571, + "X": 127, + "Y": 194 + }, + { + "StartTime": 1653, + "EndTime": 1653, + "X": 167.021988, + "Y": 193.867477 + }, + { + "StartTime": 1735, + "EndTime": 1735, + "X": 207.043976, + "Y": 193.734955 + }, + { + "StartTime": 1817, + "EndTime": 1817, + "X": 247.065887, + "Y": 193.602432 + }, + { + "StartTime": 1899, + "EndTime": 1899, + "X": 287.08783, + "Y": 193.46991 + }, + { + "StartTime": 1981, + "EndTime": 1981, + "X": 327.1098, + "Y": 193.337387 + }, + { + "StartTime": 2062, + "EndTime": 2062, + "X": 366.643738, + "Y": 193.206482 + }, + { + "StartTime": 2144, + "EndTime": 2144, + "X": 406.665649, + "Y": 193.073959 + }, + { + "StartTime": 2172, + "EndTime": 2172, + "X": 420.331726, + "Y": 193.0287 + }, + { + "StartTime": 2199, + "EndTime": 2199, + "X": 407.153748, + "Y": 193.072342 + }, + { + "StartTime": 2281, + "EndTime": 2281, + "X": 367.1318, + "Y": 193.204865 + }, + { + "StartTime": 2363, + "EndTime": 2363, + "X": 327.1098, + "Y": 193.337387 + }, + { + "StartTime": 2445, + "EndTime": 2445, + "X": 287.08783, + "Y": 193.46991 + }, + { + "StartTime": 2527, + "EndTime": 2527, + "X": 247.065887, + "Y": 193.602432 + }, + { + "StartTime": 2609, + "EndTime": 2609, + "X": 207.043976, + "Y": 193.734955 + }, + { + "StartTime": 2691, + "EndTime": 2691, + "X": 167.021988, + "Y": 193.867477 + }, + { + "StartTime": 2773, + "EndTime": 2773, + "X": 127, + "Y": 194 + }, + { + "StartTime": 2855, + "EndTime": 2855, + "X": 167.021988, + "Y": 193.867477 + }, + { + "StartTime": 2937, + "EndTime": 2937, + "X": 207.043976, + "Y": 193.734955 + }, + { + "StartTime": 3019, + "EndTime": 3019, + "X": 247.065948, + "Y": 193.602432 + }, + { + "StartTime": 3101, + "EndTime": 3101, + "X": 287.087952, + "Y": 193.46991 + }, + { + "StartTime": 3183, + "EndTime": 3183, + "X": 327.109772, + "Y": 193.337387 + }, + { + "StartTime": 3265, + "EndTime": 3265, + "X": 367.131775, + "Y": 193.204865 + }, + { + "StartTime": 3347, + "EndTime": 3347, + "X": 407.153748, + "Y": 193.072342 + }, + { + "StartTime": 3374, + "EndTime": 3374, + "X": 420.331726, + "Y": 193.0287 + }, + { + "StartTime": 3401, + "EndTime": 3401, + "X": 407.153748, + "Y": 193.072342 + }, + { + "StartTime": 3483, + "EndTime": 3483, + "X": 367.131775, + "Y": 193.204865 + }, + { + "StartTime": 3565, + "EndTime": 3565, + "X": 327.109772, + "Y": 193.337387 + }, + { + "StartTime": 3647, + "EndTime": 3647, + "X": 287.087952, + "Y": 193.46991 + }, + { + "StartTime": 3729, + "EndTime": 3729, + "X": 247.065948, + "Y": 193.602432 + }, + { + "StartTime": 3811, + "EndTime": 3811, + "X": 207.043976, + "Y": 193.734955 + }, + { + "StartTime": 3893, + "EndTime": 3893, + "X": 167.021988, + "Y": 193.867477 + }, + { + "StartTime": 3975, + "EndTime": 3975, + "X": 127, + "Y": 194 + }, + { + "StartTime": 4057, + "EndTime": 4057, + "X": 167.021988, + "Y": 193.867477 + }, + { + "StartTime": 4139, + "EndTime": 4139, + "X": 207.043976, + "Y": 193.734955 + }, + { + "StartTime": 4221, + "EndTime": 4221, + "X": 247.065948, + "Y": 193.602432 + }, + { + "StartTime": 4303, + "EndTime": 4303, + "X": 287.087952, + "Y": 193.46991 + }, + { + "StartTime": 4385, + "EndTime": 4385, + "X": 327.109772, + "Y": 193.337387 + }, + { + "StartTime": 4467, + "EndTime": 4467, + "X": 367.131775, + "Y": 193.204865 + }, + { + "StartTime": 4540, + "EndTime": 4540, + "X": 420.331726, + "Y": 193.0287 + }, + { + "StartTime": 4549, + "EndTime": 4549, + "X": 407.153748, + "Y": 193.072342 + } + ] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider.osu b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider.osu new file mode 100644 index 0000000000..64aeeb0c07 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/uneven-repeat-slider.osu @@ -0,0 +1,19 @@ +osu file format v14 + +[General] +StackLeniency: 0.4 +Mode: 0 + +[Difficulty] +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8 +SliderMultiplier:1.6 +SliderTickRate:4 + +[TimingPoints] +369,327.868852459016,4,2,2,32,1,0 + +[HitObjects] +// A slider with an un-even amount of ticks +127,194,369,6,0,L|429:193,7,293.333333333333 diff --git a/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs b/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs new file mode 100644 index 0000000000..9fba0f1668 --- /dev/null +++ b/osu.Game.Tests/Beatmaps/SliderEventGenerationTest.cs @@ -0,0 +1,116 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Tests.Beatmaps +{ + [TestFixture] + public class SliderEventGenerationTest + { + private const double start_time = 0; + private const double span_duration = 1000; + + [Test] + public void TestSingleSpan() + { + var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, null).ToArray(); + + Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head)); + Assert.That(events[0].Time, Is.EqualTo(start_time)); + + Assert.That(events[1].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[1].Time, Is.EqualTo(span_duration / 2)); + + Assert.That(events[3].Type, Is.EqualTo(SliderEventType.Tail)); + Assert.That(events[3].Time, Is.EqualTo(span_duration)); + } + + [Test] + public void TestRepeat() + { + var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 2, null).ToArray(); + + Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head)); + Assert.That(events[0].Time, Is.EqualTo(start_time)); + + Assert.That(events[1].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[1].Time, Is.EqualTo(span_duration / 2)); + + Assert.That(events[2].Type, Is.EqualTo(SliderEventType.Repeat)); + Assert.That(events[2].Time, Is.EqualTo(span_duration)); + + Assert.That(events[3].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[3].Time, Is.EqualTo(span_duration + span_duration / 2)); + + Assert.That(events[5].Type, Is.EqualTo(SliderEventType.Tail)); + Assert.That(events[5].Time, Is.EqualTo(2 * span_duration)); + } + + [Test] + public void TestNonEvenTicks() + { + var events = SliderEventGenerator.Generate(start_time, span_duration, 1, 300, span_duration, 2, null).ToArray(); + + Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head)); + Assert.That(events[0].Time, Is.EqualTo(start_time)); + + Assert.That(events[1].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[1].Time, Is.EqualTo(300)); + + Assert.That(events[2].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[2].Time, Is.EqualTo(600)); + + Assert.That(events[3].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[3].Time, Is.EqualTo(900)); + + Assert.That(events[4].Type, Is.EqualTo(SliderEventType.Repeat)); + Assert.That(events[4].Time, Is.EqualTo(span_duration)); + + Assert.That(events[5].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[5].Time, Is.EqualTo(1100)); + + Assert.That(events[6].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[6].Time, Is.EqualTo(1400)); + + Assert.That(events[7].Type, Is.EqualTo(SliderEventType.Tick)); + Assert.That(events[7].Time, Is.EqualTo(1700)); + + Assert.That(events[9].Type, Is.EqualTo(SliderEventType.Tail)); + Assert.That(events[9].Time, Is.EqualTo(2 * span_duration)); + } + + [Test] + public void TestLegacyLastTickOffset() + { + var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, 100).ToArray(); + + Assert.That(events[2].Type, Is.EqualTo(SliderEventType.LegacyLastTick)); + Assert.That(events[2].Time, Is.EqualTo(900)); + } + + [Test] + public void TestMinimumTickDistance() + { + const double velocity = 5; + const double min_distance = velocity * 10; + + var events = SliderEventGenerator.Generate(start_time, span_duration, velocity, velocity, span_duration, 2, 0).ToArray(); + + Assert.Multiple(() => + { + int tickIndex = -1; + + while (++tickIndex < events.Length) + { + if (events[tickIndex].Type != SliderEventType.Tick) + continue; + + Assert.That(events[tickIndex].Time, Is.LessThan(span_duration - min_distance).Or.GreaterThan(span_duration + min_distance)); + } + }); + } + } +} From 0ff1c6184b31768e3aff483b2c603213ae91e6c7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 17:36:20 +0900 Subject: [PATCH 082/645] Add generation comment --- osu.Game/Rulesets/Objects/SliderEventGenerator.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs index 9047d338aa..0d8796b4cb 100644 --- a/osu.Game/Rulesets/Objects/SliderEventGenerator.cs +++ b/osu.Game/Rulesets/Objects/SliderEventGenerator.cs @@ -118,6 +118,7 @@ namespace osu.Game.Rulesets.Objects if (d >= length - minDistanceFromEnd) break; + // Always generate ticks from the start of the path rather than the span to ensure that ticks in repeat spans are positioned identically to those in non-repeat spans var pathProgress = d / length; var timeProgress = reversed ? 1 - pathProgress : pathProgress; From 2ae8cba24d8c951bb7d6331b6c7151d1c02e40b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 17:58:20 +0900 Subject: [PATCH 083/645] Add hardrock spinner test --- .../CatchBeatmapConversionTest.cs | 1 + .../hardrock-spinner-expected-conversion.json | 74 +++++++++++++++++++ .../Testing/Beatmaps/hardrock-spinner.osu | 18 +++++ 3 files changed, 93 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner-expected-conversion.json create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner.osu diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 80ac64c5f9..dd272599ab 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("slider")] [TestCase("hardrock-stream", new[] { typeof(CatchModHardRock) })] [TestCase("hardrock-repeat-slider", new[] { typeof(CatchModHardRock) })] + [TestCase("hardrock-spinner", new[] { typeof(CatchModHardRock) })] public new void Test(string name, params Type[] mods) { base.Test(name, mods); diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner-expected-conversion.json new file mode 100644 index 0000000000..7333b600fb --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner-expected-conversion.json @@ -0,0 +1,74 @@ +{ + "Mappings": [{ + "StartTime": 369, + "Objects": [{ + "StartTime": 369, + "Position": 65 + }, + { + "StartTime": 450, + "Position": 482 + }, + { + "StartTime": 532, + "Position": 164 + }, + { + "StartTime": 614, + "Position": 315 + }, + { + "StartTime": 696, + "Position": 145 + }, + { + "StartTime": 778, + "Position": 159 + }, + { + "StartTime": 860, + "Position": 310 + }, + { + "StartTime": 942, + "Position": 441 + }, + { + "StartTime": 1024, + "Position": 428 + }, + { + "StartTime": 1106, + "Position": 243 + }, + { + "StartTime": 1188, + "Position": 422 + }, + { + "StartTime": 1270, + "Position": 481 + }, + { + "StartTime": 1352, + "Position": 104 + }, + { + "StartTime": 1434, + "Position": 473 + }, + { + "StartTime": 1516, + "Position": 135 + }, + { + "StartTime": 1598, + "Position": 360 + }, + { + "StartTime": 1680, + "Position": 123 + } + ] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner.osu new file mode 100644 index 0000000000..208d21a344 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-spinner.osu @@ -0,0 +1,18 @@ +osu file format v14 + +[General] +StackLeniency: 0.4 +Mode: 0 + +[Difficulty] +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8 +SliderMultiplier:1.6 +SliderTickRate:4 + +[TimingPoints] +369,327.868852459016,4,2,2,32,1,0 + +[HitObjects] +256,192,369,12,0,1680,0:0:0:0: From e9eea7157d9cf0fa333513a98171ff6b3203e23c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 1 Aug 2019 18:04:57 +0900 Subject: [PATCH 084/645] Trim unnecessary file contents --- .../Testing/Beatmaps/hardrock-stream.osu | 59 +------------------ 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu index 62835135df..321af4604b 100644 --- a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/hardrock-stream.osu @@ -1,75 +1,18 @@ osu file format v14 [General] -AudioFilename: audio.mp3 -AudioLeadIn: 0 -PreviewTime: 53483 -Countdown: 0 -SampleSet: Soft StackLeniency: 0.4 Mode: 0 -LetterboxInBreaks: 0 -WidescreenStoryboard: 0 - -[Editor] -Bookmarks: 369,1680,12172,22664,33155,43647,54139,64631,75123,85614,96106,103975,114467,124959,135287 -DistanceSpacing: 1 -BeatDivisor: 4 -GridSize: 8 -TimelineZoom: 2.899999 - -[Metadata] -Title:Silhouette -TitleUnicode:シルエット -Artist:KANA-BOON -ArtistUnicode:KANA-BOON -Creator:Nevo -Version:lit120's Hard -Source:NARUTO-ナルト-疾風伝 -Tags:shippuuden shipuuden shippuden nine tails opening 16 kage cut ver version naotoshi nao tomori shunao shogunmoon sotarks pika [[pika]] frostwich lit120 shiratoi armin a_r_m_i_n -BeatmapID:1653115 -BeatmapSetID:780952 [Difficulty] -HPDrainRate:6 CircleSize:4 OverallDifficulty:7 ApproachRate:8 SliderMultiplier:1.6 SliderTickRate:1 -[Events] -//Background and Video events -0,0,"OSpGdEP.png",0,0 -//Break Periods -//Storyboard Layer 0 (Background) -//Storyboard Layer 1 (Fail) -//Storyboard Layer 2 (Pass) -//Storyboard Layer 3 (Foreground) -//Storyboard Sound Samples - [TimingPoints] 369,327.868852459016,4,2,2,32,1,0 -1680,-100,4,2,2,42,0,0 -6926,-100,4,2,2,52,0,0 -11844,-100,4,2,2,5,0,0 -12172,-100,4,2,2,62,0,0 -22664,-100,4,2,2,52,0,0 -43647,-100,4,2,2,52,0,0 -53483,-100,4,2,2,32,0,0 -54139,-100,4,2,2,72,0,1 -96106,-100,4,2,2,52,0,0 -103975,-100,4,2,2,82,0,1 -124959,-100,4,2,2,62,0,0 -130205,-100,4,2,2,72,0,0 -132991,-100,4,2,2,82,0,0 - - -[Colours] -Combo1 : 154,53,255 -Combo2 : 253,211,47 -Combo3 : 86,168,250 -Combo4 : 192,192,192 [HitObjects] 258,189,369,1,0,0:0:0:0: @@ -104,4 +47,4 @@ Combo4 : 192,192,192 258,189,2746,1,0,0:0:0:0: 258,189,2828,1,0,0:0:0:0: 258,189,2909,1,0,0:0:0:0: -258,189,2991,1,0,0:0:0:0: +258,189,2991,1,0,0:0:0:0: \ No newline at end of file From d55875800067ec90f60f55e492a26c2a30dc0ca3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 19:14:07 +0300 Subject: [PATCH 085/645] Add PreviousUsernames field to the User --- osu.Game/Users/User.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 34bd4bbaae..22c0a4fcd0 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -20,6 +20,9 @@ namespace osu.Game.Users [JsonProperty(@"username")] public string Username; + [JsonProperty(@"previous_usernames")] + public string[] PreviousUsernames; + [JsonProperty(@"country")] public Country Country; From 90c59ab39d3058189e530ed25e3597284ea27b5b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 21:26:59 +0300 Subject: [PATCH 086/645] implement PreviousUsernamesContainer --- .../TestScenePreviousUsernamesContainer.cs | 52 +++++ .../Header/PreviousUsernamesContainer.cs | 179 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs new file mode 100644 index 0000000000..0469c230d0 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.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.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Overlays.Profile.Header; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestScenePreviousUsernamesContainer : OsuTestScene + { + public TestScenePreviousUsernamesContainer() + { + Bindable user = new Bindable(); + + Child = new PreviousUsernamesContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + User = { BindTarget = user }, + }; + + AddStep("single username", () => user.Value = new User + { + PreviousUsernames = new[] { "username1" }, + }); + + AddStep("two usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "longusername", "longerusername" }, + }); + + AddStep("three usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "test", "angelsim", "verylongusername" }, + }); + + AddStep("four usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext" , "anylonger" }, + }); + + AddStep("no username", () => user.Value = new User + { + PreviousUsernames = new string[0], + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs new file mode 100644 index 0000000000..39bd2388a4 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -0,0 +1,179 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Users; +using osuTK; +using System; +using System.Linq; + +namespace osu.Game.Overlays.Profile.Header +{ + public class PreviousUsernamesContainer : Container + { + private const int duration = 200; + private const int margin = 10; + private const int width = 350; + private const int move_offset = 30; + + public readonly Bindable User = new Bindable(); + + private readonly HoverIconContainer hoverIcon; + private readonly ContentContainer contentContainer; + + public PreviousUsernamesContainer() + { + AutoSizeAxes = Axes.Y; + Width = width; + Children = new Drawable[] + { + contentContainer = new ContentContainer(), + hoverIcon = new HoverIconContainer(), + }; + + hoverIcon.ActivateHover += () => + { + contentContainer.Show(); + this.MoveToY(-move_offset, duration, Easing.OutQuint); + }; + + User.BindValueChanged(onUserChanged); + } + + private void onUserChanged(ValueChangedEvent user) + { + contentContainer.Clear(); + + var usernames = user.NewValue.PreviousUsernames; + + if (usernames.Any()) + { + var amount = usernames.Count(); + + for (int i = 0; i < amount; i++) + { + string text = (i + 1 == amount) ? usernames[i] : $@"{usernames[i]},"; + + contentContainer.Usernames.AddText(new SpriteText + { + Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), + Text = text, + }); + } + + Show(); + return; + } + + Hide(); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + contentContainer.Hide(); + this.MoveToY(0, duration, Easing.OutQuint); + } + + private class ContentContainer : VisibilityContainer + { + private const int header_height = 25; + private const int content_padding = 60; + + public readonly TextFlowContainer Usernames; + + private readonly Box background; + + public ContentContainer() + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + Masking = true; + AlwaysPresent = true; + CornerRadius = 5; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + Height = header_height, + Children = new Drawable[] + { + new SpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Padding = new MarginPadding { Left = content_padding }, + Text = @"formerly known as", + Font = OsuFont.GetFont(size: 14, italics: true) + } + } + }, + Usernames = new TextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Full, + Spacing = new Vector2(5, 5), + Padding = new MarginPadding { Left = content_padding, Bottom = margin }, + }, + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoamDarker; + } + + public override void Clear(bool disposeChildren) => Usernames.Clear(disposeChildren); + + protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); + } + + private class HoverIconContainer : Container + { + public Action ActivateHover; + + public HoverIconContainer() + { + AutoSizeAxes = Axes.Both; + Child = new SpriteIcon + { + Margin = new MarginPadding(margin) { Top = 7 }, + Size = new Vector2(20), + Icon = FontAwesome.Solid.IdCard, + }; + } + + protected override bool OnHover(HoverEvent e) + { + ActivateHover?.Invoke(); + return base.OnHover(e); + } + } + } +} From 13fe1732d8cf8b76aa689a585ad6c3fe63128119 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 21:32:04 +0300 Subject: [PATCH 087/645] adjust height values to avoid random jumps --- .../Overlays/Profile/Header/PreviousUsernamesContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 39bd2388a4..67b9bcb651 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header private const int duration = 200; private const int margin = 10; private const int width = 350; - private const int move_offset = 30; + private const int move_offset = 20; public readonly Bindable User = new Bindable(); @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Both; Child = new SpriteIcon { - Margin = new MarginPadding(margin) { Top = 7 }, + Margin = new MarginPadding(margin) { Top = 6 }, Size = new Vector2(20), Icon = FontAwesome.Solid.IdCard, }; From e66a3494b9fbd43c9f49d718af1683106d86dc93 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 22:50:01 +0300 Subject: [PATCH 088/645] make the container hidden by default --- osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 67b9bcb651..5165f0d0df 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -45,6 +45,7 @@ namespace osu.Game.Overlays.Profile.Header }; User.BindValueChanged(onUserChanged); + Hide(); } private void onUserChanged(ValueChangedEvent user) From 55475927685aee49e5686899d6898ff8093fc7d4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 23:04:18 +0300 Subject: [PATCH 089/645] CI fixes --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 +- .../Overlays/Profile/Header/PreviousUsernamesContainer.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 0469c230d0..a33de887d7 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("four usernames", () => user.Value = new User { - PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext" , "anylonger" }, + PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" }, }); AddStep("no username", () => user.Value = new User diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 5165f0d0df..1c98cff616 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -25,11 +25,12 @@ namespace osu.Game.Overlays.Profile.Header public readonly Bindable User = new Bindable(); - private readonly HoverIconContainer hoverIcon; private readonly ContentContainer contentContainer; public PreviousUsernamesContainer() { + HoverIconContainer hoverIcon; + AutoSizeAxes = Axes.Y; Width = width; Children = new Drawable[] @@ -56,7 +57,7 @@ namespace osu.Game.Overlays.Profile.Header if (usernames.Any()) { - var amount = usernames.Count(); + var amount = usernames.Length; for (int i = 0; i < amount; i++) { From de96e5dfc605f559269a2e045652ab2453267d2d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 2 Aug 2019 07:41:11 +0300 Subject: [PATCH 090/645] Apply suggested changes --- .../TestScenePreviousUsernamesContainer.cs | 5 ++ .../Header/PreviousUsernamesContainer.cs | 58 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index a33de887d7..4f3a2e47c6 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -43,6 +43,11 @@ namespace osu.Game.Tests.Visual.Online PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" }, }); + AddStep("many usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger", "but", "ican", "try", "tomake", "this" }, + }); + AddStep("no username", () => user.Value = new User { PreviousUsernames = new string[0], diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 1c98cff616..e8443dff1b 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -16,12 +16,12 @@ using System.Linq; namespace osu.Game.Overlays.Profile.Header { - public class PreviousUsernamesContainer : Container + public class PreviousUsernamesContainer : CompositeDrawable { private const int duration = 200; private const int margin = 10; - private const int width = 350; - private const int move_offset = 20; + private const int width = 310; + private const int move_offset = 15; public readonly Bindable User = new Bindable(); @@ -33,43 +33,35 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Y; Width = width; - Children = new Drawable[] + + AddRangeInternal(new Drawable[] { contentContainer = new ContentContainer(), hoverIcon = new HoverIconContainer(), - }; + }); hoverIcon.ActivateHover += () => { contentContainer.Show(); this.MoveToY(-move_offset, duration, Easing.OutQuint); }; + } - User.BindValueChanged(onUserChanged); - Hide(); + protected override void LoadComplete() + { + base.LoadComplete(); + User.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent user) { - contentContainer.Clear(); + contentContainer.Text = string.Empty; - var usernames = user.NewValue.PreviousUsernames; + var usernames = user.NewValue?.PreviousUsernames; - if (usernames.Any()) + if (usernames?.Any() ?? false) { - var amount = usernames.Length; - - for (int i = 0; i < amount; i++) - { - string text = (i + 1 == amount) ? usernames[i] : $@"{usernames[i]},"; - - contentContainer.Usernames.AddText(new SpriteText - { - Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), - Text = text, - }); - } - + contentContainer.Text = string.Join(", ", usernames); Show(); return; } @@ -86,11 +78,15 @@ namespace osu.Game.Overlays.Profile.Header private class ContentContainer : VisibilityContainer { - private const int header_height = 25; - private const int content_padding = 60; + private const int header_height = 20; + private const int content_padding = 40; - public readonly TextFlowContainer Usernames; + public string Text + { + set => usernames.Text = value; + } + private readonly TextFlowContainer usernames; private readonly Box background; public ContentContainer() @@ -126,16 +122,16 @@ namespace osu.Game.Overlays.Profile.Header Origin = Anchor.BottomLeft, Padding = new MarginPadding { Left = content_padding }, Text = @"formerly known as", - Font = OsuFont.GetFont(size: 14, italics: true) + Font = OsuFont.GetFont(size: 10, italics: true) } } }, - Usernames = new TextFlowContainer + usernames = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Spacing = new Vector2(5, 5), + Spacing = new Vector2(0, 5), Padding = new MarginPadding { Left = content_padding, Bottom = margin }, }, } @@ -149,8 +145,6 @@ namespace osu.Game.Overlays.Profile.Header background.Colour = colours.GreySeafoamDarker; } - public override void Clear(bool disposeChildren) => Usernames.Clear(disposeChildren); - protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); @@ -166,7 +160,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new SpriteIcon { Margin = new MarginPadding(margin) { Top = 6 }, - Size = new Vector2(20), + Size = new Vector2(15), Icon = FontAwesome.Solid.IdCard, }; } From 4c0a9aeab701381ad602cde155b636327ba979f7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 2 Aug 2019 07:44:09 +0300 Subject: [PATCH 091/645] Add null user step --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 4f3a2e47c6..4a3b3403b2 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -52,6 +52,8 @@ namespace osu.Game.Tests.Visual.Online { PreviousUsernames = new string[0], }); + + AddStep("null user", () => user.Value = null); } } } From ba3f8a643a899f268d75882af1c44ba045f13180 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 2 Aug 2019 14:16:57 +0900 Subject: [PATCH 092/645] Update cake --- build/cakebuild.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/cakebuild.csproj b/build/cakebuild.csproj index 8ccce35e26..d5a6d44740 100644 --- a/build/cakebuild.csproj +++ b/build/cakebuild.csproj @@ -5,7 +5,7 @@ netcoreapp2.0 - - + + \ No newline at end of file From e84c79d14051ecb220429c38cdb321e53f9a0b24 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 2 Aug 2019 13:16:33 -0700 Subject: [PATCH 093/645] Update osu!direct categories sorting with web changes --- .../API/Requests/SearchBeatmapSetsRequest.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index d9d05ff285..c8c36789c4 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -27,24 +27,25 @@ namespace osu.Game.Online.API.Requests } // ReSharper disable once ImpureMethodCallOnReadonlyValueField - protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)searchCategory}&sort={sortCriteria.ToString().ToLowerInvariant()}_{directionString}"; + protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={searchCategory.ToString().ToLowerInvariant()}&sort={sortCriteria.ToString().ToLowerInvariant()}_{directionString}"; } public enum BeatmapSearchCategory { - Any = 7, + Any, - [Description("Ranked & Approved")] - RankedApproved = 0, - Qualified = 3, - Loved = 8, - Favourites = 2, + [Description("Has Leaderboard")] + Leaderboard, + Ranked, + Qualified, + Loved, + Favourites, [Description("Pending & WIP")] - PendingWIP = 4, - Graveyard = 5, + Pending, + Graveyard, [Description("My Maps")] - MyMaps = 6, + Mine, } } From 0082695cd827a574e91a0c8be4d0bd8da1288e8e Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 2 Aug 2019 13:22:58 -0700 Subject: [PATCH 094/645] Choose default category sorting instead of being always first --- osu.Game/Overlays/Direct/FilterControl.cs | 1 + .../Overlays/SearchableList/SearchableListFilterControl.cs | 4 ++++ osu.Game/Overlays/Social/FilterControl.cs | 1 + osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs | 1 + 4 files changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 4b43542b43..8b04bf0387 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -18,6 +18,7 @@ namespace osu.Game.Overlays.Direct protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked; + protected override BeatmapSearchCategory DefaultCategory => BeatmapSearchCategory.Leaderboard; protected override Drawable CreateSupplementaryControls() => rulesetSelector = new DirectRulesetSelector(); diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index b0a8a0e77d..a0c4e9a080 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -26,6 +26,7 @@ namespace osu.Game.Overlays.SearchableList protected abstract Color4 BackgroundColour { get; } protected abstract T DefaultTab { get; } + protected abstract U DefaultCategory { get; } protected virtual Drawable CreateSupplementaryControls() => null; /// @@ -109,6 +110,9 @@ namespace osu.Game.Overlays.SearchableList Tabs.Current.Value = DefaultTab; Tabs.Current.TriggerChange(); + + DisplayStyleControl.Dropdown.Current.Value = DefaultCategory; + DisplayStyleControl.Dropdown.Current.TriggerChange(); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 6abf6ec98d..1c2cb95dfe 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -12,6 +12,7 @@ namespace osu.Game.Overlays.Social { protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Rank; + protected override SortDirection DefaultCategory => SortDirection.Ascending; public FilterControl() { diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index 8e14f76e4b..d0d983bbff 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42"); protected override PrimaryFilter DefaultTab => PrimaryFilter.Open; + protected override SecondaryFilter DefaultCategory => SecondaryFilter.Public; protected override float ContentHorizontalPadding => base.ContentHorizontalPadding + OsuScreen.HORIZONTAL_OVERFLOW_PADDING; From f81238b8b18b38546615c2992df68ca35a19baa8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Aug 2019 04:45:41 +0300 Subject: [PATCH 095/645] Add online test --- .../TestScenePreviousUsernamesContainer.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 4a3b3403b2..dafc1870e4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -2,8 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; @@ -12,10 +15,13 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestScenePreviousUsernamesContainer : OsuTestScene { + [Resolved] + private IAPIProvider api { get; set; } + + private readonly Bindable user = new Bindable(); + public TestScenePreviousUsernamesContainer() { - Bindable user = new Bindable(); - Child = new PreviousUsernamesContainer { Anchor = Anchor.Centre, @@ -55,5 +61,17 @@ namespace osu.Game.Tests.Visual.Online AddStep("null user", () => user.Value = null); } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AddStep("online user (Angelsim)", () => + { + var request = new GetUserRequest(1777162); + request.Success += user => this.user.Value = user; + api.Queue(request); + }); + } } } From 37be4fbf1622d0f80271b5400a497b0bfdfb9984 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Aug 2019 05:34:14 +0300 Subject: [PATCH 096/645] Use GridContainer for layout --- .../TestScenePreviousUsernamesContainer.cs | 43 ++--- .../Header/PreviousUsernamesContainer.cs | 159 +++++++++--------- 2 files changed, 90 insertions(+), 112 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index dafc1870e4..5636f8756d 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -29,37 +29,22 @@ namespace osu.Game.Tests.Visual.Online User = { BindTarget = user }, }; - AddStep("single username", () => user.Value = new User + User[] users = new[] { - PreviousUsernames = new[] { "username1" }, - }); + new User { PreviousUsernames = new[] { "username1" } }, + new User { PreviousUsernames = new[] { "longusername", "longerusername" } }, + new User { PreviousUsernames = new[] { "test", "angelsim", "verylongusername" } }, + new User { PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" } }, + new User { PreviousUsernames = new string[0] }, + null + }; - AddStep("two usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "longusername", "longerusername" }, - }); - - AddStep("three usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "test", "angelsim", "verylongusername" }, - }); - - AddStep("four usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" }, - }); - - AddStep("many usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger", "but", "ican", "try", "tomake", "this" }, - }); - - AddStep("no username", () => user.Value = new User - { - PreviousUsernames = new string[0], - }); - - AddStep("null user", () => user.Value = null); + AddStep("single username", () => user.Value = users[0]); + AddStep("two usernames", () => user.Value = users[1]); + AddStep("three usernames", () => user.Value = users[2]); + AddStep("four usernames", () => user.Value = users[3]); + AddStep("no username", () => user.Value = users[4]); + AddStep("null user", () => user.Value = users[5]); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index e8443dff1b..36034fe8db 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -25,7 +25,9 @@ namespace osu.Game.Overlays.Profile.Header public readonly Bindable User = new Bindable(); - private readonly ContentContainer contentContainer; + private readonly TextFlowContainer text; + private readonly Box background; + private readonly SpriteText header; public PreviousUsernamesContainer() { @@ -33,18 +35,68 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Y; Width = width; + Masking = true; + CornerRadius = 5; AddRangeInternal(new Drawable[] { - contentContainer = new ContentContainer(), - hoverIcon = new HoverIconContainer(), + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new GridContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize) + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed) + }, + Content = new[] + { + new Drawable[] + { + hoverIcon = new HoverIconContainer(), + header = new SpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = @"formerly known as", + Font = OsuFont.GetFont(size: 10, italics: true) + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + }, + text = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Full, + Margin = new MarginPadding { Bottom = margin, Top = margin / 2 } + } + } + } + } }); - hoverIcon.ActivateHover += () => - { - contentContainer.Show(); - this.MoveToY(-move_offset, duration, Easing.OutQuint); - }; + hoverIcon.ActivateHover += showContent; + hideContent(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoamDarker; } protected override void LoadComplete() @@ -55,13 +107,13 @@ namespace osu.Game.Overlays.Profile.Header private void onUserChanged(ValueChangedEvent user) { - contentContainer.Text = string.Empty; + text.Text = string.Empty; var usernames = user.NewValue?.PreviousUsernames; if (usernames?.Any() ?? false) { - contentContainer.Text = string.Join(", ", usernames); + text.Text = string.Join(", ", usernames); Show(); return; } @@ -72,82 +124,23 @@ namespace osu.Game.Overlays.Profile.Header protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - contentContainer.Hide(); - this.MoveToY(0, duration, Easing.OutQuint); + hideContent(); } - private class ContentContainer : VisibilityContainer + private void showContent() { - private const int header_height = 20; - private const int content_padding = 40; + text.FadeIn(duration, Easing.OutQuint); + header.FadeIn(duration, Easing.OutQuint); + background.FadeIn(duration, Easing.OutQuint); + this.MoveToY(-move_offset, duration, Easing.OutQuint); + } - public string Text - { - set => usernames.Text = value; - } - - private readonly TextFlowContainer usernames; - private readonly Box background; - - public ContentContainer() - { - AutoSizeAxes = Axes.Y; - RelativeSizeAxes = Axes.X; - Masking = true; - AlwaysPresent = true; - CornerRadius = 5; - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.X, - Height = header_height, - Children = new Drawable[] - { - new SpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Padding = new MarginPadding { Left = content_padding }, - Text = @"formerly known as", - Font = OsuFont.GetFont(size: 10, italics: true) - } - } - }, - usernames = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Full, - Spacing = new Vector2(0, 5), - Padding = new MarginPadding { Left = content_padding, Bottom = margin }, - }, - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.GreySeafoamDarker; - } - - protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); - - protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); + private void hideContent() + { + text.FadeOut(duration, Easing.OutQuint); + header.FadeOut(duration, Easing.OutQuint); + background.FadeOut(duration, Easing.OutQuint); + this.MoveToY(0, duration, Easing.OutQuint); } private class HoverIconContainer : Container @@ -159,7 +152,7 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Both; Child = new SpriteIcon { - Margin = new MarginPadding(margin) { Top = 6 }, + Margin = new MarginPadding { Top = 6, Left = margin, Right = margin * 2 }, Size = new Vector2(15), Icon = FontAwesome.Solid.IdCard, }; From 416f9d89dba59a8cc85e020e643506f4f02b1b44 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Aug 2019 05:49:01 +0300 Subject: [PATCH 097/645] CI fixes --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 +- osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 5636f8756d..b891fda0f4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual.Online User = { BindTarget = user }, }; - User[] users = new[] + User[] users = { new User { PreviousUsernames = new[] { "username1" } }, new User { PreviousUsernames = new[] { "longusername", "longerusername" } }, diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 36034fe8db..b53ac8eb80 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Margin = new MarginPadding { Bottom = margin, Top = margin / 2 } + Margin = new MarginPadding { Bottom = margin, Top = margin / 2f } } } } From b244b2fe3d378f7050ba3f8dc9f88a098a98b776 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 2 Aug 2019 21:13:29 -0700 Subject: [PATCH 098/645] Add hover click sounds to leaderboard mod filter --- osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index d158186899..544acc7eb2 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -81,7 +81,8 @@ namespace osu.Game.Graphics.UserInterface Colour = Color4.White, Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, - } + }, + new HoverClickSounds() }; Current.ValueChanged += selected => From c8dd29067b2f44354a624bf67567b6f382bd1bd5 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Sun, 4 Aug 2019 00:34:51 +0300 Subject: [PATCH 099/645] Update Entity Framework Core --- osu.Desktop/osu.Desktop.csproj | 4 ++-- osu.Game/osu.Game.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 8c9e1f279f..538aaf2d7a 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -28,8 +28,8 @@ - - + + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1f91ce1cd8..cf325b77be 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -11,8 +11,8 @@ - - + + From 115cf47ed5e8a697c25b24395094f076b0a47955 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 3 Aug 2019 15:20:44 -0700 Subject: [PATCH 100/645] Fix settings sidebar showing scrollbar at max ui scale --- osu.Game/Overlays/Settings/Sidebar.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index a80b7c1108..358f94b659 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -84,6 +84,7 @@ namespace osu.Game.Overlays.Settings Content.Anchor = Anchor.CentreLeft; Content.Origin = Anchor.CentreLeft; RelativeSizeAxes = Axes.Both; + ScrollbarVisible = false; } } From f6f96658c7b7a51f327702d9a612806af0484da2 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 3 Aug 2019 15:22:06 -0700 Subject: [PATCH 101/645] Fix settings sidebar being behind toolbar --- osu.Game/Overlays/SettingsPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 474f529bb1..9dd0def453 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -186,7 +186,7 @@ namespace osu.Game.Overlays base.UpdateAfterChildren(); ContentContainer.Margin = new MarginPadding { Left = Sidebar?.DrawWidth ?? 0 }; - ContentContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 }; + Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 }; } protected class SettingsSectionsContainer : SectionsContainer From c8acbdb1d9600db601c9967f0d2e18b15584be80 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 4 Aug 2019 06:15:15 +0300 Subject: [PATCH 102/645] Update the colour --- osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs index c5e61f68f4..fa60a37ddb 100644 --- a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs @@ -80,7 +80,6 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load(OsuColour colours) { background.Colour = colours.Pink; - iconContainer.Colour = colours.GreySeafoam; } } } From a30d7912b1b34cb0d06b013683143994549b7f57 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 4 Aug 2019 11:09:12 +0300 Subject: [PATCH 103/645] Move DimmedLoadingAnimation to it's own file --- .../UserInterface/DimmedLoadingAnimation.cs | 44 +++++++++++++++++++ osu.Game/Screens/Select/BeatmapDetails.cs | 35 +-------------- 2 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs diff --git a/osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs b/osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs new file mode 100644 index 0000000000..30c8c5f143 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs @@ -0,0 +1,44 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osuTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Extensions.Color4Extensions; + +namespace osu.Game.Graphics.UserInterface +{ + public class DimmedLoadingAnimation : VisibilityContainer + { + private const float transition_duration = 250; + + private readonly LoadingAnimation loading; + + public DimmedLoadingAnimation() + { + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + loading = new LoadingAnimation(), + }; + } + + protected override void PopIn() + { + this.FadeIn(transition_duration, Easing.OutQuint); + loading.Show(); + } + + protected override void PopOut() + { + this.FadeOut(transition_duration, Easing.OutQuint); + loading.Hide(); + } + } +} diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 23dd87d8ea..9d2e6f1719 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -156,10 +156,7 @@ namespace osu.Game.Screens.Select }, }, }, - loading = new DimmedLoadingAnimation - { - RelativeSizeAxes = Axes.Both, - }, + loading = new DimmedLoadingAnimation(), }; } @@ -365,35 +362,5 @@ namespace osu.Game.Screens.Select }); } } - - private class DimmedLoadingAnimation : VisibilityContainer - { - private readonly LoadingAnimation loading; - - public DimmedLoadingAnimation() - { - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - loading = new LoadingAnimation(), - }; - } - - protected override void PopIn() - { - this.FadeIn(transition_duration, Easing.OutQuint); - loading.Show(); - } - - protected override void PopOut() - { - this.FadeOut(transition_duration, Easing.OutQuint); - loading.Hide(); - } - } } } From fd44ca3233a90207122b0ae16d9606bf09fa9755 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 4 Aug 2019 13:54:23 +0300 Subject: [PATCH 104/645] Rename Animation to Layer --- .../{DimmedLoadingAnimation.cs => DimmedLoadingLayer.cs} | 4 ++-- osu.Game/Screens/Select/BeatmapDetails.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Graphics/UserInterface/{DimmedLoadingAnimation.cs => DimmedLoadingLayer.cs} (91%) diff --git a/osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs b/osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs similarity index 91% rename from osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs rename to osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs index 30c8c5f143..b7d2222f33 100644 --- a/osu.Game/Graphics/UserInterface/DimmedLoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/DimmedLoadingLayer.cs @@ -9,13 +9,13 @@ using osu.Framework.Extensions.Color4Extensions; namespace osu.Game.Graphics.UserInterface { - public class DimmedLoadingAnimation : VisibilityContainer + public class DimmedLoadingLayer : VisibilityContainer { private const float transition_duration = 250; private readonly LoadingAnimation loading; - public DimmedLoadingAnimation() + public DimmedLoadingLayer() { RelativeSizeAxes = Axes.Both; Children = new Drawable[] diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 9d2e6f1719..577d999388 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Select private readonly MetadataSection description, source, tags; private readonly Container failRetryContainer; private readonly FailRetryGraph failRetryGraph; - private readonly DimmedLoadingAnimation loading; + private readonly DimmedLoadingLayer loading; private IAPIProvider api; @@ -156,7 +156,7 @@ namespace osu.Game.Screens.Select }, }, }, - loading = new DimmedLoadingAnimation(), + loading = new DimmedLoadingLayer(), }; } From 3ae5428dad6e81dc0f7d5e3043247063774ee2d2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 4 Aug 2019 14:15:16 +0300 Subject: [PATCH 105/645] ProfileRulesetSelector improvements --- .../Online/TestSceneProfileRulesetSelector.cs | 8 +++++- .../Components/ProfileRulesetSelector.cs | 28 ++++++++++--------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index c344cb9598..d439e6a7c3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; +using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { @@ -34,7 +35,12 @@ namespace osu.Game.Tests.Visual.Online AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo)); AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); - AddStep("select default ruleset", selector.SelectDefaultRuleset); + + AddStep("User with osu as default", () => selector.User.Value = new User { PlayMode = "osu" }); + AddStep("User with mania as default", () => selector.User.Value = new User { PlayMode = "mania" }); + AddStep("User with taiko as default", () => selector.User.Value = new User { PlayMode = "taiko" }); + AddStep("User with catch as default", () => selector.User.Value = new User { PlayMode = "fruits" }); + AddStep("null user", () => selector.User.Value = null); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index b6112a6501..09bc2f2cdc 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -2,11 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Rulesets; +using osu.Game.Users; using osuTK; using osuTK.Graphics; @@ -16,6 +18,8 @@ namespace osu.Game.Overlays.Profile.Header.Components { private Color4 accentColour = Color4.White; + public readonly Bindable User = new Bindable(); + public ProfileRulesetSelector() { TabContainer.Masking = false; @@ -32,24 +36,22 @@ namespace osu.Game.Overlays.Profile.Header.Components ((ProfileRulesetTabItem)tabItem).AccentColour = accentColour; } - public void SetDefaultRuleset(RulesetInfo ruleset) + protected override void LoadComplete() { - // Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value - foreach (TabItem tabItem in TabContainer) - ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; + base.LoadComplete(); + + User.BindValueChanged(onUserChanged, true); } - public void SelectDefaultRuleset() + private void onUserChanged(ValueChangedEvent user) + { + SetDefaultRuleset(Rulesets.GetRuleset(user.NewValue?.PlayMode ?? "osu")); + } + + public void SetDefaultRuleset(RulesetInfo ruleset) { - // Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value foreach (TabItem tabItem in TabContainer) - { - if (((ProfileRulesetTabItem)tabItem).IsDefault) - { - Current.Value = ((ProfileRulesetTabItem)tabItem).Value; - return; - } - } + ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; } protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) From d693a54c84eb088a31fc9ebefcc9d7d811db60d1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 4 Aug 2019 14:35:26 +0300 Subject: [PATCH 106/645] Move RankHistoryData to User Statistics --- .../Visual/Online/TestSceneRankGraph.cs | 47 +++++++------------ .../Online/TestSceneUserProfileOverlay.cs | 12 ++--- .../Profile/Header/Components/RankGraph.cs | 19 +++++--- .../Profile/Header/DetailHeaderContainer.cs | 2 +- osu.Game/Users/User.cs | 5 +- osu.Game/Users/UserStatistics.cs | 3 ++ 6 files changed, 42 insertions(+), 46 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs index 709e75ab13..c70cc4ae4e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs @@ -69,28 +69,22 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("null user", () => graph.User.Value = null); + AddStep("null user", () => graph.Statistics.Value = null); AddStep("rank only", () => { - graph.User.Value = new User + graph.Statistics.Value = new UserStatistics { - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 123456 }, - PP = 12345, - } + Ranks = new UserStatistics.UserRanks { Global = 123456 }, + PP = 12345, }; }); AddStep("with rank history", () => { - graph.User.Value = new User + graph.Statistics.Value = new UserStatistics { - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 89000 }, - PP = 12345, - }, + Ranks = new UserStatistics.UserRanks { Global = 89000 }, + PP = 12345, RankHistory = new User.RankHistoryData { Data = data, @@ -100,13 +94,10 @@ namespace osu.Game.Tests.Visual.Online AddStep("with zero values", () => { - graph.User.Value = new User + graph.Statistics.Value = new UserStatistics { - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 89000 }, - PP = 12345, - }, + Ranks = new UserStatistics.UserRanks { Global = 89000 }, + PP = 12345, RankHistory = new User.RankHistoryData { Data = dataWithZeros, @@ -116,13 +107,10 @@ namespace osu.Game.Tests.Visual.Online AddStep("small amount of data", () => { - graph.User.Value = new User + graph.Statistics.Value = new UserStatistics { - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 12000 }, - PP = 12345, - }, + Ranks = new UserStatistics.UserRanks { Global = 12000 }, + PP = 12345, RankHistory = new User.RankHistoryData { Data = smallData, @@ -132,13 +120,10 @@ namespace osu.Game.Tests.Visual.Online AddStep("graph with edges", () => { - graph.User.Value = new User + graph.Statistics.Value = new UserStatistics { - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 12000 }, - PP = 12345, - }, + Ranks = new UserStatistics.UserRanks { Global = 12000 }, + PP = 12345, RankHistory = new User.RankHistoryData { Data = edgyData, diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index c2376aa153..84c99d8c3a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -50,12 +50,12 @@ namespace osu.Game.Tests.Visual.Online { Current = 727, Progress = 69, - } - }, - RankHistory = new User.RankHistoryData - { - Mode = @"osu", - Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() + }, + RankHistory = new User.RankHistoryData + { + Mode = @"osu", + Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() + }, }, Badges = new[] { diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 5f79386b76..4818cd8df6 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private KeyValuePair[] ranks; private int dayIndex; - public Bindable User = new Bindable(); + public readonly Bindable Statistics = new Bindable(); public RankGraph() { @@ -56,8 +56,6 @@ namespace osu.Game.Overlays.Profile.Header.Components }; graph.OnBallMove += i => dayIndex = i; - - User.ValueChanged += userChanged; } [BackgroundDependencyLoader] @@ -66,18 +64,25 @@ namespace osu.Game.Overlays.Profile.Header.Components graph.LineColour = colours.Yellow; } - private void userChanged(ValueChangedEvent e) + protected override void LoadComplete() + { + base.LoadComplete(); + + Statistics.BindValueChanged(statistics => updateStatistics(statistics.NewValue)); + } + + private void updateStatistics(UserStatistics statistics) { placeholder.FadeIn(fade_duration, Easing.Out); - if (e.NewValue?.Statistics?.Ranks.Global == null) + if (statistics?.Ranks.Global == null) { graph.FadeOut(fade_duration, Easing.Out); ranks = null; return; } - int[] userRanks = e.NewValue.RankHistory?.Data ?? new[] { e.NewValue.Statistics.Ranks.Global.Value }; + int[] userRanks = statistics.RankHistory?.Data ?? new[] { statistics.Ranks.Global.Value }; ranks = userRanks.Select((x, index) => new KeyValuePair(index, x)).Where(x => x.Value != 0).ToArray(); if (ranks.Length > 1) @@ -191,7 +196,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } } - public string TooltipText => User.Value?.Statistics?.Ranks.Global == null ? "" : $"#{ranks[dayIndex].Value:#,##0}|{ranked_days - ranks[dayIndex].Key + 1}"; + public string TooltipText => Statistics.Value?.Ranks.Global == null ? "" : $"#{ranks[dayIndex].Value:#,##0}|{ranked_days - ranks[dayIndex].Key + 1}"; public ITooltip GetCustomTooltip() => new RankGraphTooltip(); diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 0db1cb32d7..6ee0d9ee8f 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -179,7 +179,7 @@ namespace osu.Game.Overlays.Profile.Header detailGlobalRank.Content = user?.Statistics?.Ranks.Global?.ToString("\\##,##0") ?? "-"; detailCountryRank.Content = user?.Statistics?.Ranks.Country?.ToString("\\##,##0") ?? "-"; - rankGraph.User.Value = user; + rankGraph.Statistics.Value = user?.Statistics; } private class ScoreRankInfo : CompositeDrawable diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 34bd4bbaae..b738eff4a6 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -159,7 +159,10 @@ namespace osu.Game.Users } [JsonProperty(@"rankHistory")] - public RankHistoryData RankHistory; + private RankHistoryData rankHistory + { + set => Statistics.RankHistory = value; + } [JsonProperty("badges")] public Badge[] Badges; diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 7afbef01c5..032ec2e05f 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -4,6 +4,7 @@ using System; using Newtonsoft.Json; using osu.Game.Scoring; +using static osu.Game.Users.User; namespace osu.Game.Users { @@ -113,5 +114,7 @@ namespace osu.Game.Users [JsonProperty(@"country")] public int? Country; } + + public RankHistoryData RankHistory; } } From cd7b6d2d27de45747cf439a4676e0b3c0ba5cc43 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 4 Aug 2019 15:00:02 +0300 Subject: [PATCH 107/645] TestCase improvement --- .../Online/TestSceneProfileRulesetSelector.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index d439e6a7c3..1f5ba67e03 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; using osu.Game.Users; +using osu.Framework.Bindables; namespace osu.Game.Tests.Visual.Online { @@ -24,11 +25,13 @@ namespace osu.Game.Tests.Visual.Online public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; + Bindable user = new Bindable(); Child = selector = new ProfileRulesetSelector { Anchor = Anchor.Centre, Origin = Anchor.Centre, + User = { BindTarget = user } }; AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo)); @@ -36,11 +39,11 @@ namespace osu.Game.Tests.Visual.Online AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); - AddStep("User with osu as default", () => selector.User.Value = new User { PlayMode = "osu" }); - AddStep("User with mania as default", () => selector.User.Value = new User { PlayMode = "mania" }); - AddStep("User with taiko as default", () => selector.User.Value = new User { PlayMode = "taiko" }); - AddStep("User with catch as default", () => selector.User.Value = new User { PlayMode = "fruits" }); - AddStep("null user", () => selector.User.Value = null); + AddStep("User with osu as default", () => user.Value = new User { PlayMode = "osu" }); + AddStep("User with mania as default", () => user.Value = new User { PlayMode = "mania" }); + AddStep("User with taiko as default", () => user.Value = new User { PlayMode = "taiko" }); + AddStep("User with catch as default", () => user.Value = new User { PlayMode = "fruits" }); + AddStep("null user", () => user.Value = null); } } } From 2f5d23b35419f78763924593e5dc03876b0baeb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=BCbner?= Date: Mon, 5 Aug 2019 01:02:42 +0200 Subject: [PATCH 108/645] add join command --- osu.Game/Online/Chat/ChannelManager.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 3af11ff20f..30135d5b8b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -213,8 +213,27 @@ namespace osu.Game.Online.Chat PostMessage(content, true); break; + case "j": + case "join": + if (string.IsNullOrWhiteSpace(content)) + { + target.AddNewMessages(new ErrorMessage("Usage: /join [channel]")); + break; + } + + var channel = availableChannels.Where(c => c.Name == content || c.Name == $"#{content}").FirstOrDefault(); + if (channel == null) + { + target.AddNewMessages(new ErrorMessage($"Channel '{content}' not found.")); + break; + } + + JoinChannel(channel); + CurrentChannel.Value = channel; + break; + case "help": - target.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]")); + target.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action], /join [channel]")); break; default: From d83971713118afe7dff0ea2f31d47e540b9d3f27 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Aug 2019 13:18:29 +0900 Subject: [PATCH 109/645] Remove unnecessary intermediate method --- .../Profile/Header/Components/ProfileRulesetSelector.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 09bc2f2cdc..2c9a3dd5f9 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -40,12 +40,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { base.LoadComplete(); - User.BindValueChanged(onUserChanged, true); - } - - private void onUserChanged(ValueChangedEvent user) - { - SetDefaultRuleset(Rulesets.GetRuleset(user.NewValue?.PlayMode ?? "osu")); + User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu")), true); } public void SetDefaultRuleset(RulesetInfo ruleset) From 379c9e8b7caf3f8382418d818741632ce5dd0303 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 5 Aug 2019 10:02:28 +0200 Subject: [PATCH 110/645] Use expression body --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 5 +---- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 5 +---- osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 3a695ca179..b9699a88e4 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -22,10 +22,7 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("spinner")] [TestCase("spinner-and-circles")] [TestCase("slider")] - public void Test(string name) - { - base.Test(name); - } + public void Test(string name) => base.Test(name); protected override IEnumerable CreateConvertValue(HitObject hitObject) { diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 3ca9dcc42c..6f10540973 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -20,10 +20,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; [TestCase("basic")] - public void Test(string name) - { - base.Test(name); - } + public void Test(string name) => base.Test(name); protected override IEnumerable CreateConvertValue(HitObject hitObject) { diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index bafa814582..6c1882b4e2 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -20,10 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Tests [NonParallelizable] [TestCase("basic")] [TestCase("slider-generating-drumroll")] - public void Test(string name) - { - base.Test(name); - } + public void Test(string name) => base.Test(name); protected override IEnumerable CreateConvertValue(HitObject hitObject) { From ee9e8f6261d92ca24f364b7147c54dca4e542d39 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Aug 2019 17:58:16 +0900 Subject: [PATCH 111/645] Fix memory leaks from download buttons --- osu.Game/Online/DownloadTrackingComposite.cs | 30 +++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 62d6efcb6f..7bfdc7ff69 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -48,22 +48,24 @@ namespace osu.Game.Online attachDownload(manager.GetExistingDownload(modelInfo.NewValue)); }, true); - manager.DownloadBegan += download => - { - if (download.Model.Equals(Model.Value)) - attachDownload(download); - }; - - manager.DownloadFailed += download => - { - if (download.Model.Equals(Model.Value)) - attachDownload(null); - }; - + manager.DownloadBegan += downloadBegan; + manager.DownloadFailed += downloadFailed; manager.ItemAdded += itemAdded; manager.ItemRemoved += itemRemoved; } + private void downloadBegan(ArchiveDownloadRequest request) + { + if (request.Model.Equals(Model.Value)) + attachDownload(request); + } + + private void downloadFailed(ArchiveDownloadRequest request) + { + if (request.Model.Equals(Model.Value)) + attachDownload(null); + } + private ArchiveDownloadRequest attachedRequest; private void attachDownload(ArchiveDownloadRequest request) @@ -126,8 +128,10 @@ namespace osu.Game.Online if (manager != null) { - manager.DownloadBegan -= attachDownload; + manager.DownloadBegan -= downloadBegan; + manager.DownloadFailed -= downloadFailed; manager.ItemAdded -= itemAdded; + manager.ItemRemoved -= itemRemoved; } State.UnbindAll(); From 749a00cc2f324490096fadd5bc3eeee12f13ce81 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 5 Aug 2019 12:49:54 +0300 Subject: [PATCH 112/645] Force bindable change --- osu.Game/Overlays/Profile/Header/Components/RankGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 4818cd8df6..9cb9d48de7 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { base.LoadComplete(); - Statistics.BindValueChanged(statistics => updateStatistics(statistics.NewValue)); + Statistics.BindValueChanged(statistics => updateStatistics(statistics.NewValue), true); } private void updateStatistics(UserStatistics statistics) From 11916782ba9dd82b51ede9cf57e4e36252f05e34 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Aug 2019 19:23:13 +0900 Subject: [PATCH 113/645] Fix drawable channels remaining in memory after being closed --- osu.Game/Overlays/ChatOverlay.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index e223856b27..53a05656b1 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -256,6 +256,9 @@ namespace osu.Game.Overlays loadedChannels.Add(loaded); LoadComponentAsync(loaded, l => { + if (currentChannel.Value != e.NewValue) + return; + loading.Hide(); currentChannelContainer.Clear(false); @@ -381,7 +384,18 @@ namespace osu.Game.Overlays foreach (Channel channel in channels) { ChannelTabControl.RemoveChannel(channel); - loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); + + var loaded = loadedChannels.Find(c => c.Channel == channel); + + if (loaded != null) + { + loadedChannels.Remove(loaded); + + // Because the container is only cleared in the async load callback of a new channel, it is forcefully cleared + // to ensure that the previous channel doesn't get updated after it's disposed + currentChannelContainer.Remove(loaded); + loaded.Dispose(); + } } } From a7ac411c2562e1f774b77111c10abc8ea6667fe8 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 5 Aug 2019 17:57:04 -0700 Subject: [PATCH 114/645] Fix footer button hover sounds playing in unclickable area --- osu.Game/Screens/Select/Footer.cs | 2 +- osu.Game/Screens/Select/FooterButton.cs | 12 ++++++------ osu.Game/Screens/Select/FooterButtonMods.cs | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index 0680711f1c..1dc7081c1c 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Select buttons = new FillFlowContainer { Direction = FillDirection.Horizontal, - Spacing = new Vector2(0.2f, 0), + Spacing = new Vector2(-FooterButton.SHEAR_WIDTH, 0), AutoSizeAxes = Axes.Both, } } diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index e18a086a10..90bc902ad8 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -17,7 +17,9 @@ namespace osu.Game.Screens.Select { public class FooterButton : OsuClickableContainer { - private static readonly Vector2 shearing = new Vector2(0.15f, 0); + public static readonly float SHEAR_WIDTH = 7.5f; + + protected static readonly Vector2 SHEARING = new Vector2(SHEAR_WIDTH / Footer.HEIGHT, 0); public string Text { @@ -59,16 +61,16 @@ namespace osu.Game.Screens.Select private readonly Box box; private readonly Box light; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => box.ReceivePositionalInputAt(screenSpacePos); - public FooterButton() { AutoSizeAxes = Axes.Both; + Shear = SHEARING; Children = new Drawable[] { TextContainer = new Container { - Size = new Vector2(100, 50), + Size = new Vector2(100 - SHEAR_WIDTH, 50), + Shear = -SHEARING, Child = SpriteText = new OsuSpriteText { Anchor = Anchor.Centre, @@ -78,14 +80,12 @@ namespace osu.Game.Screens.Select box = new Box { RelativeSizeAxes = Axes.Both, - Shear = shearing, EdgeSmoothness = new Vector2(2, 0), Colour = Color4.White, Alpha = 0, }, light = new Box { - Shear = shearing, Height = 4, EdgeSmoothness = new Vector2(2, 0), RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index fce4d1b2e2..58d92dbca6 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -32,6 +32,7 @@ namespace osu.Game.Screens.Select { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, + Shear = -SHEARING, Child = modDisplay = new FooterModDisplay { DisplayUnrankedText = false, From cd6fe918821aec9d150311bcc6ac0ec653b672dc Mon Sep 17 00:00:00 2001 From: David Zhao Date: Mon, 5 Aug 2019 19:56:35 +0900 Subject: [PATCH 115/645] Log error for invalid events --- .../Formats/LegacyBeatmapDecoderTest.cs | 17 + osu.Game.Tests/Resources/invalid-events.osu | 1004 +++++++++++++++++ .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 +- .../Formats/LegacyStoryboardDecoder.cs | 3 +- 4 files changed, 1028 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Resources/invalid-events.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index d087251e7e..98464b8d91 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -482,5 +482,22 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(hitObjects[0].Samples[0].Bank, hitObjects[0].Samples[1].Bank); } } + + [Test] + public void TestDecodeInvalidEvents() + { + using (var normalResStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + using (var normalStream = new StreamReader(normalResStream)) + using (var resStream = TestResources.OpenResource("invalid-events.osu")) + using (var stream = new StreamReader(resStream)) + { + var decoder = Decoder.GetDecoder(stream); + var goodBeatmap = decoder.Decode(normalStream); + Beatmap badBeatmap = null; + + Assert.DoesNotThrow(() => badBeatmap = decoder.Decode(stream)); + Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); + } + } } } diff --git a/osu.Game.Tests/Resources/invalid-events.osu b/osu.Game.Tests/Resources/invalid-events.osu new file mode 100644 index 0000000000..a8e767585c --- /dev/null +++ b/osu.Game.Tests/Resources/invalid-events.osu @@ -0,0 +1,1004 @@ +osu file format v14 + +[General] +AudioFilename: 03. Renatus - Soleily 192kbps.mp3 +AudioLeadIn: 0 +PreviewTime: 164471 +Countdown: 0 +SampleSet: Soft +StackLeniency: 0.7 +Mode: 0 +LetterboxInBreaks: 0 +WidescreenStoryboard: 0 + +[Editor] +Bookmarks: 11505,22054,32604,43153,53703,64252,74802,85351,95901,106450,116999,119637,130186,140735,151285,161834,164471,175020,185570,196119,206669,209306 +DistanceSpacing: 1.8 +BeatDivisor: 4 +GridSize: 4 +TimelineZoom: 2 + +[Metadata] +Title:Renatus +TitleUnicode:Renatus +Artist:Soleily +ArtistUnicode:Soleily +Creator:Gamu +Version:Insane +Source: +Tags:MBC7 Unisphere 地球ヤバイEP Chikyu Yabai +BeatmapID:557821 +BeatmapSetID:241526 + +[Difficulty] +HPDrainRate:6.5 +CircleSize:4 +OverallDifficulty:8 +ApproachRate:9 +SliderMultiplier:1.8 +SliderTickRate:2 + +[Events] +bad,event,this,should,fail +//Background and Video events +0,0,"machinetop_background.jpg",0,0 +//Break Periods +2,122474,140135 +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples + +[TimingPoints] +956,329.67032967033,4,2,0,60,1,0 +20736,-100,4,2,0,65,0,0 +22054,-100,4,2,0,70,0,0 +43153,-100,4,2,0,60,0,0 +48428,-100,4,2,0,50,0,0 +52879,-100,4,2,0,50,0,0 +53373,-100,4,2,0,60,0,0 +53703,-100,4,2,0,70,0,1 +74719,-100,4,2,0,70,0,0 +74802,-100,4,2,0,70,0,1 +95901,-100,4,2,0,70,0,0 +116999,-133.333333333333,4,2,0,50,0,0 +117164,-133.333333333333,4,2,0,30,0,0 +117329,-79.9999999999999,4,2,0,50,0,0 +117659,-100,4,2,0,50,0,0 +118977,-100,4,2,0,60,0,0 +119307,-100,4,2,0,70,0,0 +119637,659.340659340659,4,2,0,80,1,0 +119966,-100,4,2,0,70,0,0 +120296,-100,4,2,0,60,0,0 +120626,-100,4,2,0,50,0,0 +120955,-100,4,2,0,40,0,0 +121285,-100,4,2,0,30,0,0 +121615,-100,4,2,0,20,0,0 +121944,-100,4,2,0,10,0,0 +122274,-100,4,2,0,5,0,0 +140735,-100,4,2,0,50,0,0 +151285,-80,4,2,0,60,0,0 +161834,329.67032967033,4,2,0,65,1,0 +164141,-100,4,2,0,70,0,0 +164471,-100,4,2,0,70,0,1 +185487,-100,4,2,0,70,0,0 +185570,-100,4,2,0,70,0,1 +206669,659.340659340659,4,2,0,80,1,0 +206998,-100,4,2,0,70,0,0 +207328,-100,4,2,0,60,0,0 +207658,-100,4,2,0,50,0,0 +207987,-100,4,2,0,40,0,0 +208317,-100,4,2,0,30,0,0 +208647,-100,4,2,0,20,0,0 +208976,-100,4,2,0,10,0,0 +209306,-100,4,2,0,5,0,0 + + +[Colours] +Combo1 : 142,199,255 +Combo2 : 255,128,128 +Combo3 : 128,255,255 +Combo4 : 128,255,128 +Combo5 : 255,187,255 +Combo6 : 255,177,140 +Combo7 : 100,100,100,100 + +[HitObjects] +192,168,956,6,0,P|184:128|200:80,1,90,4|0,1:2|0:0,0:0:0:0: +304,56,1285,1,8,0:0:0:0: +244,236,1450,2,0,P|204:252|156:244,1,90,2|0,0:0|0:0,0:0:0:0: +276,156,1780,2,0,P|310:181|329:226,1,90,2|8,1:2|0:0,0:0:0:0: +300,328,2109,1,2,0:0:0:0: +192,332,2274,6,0,L|144:340,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +388,300,2604,1,8,0:0:0:0: +244,236,2769,1,0,1:0:0:0: +232,208,2851,1,0,0:0:0:0: +224,176,2934,1,0,0:0:0:0: +228,144,3016,1,0,0:0:0:0: +244,116,3098,1,0,1:0:0:0: +332,52,3263,2,0,P|376:48|424:56,1,90,8|0,0:0|0:0,0:0:0:0: +488,228,3593,5,0,1:0:0:0: +460,240,3675,1,0,0:0:0:0: +428,236,3758,1,0,0:0:0:0: +292,160,3923,2,0,P|288:204|300:252,1,90,8|0,0:0|0:0,0:0:0:0: +316,276,4170,1,0,0:0:0:0: +344,292,4252,2,0,L|388:300,1,45,0|0,0:0|0:0,0:0:0:0: +288,356,4417,2,0,L|244:364,1,45,0|0,1:0|0:0,0:0:0:0: +168,328,4582,2,0,P|124:324|72:332,1,90,8|0,0:0|0:0,0:0:0:0: +24,188,4912,5,0,1:0:0:0: +56,192,4994,1,0,0:0:0:0: +88,196,5076,1,0,0:0:0:0: +148,108,5241,1,8,0:0:0:0: +188,240,5406,1,0,1:0:0:0: +188,240,5488,1,0,0:0:0:0: +188,240,5571,2,0,L|168:328,1,90,0|0,0:0|1:0,0:0:0:0: +260,216,5901,2,0,P|236:180|188:164,1,90,8|0,0:0|0:0,0:0:0:0: +248,296,6230,6,0,L|348:292,1,90,0|0,1:0|0:0,0:0:0:0: +504,232,6560,1,8,0:0:0:0: +400,204,6725,1,0,0:0:0:0: +392,176,6807,1,0,0:0:0:0: +384,144,6890,1,0,0:0:0:0: +376,116,6972,1,0,0:0:0:0: +368,88,7054,1,0,1:0:0:0: +188,48,7219,2,0,L|208:140,1,90,8|0,0:0|0:0,0:0:0:0: +248,296,7549,5,0,1:0:0:0: +207,135,7714,1,0,0:0:0:0: +156,232,7879,1,8,0:0:0:0: +316,191,8043,1,0,1:0:0:0: +316,191,8126,1,0,0:0:0:0: +316,191,8208,2,0,L|372:200,1,45,0|0,0:0|0:0,0:0:0:0: +492,200,8373,2,0,L|447:207,1,45,0|0,1:0|0:0,0:0:0:0: +408,136,8538,2,0,P|396:92|400:48,1,90,8|0,0:0|0:0,0:0:0:0: +260,32,8868,5,0,1:0:0:0: +252,64,8950,1,0,0:0:0:0: +236,92,9032,2,0,P|204:116|148:128,1,90,0|8,0:0|0:0,0:0:0:0: +28,188,9362,1,0,0:0:0:0: +60,196,9445,1,0,0:0:0:0: +88,212,9527,2,0,P|112:244|124:300,1,90,0|0,0:0|1:0,0:0:0:0: +112,128,9857,2,0,P|152:156|184:196,1,90,8|0,0:0|0:0,0:0:0:0: +216,288,10186,5,0,1:0:0:0: +216,288,10269,1,0,0:0:0:0: +216,288,10351,1,0,0:0:0:0: +268,192,10516,1,8,0:0:0:0: +356,128,10681,1,0,1:0:0:0: +388,120,10763,1,0,0:0:0:0: +420,128,10846,2,0,P|440:168|436:220,1,90,0|0,0:0|1:0,0:0:0:0: +332,328,11175,2,0,L|280:332,1,45,8|8,0:0|0:0,0:0:0:0: +216,288,11340,2,0,L|164:292,1,45,0|0,1:0|0:0,1:0:0:0: +100,248,11505,5,4,1:2:0:0: +148,116,11670,1,2,0:0:0:0: +268,192,11835,1,10,0:0:0:0: +136,328,11999,2,0,L|44:336,1,90,2|0,0:0|0:0,0:0:0:0: +216,288,12329,1,2,1:2:0:0: +148,116,12494,1,10,0:0:0:0: +100,248,12659,1,2,0:0:0:0: +268,192,12824,5,0,1:0:0:0: +268,192,12906,1,0,0:0:0:0: +268,192,12988,1,0,0:0:0:0: +340,272,13153,2,0,P|384:276|432:264,1,90,8|0,0:0|1:0,0:0:0:0: +452,244,13401,1,0,0:0:0:0: +468,216,13483,2,0,L|476:124,1,90,0|0,0:0|1:0,0:0:0:0: +368,32,13813,2,0,L|360:121,1,90,8|0,0:0|0:0,0:0:0:0: +340,272,14142,6,0,L|316:316,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +452,244,14472,1,8,0:0:0:0: +268,192,14637,1,0,0:0:0:0: +236,188,14719,1,0,0:0:0:0: +204,192,14802,2,0,P|172:228|160:272,1,90,0|0,0:0|1:0,0:0:0:0: +128,140,15131,2,0,P|160:104|172:60,1,90,8|0,0:0|0:0,0:0:0:0: +64,52,15461,6,0,L|20:68,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +171,64,15791,1,8,0:0:0:0: +264,8,15956,2,0,L|356:12,1,90,0|0,1:0|0:0,0:0:0:0: +452,56,16285,1,0,1:0:0:0: +296,140,16450,2,0,L|206:136,1,90,8|0,0:0|0:0,0:0:0:0: +108,184,16780,6,0,P|92:224|96:272,1,90,0|0,1:0|0:0,0:0:0:0: +200,244,17109,1,8,0:0:0:0: +108,108,17274,2,0,L|12:116,1,90,0|0,0:0|0:0,0:0:0:0: +200,244,17604,1,0,1:0:0:0: +296,140,17769,2,0,L|385:132,1,90,8|0,0:0|0:0,0:0:0:0: +480,184,18098,5,0,1:0:0:0: +488,216,18181,1,0,0:0:0:0: +496,248,18263,2,0,L|492:340,1,90,0|8,0:0|0:0,0:0:0:0: +404,224,18593,2,0,L|396:176,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +304,264,18923,1,0,1:0:0:0: +200,244,19087,2,0,P|156:240|108:248,1,90,8|0,0:0|0:0,0:0:0:0: +296,140,19417,6,0,P|340:144|388:136,1,90,0|0,1:0|0:0,0:0:0:0: +440,44,19747,1,8,0:0:0:0: +404,224,19912,1,0,0:0:0:0: +404,224,19994,1,0,0:0:0:0: +404,224,20076,2,0,L|412:320,1,90,0|0,0:0|1:0,0:0:0:0: +200,244,20406,2,0,L|192:154,1,90,8|0,0:0|0:0,0:0:0:0: +184,44,20736,5,4,1:2:0:0: +152,40,20818,1,0,0:0:0:0: +120,48,20901,1,0,0:0:0:0: +96,68,20983,1,0,0:0:0:0: +76,92,21065,1,2,0:3:0:0: +64,120,21148,1,0,0:0:0:0: +60,152,21230,1,0,1:0:0:0: +64,184,21313,1,0,0:0:0:0: +76,212,21395,2,0,L|96:252,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +144,316,21725,2,0,L|188:324,3,45,0|0|2|0,0:0|0:0|0:3|0:0,0:0:0:0: +268,340,22054,6,0,L|364:336,1,90,4|0,1:2|0:0,0:0:0:0: +452,280,22384,1,8,0:0:0:0: +512,188,22549,2,0,P|516:144|504:96,1,90,2|0,0:0|0:0,0:0:0:0: +340,24,22879,2,0,P|336:68|348:116,1,90,2|8,1:2|0:0,0:0:0:0: +420,192,23208,1,2,0:0:0:0: +328,252,23373,6,0,L|232:240,1,90,0|0,1:0|0:0,0:0:0:0: +64,256,23703,1,8,0:0:0:0: +144,184,23868,2,0,P|148:140|136:88,1,90,0|0,1:0|0:0,0:0:0:0: +40,52,24197,1,2,1:2:0:0: +139,95,24362,1,8,0:0:0:0: +216,20,24527,1,0,0:0:0:0: +315,63,24692,6,0,P|360:72|408:68,1,90,2|0,1:2|0:0,0:0:0:0: +492,132,25021,1,8,0:0:0:0: +412,204,25186,2,0,P|403:249|407:297,1,90,2|0,0:0|0:0,0:0:0:0: +268,328,25516,2,0,P|277:283|273:235,1,90,2|8,1:2|0:0,0:0:0:0: +232,140,25846,2,0,P|187:131|139:135,1,90,2|0,0:0|1:0,0:0:0:0: +64,208,26175,5,2,0:0:0:0: +44,316,26340,1,8,0:0:0:0: +148,280,26505,1,2,1:2:0:0: +456,208,26835,1,2,1:2:0:0: +476,316,26999,1,10,0:0:0:0: +372,280,27164,1,2,0:0:0:0: +356,172,27329,6,0,L|380:80,1,90,0|0,1:0|0:0,0:0:0:0: +456,208,27659,1,8,0:0:0:0: +300,236,27824,1,2,0:0:0:0: +300,236,27906,1,0,0:0:0:0: +300,236,27988,2,0,L|208:228,1,90,0|2,0:0|1:2,0:0:0:0: +140,312,28318,1,8,0:0:0:0: +372,280,28483,2,0,L|464:272,1,90,2|0,0:0|1:0,0:0:0:0: +500,136,28813,5,2,0:0:0:0: +432,56,28977,1,8,0:0:0:0: +328,24,29142,2,0,P|284:24|236:28,1,90,2|0,1:2|0:0,0:0:0:0: +80,144,29472,1,2,1:2:0:0: +116,44,29637,1,10,0:0:0:0: +184,128,29802,1,2,0:0:0:0: +20,88,29966,6,0,P|1:164|73:227,1,180,2|10,1:2|0:0,0:0:0:0: +184,128,30461,2,0,P|227:120|276:124,1,90,2|0,0:0|0:0,0:0:0:0: +392,188,30791,1,2,1:2:0:0: +272,260,30956,1,8,0:0:0:0: +396,328,31120,1,0,0:0:0:0: +256,348,31285,5,2,1:2:0:0: +224,344,31368,1,0,1:0:0:0: +192,340,31450,2,0,L|172:248,1,90,2|0,1:2|1:0,0:0:0:0: +8,136,31780,2,0,L|27:223,1,90,2|0,1:2|0:0,0:0:0:0: +56,328,32109,1,2,1:2:0:0: +108,192,32274,1,2,1:2:0:0: +100,160,32357,1,0,1:0:0:0: +92,132,32439,1,2,1:2:0:0: +84,104,32521,1,0,1:0:0:0: +76,72,32604,6,0,P|100:112|148:136,1,90,4|0,1:2|0:0,0:0:0:0: +240,168,32934,1,8,0:0:0:0: +336,124,33098,2,0,L|344:80,2,45,2|0|0,0:0|0:0|0:0,0:0:0:0: +264,248,33428,2,0,P|220:248|176:220,1,90,2|8,1:2|0:0,0:0:0:0: +260,84,33758,1,2,0:0:0:0: +344,212,33923,5,0,1:0:0:0: +344,212,34005,1,0,0:0:0:0: +344,212,34087,1,0,0:0:0:0: +440,160,34252,1,8,0:0:0:0: +312,320,34417,2,0,P|272:336|220:324,1,90,0|0,1:0|0:0,0:0:0:0: +156,176,34747,2,0,P|196:160|248:172,2,90,2|8|0,1:2|0:0|0:0,0:0:0:0: +132,280,35241,5,2,1:2:0:0: +132,280,35324,1,0,0:0:0:0: +132,280,35406,2,0,L|120:376,1,90,0|8,0:0|0:0,0:0:0:0: +312,320,35736,2,0,L|300:230,1,90,2|0,0:0|0:0,0:0:0:0: +316,124,36065,1,2,1:2:0:0: +400,192,36230,1,8,0:0:0:0: +300,230,36395,2,0,P|255:231|211:224,1,90,2|0,0:0|1:0,0:0:0:0: +24,132,36725,5,0,0:0:0:0: +132,152,36890,1,8,0:0:0:0: +60,232,37054,1,2,1:2:0:0: +60,232,37137,1,0,0:0:0:0: +60,232,37219,1,0,0:0:0:0: +92,56,37384,2,0,L|184:44,1,90,2|10,1:2|0:0,0:0:0:0: +316,124,37714,2,0,L|226:135,1,90,2|0,0:0|1:0,0:0:0:0: +60,232,38043,6,0,P|52:276|64:328,1,90,0|8,0:0|0:0,0:0:0:0: +220,152,38373,2,0,P|176:144|124:156,1,90,2|0,0:0|0:0,0:0:0:0: +176,252,38703,1,2,1:2:0:0: +323,213,38868,2,0,L|316:124,1,90,8|2,0:0|0:0,0:0:0:0: +332,320,39197,5,0,1:0:0:0: +424,260,39362,1,2,0:0:0:0: +260,272,39527,2,0,P|246:313|256:360,1,90,8|2,0:0|1:2,0:0:0:0: +408,336,39857,1,0,0:0:0:0: +176,252,40021,2,0,L|80:260,2,90,2|10|2,1:2|0:0|0:0,0:0:0:0: +324,212,40516,5,2,1:2:0:0: +324,212,40598,1,0,1:0:0:0: +324,212,40681,1,0,1:0:0:0: +200,336,40846,1,2,1:2:0:0: +236,188,41010,1,2,1:2:0:0: +236,188,41093,1,0,1:0:0:0: +236,188,41175,1,0,1:0:0:0: +281,357,41340,1,2,1:2:0:0: +176,252,41505,1,2,1:2:0:0: +176,252,41587,1,0,1:0:0:0: +176,252,41670,1,0,1:0:0:0: +344,297,41835,5,2,1:2:0:0: +432,232,41999,1,2,1:2:0:0: +444,204,42082,1,0,1:0:0:0: +448,172,42164,1,0,1:0:0:0: +444,140,42247,1,0,1:0:0:0: +432,112,42329,2,0,L|440:64,2,45,2|0|0,1:2|1:0|1:0,0:0:0:0: +236,188,42659,1,0,0:0:0:0: +340,172,42824,1,2,0:3:0:0: +272,88,42988,1,0,0:0:0:0: +132,160,43153,6,0,P|148:248|220:296,1,180,4|8,1:2|0:0,0:0:0:0: +324,320,43648,2,0,L|336:364,2,45,0|0|0,0:0|0:0|0:0,0:0:0:0: +292,216,43977,1,0,1:0:0:0: +396,240,44142,2,0,P|440:244|488:232,1,90,8|0,0:0|0:0,0:0:0:0: +328,124,44472,6,0,P|284:120|236:132,1,90,0|0,1:0|0:0,0:0:0:0: +168,212,44802,1,8,0:0:0:0: +192,316,44966,1,0,1:0:0:0: +140,220,45131,1,0,0:0:0:0: +83,310,45296,1,0,1:0:0:0: +114,205,45461,1,8,0:0:0:0: +10,229,45626,1,0,0:0:0:0: +106,176,45791,6,0,P|113:133|108:85,1,90,0|0,1:0|0:0,0:0:0:0: +204,136,46120,1,8,0:0:0:0: +256,40,46285,1,0,0:0:0:0: +256,40,46368,1,0,0:0:0:0: +256,40,46450,2,0,L|356:44,1,90,0|0,0:0|1:0,0:0:0:0: +501,124,46780,2,0,L|412:128,1,90,8|0,0:0|0:0,0:0:0:0: +324,192,47109,5,0,1:0:0:0: +356,296,47274,1,0,0:0:0:0: +284,216,47439,1,8,0:0:0:0: +269,323,47604,1,0,1:0:0:0: +237,220,47769,1,0,0:0:0:0: +178,311,47934,1,0,1:0:0:0: +191,203,48098,1,8,0:0:0:0: +99,261,48263,1,0,0:0:0:0: +156,168,48428,6,0,B|176:112|136:64|136:64|200:96,1,180,4|8,1:2|0:0,0:0:0:0: +300,124,48923,2,0,L|392:120,1,90,0|0,0:0|0:0,0:0:0:0: +468,48,49252,1,0,1:0:0:0: +390,120,49417,2,0,P|390:164|406:208,1,90,8|0,0:0|0:0,0:0:0:0: +352,344,49747,6,0,P|352:300|336:256,1,90,4|0,1:2|0:0,0:0:0:0: +240,208,50076,1,8,0:0:0:0: +163,320,50241,2,0,P|207:324|252:316,1,90,0|0,1:0|0:0,0:0:0:0: +240,208,50571,1,0,1:0:0:0: +76,296,50736,2,0,P|76:340|92:384,1,90,8|0,0:0|0:0,0:0:0:0: +312,164,51065,6,0,P|236:124|160:184,1,180,4|8,1:2|0:0,0:0:0:0: +247,297,51560,2,0,L|240:208,1,90,0|0,0:0|0:0,0:0:0:0: +224,48,51890,1,0,1:0:0:0: +332,56,52054,2,0,L|366:58,5,30,8|0|0|0|0|0,0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0: +408,64,52384,6,0,P|420:108|416:156,1,90,0|0,1:0|0:0,0:0:0:0: +360,260,52714,1,8,0:0:0:0: +247,297,52879,2,0,B|203:281|159:297|159:297|115:313|71:297,1,180,0|0,1:0|1:0,0:0:0:0: +116,196,53373,1,8,0:0:0:0: +120,164,53456,1,0,0:0:0:0: +124,132,53538,1,0,0:0:0:0: +128,100,53620,1,0,0:0:0:0: +132,68,53703,5,4,1:2:0:0: +40,136,53868,1,0,0:0:0:0: +204,160,54032,2,0,L|304:152,1,90,8|0,0:0|0:0,0:0:0:0: +408,64,54362,1,0,0:0:0:0: +408,64,54445,1,0,0:0:0:0: +408,64,54527,2,0,P|404:112|416:160,1,90,0|8,1:0|0:0,0:0:0:0: +484,236,54857,1,0,0:0:0:0: +428,328,55021,5,0,1:0:0:0: +328,296,55186,1,0,0:0:0:0: +328,296,55269,1,0,0:0:0:0: +328,296,55351,1,8,0:0:0:0: +416,300,55516,1,0,1:0:0:0: +472,208,55681,1,0,0:0:0:0: +316,268,55846,1,0,1:0:0:0: +460,180,56010,1,8,0:0:0:0: +304,240,56175,1,0,0:0:0:0: +404,272,56340,5,0,1:0:0:0: +448,152,56505,1,0,0:0:0:0: +448,152,56587,1,0,0:0:0:0: +448,152,56670,2,0,P|456:112|448:60,1,90,8|0,0:0|0:0,0:0:0:0: +268,28,56999,2,0,P|260:68|268:120,1,90,0|0,0:0|1:0,0:0:0:0: +404,272,57329,2,0,P|444:280|496:272,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: +304,240,57824,5,0,0:0:0:0: +252,336,57988,1,8,0:0:0:0: +196,244,58153,1,0,1:0:0:0: +24,256,58318,1,0,0:0:0:0: +116,200,58483,1,0,1:0:0:0: +136,60,58648,1,8,0:0:0:0: +192,152,58813,1,0,0:0:0:0: +304,240,58977,6,0,P|348:252|396:248,1,90,0|0,1:0|0:0,0:0:0:0: +456,116,59307,2,0,P|412:104|364:108,1,90,8|0,0:0|0:0,0:0:0:0: +273,161,59637,1,0,0:0:0:0: +136,60,59802,1,0,1:0:0:0: +192,152,59966,1,8,0:0:0:0: +23,177,60131,1,0,0:0:0:0: +129,203,60296,5,0,1:0:0:0: +88,304,60461,2,0,P|132:311|176:303,1,90,0|8,0:0|0:0,0:0:0:0: +304,240,60791,1,0,1:0:0:0: +304,240,60873,1,0,0:0:0:0: +304,240,60956,2,0,L|312:288,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +384,256,61285,2,0,L|392:304,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +464,272,61615,5,2,1:2:0:0: +488,168,61780,1,2,0:0:0:0: +428,80,61945,1,10,0:0:0:0: +332,32,62109,2,0,P|288:28|240:36,1,90,2|0,0:0|0:0,0:0:0:0: +28,216,62439,1,2,1:2:0:0: +88,304,62604,1,10,0:0:0:0: +184,352,62769,2,0,P|228:356|276:348,1,90,2|0,0:0|1:0,0:0:0:0: +384,256,63098,6,0,P|409:219|426:174,1,90,2|8,0:0|0:0,0:0:0:0: +428,80,63428,2,0,L|420:36,2,45,2|0|0,1:2|0:0|0:0,0:0:0:0: +456,288,63758,1,2,1:2:0:0: +324,200,63923,1,10,1:2:0:0: +292,204,64005,1,0,1:0:0:0: +260,208,64087,1,2,1:2:0:0: +228,212,64170,1,0,1:0:0:0: +196,216,64252,5,4,1:2:0:0: +104,160,64417,1,0,0:0:0:0: +228,296,64582,2,0,L|320:284,1,90,8|0,0:0|0:0,0:0:0:0: +344,112,64912,1,0,0:0:0:0: +344,112,64994,1,0,0:0:0:0: +344,112,65076,2,0,L|254:123,1,90,0|8,1:0|0:0,0:0:0:0: +144,284,65406,2,0,P|148:328|176:364,1,90,0|0,0:0|1:0,0:0:0:0: +196,216,65736,5,0,0:0:0:0: +196,216,65818,1,0,0:0:0:0: +196,216,65901,2,0,P|155:198|110:205,1,90,8|0,0:0|1:0,0:0:0:0: +36,284,66230,1,0,0:0:0:0: +4,180,66395,1,0,1:0:0:0: +132,24,66560,1,8,0:0:0:0: +100,128,66725,1,0,0:0:0:0: +24,48,66890,5,0,1:0:0:0: +212,108,67054,1,0,0:0:0:0: +212,108,67137,1,0,0:0:0:0: +212,108,67219,2,0,L|300:92,1,90,8|0,0:0|0:0,0:0:0:0: +472,144,67549,2,0,L|384:160,1,90,0|0,0:0|1:0,0:0:0:0: +196,216,67879,2,0,P|240:216|288:240,1,90,8|0,0:0|0:0,0:0:0:0: +324,336,68208,5,0,1:0:0:0: +144,288,68373,1,0,0:0:0:0: +58,170,68538,1,8,0:0:0:0: +196,215,68703,1,0,1:0:0:0: +58,260,68868,1,0,0:0:0:0: +144,142,69032,2,0,L|138:108,2,30,0|0|0,1:0|0:0|0:0,0:0:0:0: +144,142,69197,2,0,P|184:124|232:132,1,90,8|0,0:0|0:0,0:0:0:0: +312,248,69527,6,0,L|324:338,1,90,0|0,1:0|0:0,0:0:0:0: +436,248,69857,1,8,0:0:0:0: +432,216,69939,1,0,0:0:0:0: +428,184,70021,1,0,0:0:0:0: +328,120,70186,1,0,0:0:0:0: +324,152,70269,1,0,0:0:0:0: +320,184,70351,1,0,1:0:0:0: +316,216,70434,1,0,0:0:0:0: +312,248,70516,2,0,L|320:300,1,45,8|0,0:0|0:0,0:0:0:0: +244,340,70681,2,0,L|237:295,1,45,0|0,0:0|0:0,0:0:0:0: +216,224,70846,6,0,P|168:216|124:224,1,90,0|0,1:0|0:0,0:0:0:0: +40,288,71175,1,8,0:0:0:0: +2,95,71340,2,0,P|-4:139|4:184,1,90,0|0,1:0|0:0,0:0:0:0: +164,304,71670,1,0,1:0:0:0: +312,248,71835,1,8,0:0:0:0: +244,340,71999,1,0,0:0:0:0: +216,224,72164,6,0,L|228:132,1,90,0|0,1:0|0:0,0:0:0:0: +332,148,72494,2,0,L|344:56,1,90,8|0,0:0|0:0,0:0:0:0: +312,248,72824,1,0,0:0:0:0: +164,304,72988,1,0,1:0:0:0: +332,336,73153,1,8,0:0:0:0: +360,324,73236,1,0,0:0:0:0: +384,304,73318,1,0,0:0:0:0: +399,276,73401,1,0,0:0:0:0: +403,244,73483,6,0,L|396:200,3,45,4|0|2|0,1:2|0:0|0:0|1:0,0:0:0:0: +420,112,73813,2,0,L|427:68,3,45,2|0|2|0,1:2|0:0|1:2|0:0,0:0:0:0: +352,16,74142,2,0,L|345:60,3,45,0|0|2|0,0:0|1:0|1:2|0:0,0:0:0:0: +332,148,74472,1,2,1:2:0:0: +332,148,74554,1,0,1:0:0:0: +332,148,74637,1,2,1:2:0:0: +332,148,74719,1,0,1:0:0:0: +332,148,74802,6,0,P|360:216|320:312,1,180,4|2,1:2|0:3,0:0:0:0: +190,310,75296,2,0,P|151:231|180:148,1,180,4|0,1:2|0:0,0:0:0:0: +256,56,75791,1,0,0:0:0:0: +332,148,75956,1,2,0:3:0:0: +179,148,76120,5,4,1:2:0:0: +336,64,76285,1,4,1:2:0:0: +256,224,76450,1,2,0:3:0:0: +176,64,76615,1,4,1:2:0:0: +256,140,76780,2,0,L|256:324,1,180,2|0,0:0|0:0,0:0:0:0: +364,300,77274,1,2,0:3:0:0: +148,300,77439,6,0,P|104:316|76:356,1,90,4|0,1:2|0:0,0:0:0:0: +24,252,77769,2,0,L|16:208,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +96,212,78098,2,0,L|104:168,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +32,128,78428,2,0,L|24:84,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +104,88,78758,5,2,1:2:0:0: +204,132,78923,1,0,0:0:0:0: +236,124,79005,1,0,0:0:0:0: +268,116,79087,2,0,L|280:68,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +348,100,79417,2,0,L|360:52,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +428,84,79747,1,8,1:2:0:0: +460,76,79829,1,0,1:0:0:0: +492,68,79912,1,0,1:0:0:0: +492,260,80076,6,0,P|400:248|328:296,1,180,4|2,1:2|0:3,0:0:0:0: +144,236,80571,2,0,P|236:248|308:200,1,180,4|0,1:2|0:0,0:0:0:0: +348,100,81065,2,0,P|348:56|336:8,1,90,0|2,0:0|0:3,0:0:0:0: +140,48,81395,5,4,1:2:0:0: +244,68,81560,1,4,1:2:0:0: +144,236,81725,1,2,0:3:0:0: +176,133,81890,1,4,1:2:0:0: +184,304,82054,2,0,P|100:300|68:220,1,180,2|0,0:0|0:0,0:0:0:0: +100,116,82549,1,2,0:3:0:0: +264,244,82714,6,0,L|272:340,1,90,4|0,1:2|0:0,0:0:0:0: +380,316,83043,1,8,0:0:0:0: +396,288,83126,1,0,0:0:0:0: +400,256,83208,1,0,0:0:0:0: +396,224,83291,1,0,0:0:0:0: +380,196,83373,2,0,L|336:176,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +272,148,83703,1,8,0:0:0:0: +256,120,83785,1,0,0:0:0:0: +252,88,83868,1,0,0:0:0:0: +256,56,83950,1,0,0:0:0:0: +272,28,84032,6,0,L|316:8,3,45,2|0|0|0,1:2|0:0|0:0|0:0,0:0:0:0: +360,72,84362,2,0,L|408:72,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +421,149,84692,2,0,L|464:169,3,45,2|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +443,244,85021,2,0,L|473:281,3,45,8|0|0|0,1:2|1:0|0:0|0:0,0:0:0:0: +422,339,85351,6,0,L|240:348,1,180,4|2,1:2|0:3,0:0:0:0: +76,172,85846,2,0,L|255:163,1,180,4|0,1:2|0:0,0:0:0:0: +421,149,86340,2,0,P|435:107|428:56,1,90,0|2,0:0|0:3,0:0:0:0: +228,56,86670,5,4,1:2:0:0: +280,192,86835,1,4,1:2:0:0: +328,96,86999,1,2,0:3:0:0: +180,152,87164,1,4,1:2:0:0: +28,100,87330,2,0,P|16:56|20:8,1,90,2|0,0:0|0:0,0:0:0:0: +0,180,87659,1,0,0:0:0:0: +28,284,87824,1,2,0:3:0:0: +108,352,87988,6,0,P|152:360|196:356,1,90,4|0,1:2|0:0,0:0:0:0: +276,284,88318,1,8,0:0:0:0: +304,272,88401,1,0,0:0:0:0: +336,268,88483,1,0,0:0:0:0: +368,272,88565,1,0,0:0:0:0: +396,284,88648,2,0,L|432:312,1,45,0|0,0:0|0:0,0:0:0:0: +488,252,88813,2,0,L|452:224,1,45,0|0,1:0|0:0,0:0:0:0: +400,164,88977,2,0,L|396:116,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +316,64,89307,6,0,L|320:160,1,90,2|0,1:2|0:0,0:0:0:0: +276,284,89637,1,8,0:0:0:0: +248,296,89719,1,0,0:0:0:0: +216,300,89802,1,0,1:0:0:0: +184,296,89884,1,0,0:0:0:0: +156,284,89966,2,0,L|120:256,1,45,0|0,0:0|0:0,0:0:0:0: +176,200,90131,2,0,L|140:172,1,45,0|0,1:0|0:0,0:0:0:0: +196,116,90296,2,0,L|160:88,3,45,8|0|0|0,1:2|1:0|1:0|0:0,0:0:0:0: +92,44,90626,6,0,P|48:44|24:160,1,180,4|2,1:2|0:3,0:0:0:0: +156,284,91120,2,0,B|200:300|244:284|244:284|288:268|332:284,1,180,4|0,1:2|0:0,0:0:0:0: +176,200,91615,2,0,P|176:156|196:116,1,90,0|2,0:0|0:3,0:0:0:0: +264,28,91945,6,0,L|353:39,1,90,4|0,1:2|1:0,0:0:0:0: +453,159,92274,2,0,L|364:148,1,90,2|4,0:3|1:2,0:0:0:0: +268,196,92604,2,0,P|260:268|328:348,1,180,2|0,0:0|0:0,0:0:0:0: +364,248,93098,1,2,0:3:0:0: +176,200,93263,5,4,1:2:0:0: +72,228,93428,1,0,1:0:0:0: +152,92,93593,1,0,1:0:0:0: +256,64,93758,1,0,1:0:0:0: +336,200,93923,5,0,1:0:0:0: +440,228,94087,1,0,1:0:0:0: +360,92,94252,1,0,1:0:0:0: +256,64,94417,1,0,1:0:0:0: +176,200,94582,5,2,1:2:0:0: +168,228,94664,1,0,1:0:0:0: +168,260,94747,1,0,1:0:0:0: +172,292,94829,1,0,1:0:0:0: +192,316,94912,1,0,1:0:0:0: +220,328,94994,1,0,1:0:0:0: +252,332,95076,1,0,1:0:0:0: +280,320,95159,1,0,1:0:0:0: +300,296,95241,2,0,L|308:248,3,45,2|0|0|0,1:2|1:0|1:0|1:0,0:0:0:0: +312,172,95571,2,0,L|304:127,3,45,0|0|0|0,1:0|1:0|1:0|1:0,0:0:0:0: +256,64,95901,6,0,P|208:56|164:60,1,90,4|0,1:2|0:0,0:0:0:0: +76,116,96230,1,8,0:0:0:0: +60,224,96395,1,0,0:0:0:0: +60,224,96477,1,0,0:0:0:0: +160,184,96642,1,0,0:0:0:0: +160,184,96725,1,0,1:0:0:0: +63,26,96890,2,0,L|76:116,1,90,8|0,0:0|0:0,0:0:0:0: +136,272,97219,5,0,1:0:0:0: +168,268,97302,1,0,0:0:0:0: +200,264,97384,1,0,0:0:0:0: +232,260,97466,1,0,0:0:0:0: +264,256,97549,1,8,0:0:0:0: +384,136,97714,1,0,1:0:0:0: +376,168,97796,1,0,0:0:0:0: +380,200,97879,1,0,0:0:0:0: +392,228,97961,1,0,0:0:0:0: +416,248,98043,2,0,P|464:260|512:260,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +231,105,98538,6,0,L|188:116,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +376,56,98868,2,0,L|420:64,1,45,8|0,0:0|0:0,0:0:0:0: +384,136,99032,1,0,0:0:0:0: +384,136,99115,2,0,P|340:128|304:92,1,90,0|0,0:0|0:0,0:0:0:0: +303,18,99362,2,0,L|207:26,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +452,88,99857,5,0,1:0:0:0: +465,116,99939,1,0,0:0:0:0: +466,147,100021,1,0,0:0:0:0: +456,177,100104,1,0,0:0:0:0: +436,201,100186,2,0,P|416:213|389:216,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +320,188,100516,2,0,P|300:176|273:173,3,45,0|0|0|0,0:0|1:0|1:0|0:0,0:0:0:0: +204,200,100846,2,0,P|192:220|189:247,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +188,320,101175,6,0,P|143:322|100:310,1,90,0|0,1:0|0:0,0:0:0:0: +76,292,101423,1,0,0:0:0:0: +76,292,101505,1,8,0:0:0:0: +76,292,101587,2,0,L|72:248,1,45 +12,68,101835,2,0,L|6:24,2,45,0|0|0,0:0|0:0|1:0,0:0:0:0: +104,140,102164,2,0,L|171:132,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +224,124,102494,6,0,P|236:164|232:216,1,90,0|0,1:0|0:0,0:0:0:0: +288,296,102824,1,8,0:0:0:0: +288,296,102906,1,0,0:0:0:0: +288,296,102988,2,0,P|328:284|380:288,1,90,0|0,1:0|0:0,0:0:0:0: +404,304,103236,1,0,0:0:0:0: +424,328,103318,1,0,1:0:0:0: +448,188,103483,2,0,L|440:140,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +424,72,103813,5,0,1:0:0:0: +324,112,103977,1,0,0:0:0:0: +324,112,104060,1,0,0:0:0:0: +324,112,104142,2,0,P|280:116|232:104,1,90,8|0,0:0|0:0,0:0:0:0: +160,28,104472,1,0,0:0:0:0: +216,208,104637,1,0,1:0:0:0: +216,208,104719,1,0,0:0:0:0: +216,208,104802,1,8,0:0:0:0: +352,240,104966,1,0,0:0:0:0: +384,244,105049,1,0,0:0:0:0: +416,248,105131,6,0,L|460:240,4,45,0|0|0|0|8,1:0|0:0|0:0|0:0|0:0,0:0:0:0: +272,288,105626,1,0,1:0:0:0: +264,320,105708,1,0,0:0:0:0: +256,352,105791,2,0,L|204:356,5,30,0|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: +156,332,106120,2,0,L|104:336,5,30,8|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: +56,312,106450,5,4,1:2:0:0: +4,188,106615,1,0,0:0:0:0: +168,220,106780,2,0,P|127:232|79:228,1,90,8|0,0:0|0:0,0:0:0:0: +112,124,107109,1,0,0:0:0:0: +272,216,107274,2,0,L|264:316,1,90,0|8,1:0|0:0,0:0:0:0: +400,268,107604,1,0,0:0:0:0: +428,132,107769,5,0,1:0:0:0: +428,132,107851,1,0,0:0:0:0: +428,132,107934,1,0,0:0:0:0: +428,132,108016,1,0,0:0:0:0: +428,132,108098,1,8,0:0:0:0: +332,84,108263,2,0,P|288:80|232:88,1,90,0|0,1:0|0:0,0:0:0:0: +112,124,108593,1,0,1:0:0:0: +148,264,108758,1,8,0:0:0:0: +16,236,108923,1,0,0:0:0:0: +264,126,109087,6,0,L|272:216,1,90,0|0,1:0|0:0,0:0:0:0: +452,224,109417,2,0,L|460:320,1,90,8|0,0:0|0:0,0:0:0:0: +360,232,109747,1,0,0:0:0:0: +348,56,109912,1,0,1:0:0:0: +416,140,110076,1,8,0:0:0:0: +256,112,110241,2,0,P|212:120|160:112,1,90,0|0,0:0|1:0,0:0:0:0: +348,56,110571,6,0,L|331:150,1,90,0|8,0:0|0:0,0:0:0:0: +208,328,110901,2,0,L|191:239,1,90,0|0,1:0|0:0,0:0:0:0: +184,216,111148,1,0,1:0:0:0: +178,194,111230,1,0,1:0:0:0: +68,272,111395,1,8,0:0:0:0: +56,136,111560,1,0,1:0:0:0: +178,194,111725,6,0,P|219:203|267:199,1,90,4|0,1:2|0:0,0:0:0:0: +364,148,112054,1,8,0:0:0:0: +384,256,112219,2,0,P|406:291|443:322,1,90,0|0,0:0|0:0,0:0:0:0: +488,224,112549,1,0,1:0:0:0: +304,232,112714,2,0,L|208:224,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: +208,328,113208,6,0,L|112:320,1,90,0|8,0:0|0:0,0:0:0:0: +26,184,113538,2,0,L|116:192,1,90,0|0,1:0|0:0,0:0:0:0: +304,232,113868,1,0,1:0:0:0: +116,192,114032,1,8,0:0:0:0: +224,132,114197,1,0,0:0:0:0: +208,328,114362,6,0,B|272:360|320:312|320:312|340:368,1,180,4|8,1:2|0:0,0:0:0:0: +304,232,114857,2,0,P|300:184|308:140,1,90,0|0,0:0|0:0,0:0:0:0: +384,64,115186,1,0,1:0:0:0: +307,143,115351,1,8,0:0:0:0: +256,48,115516,1,0,0:0:0:0: +456,24,115681,6,0,B|482:101|420:136|420:136|440:184,1,180,4|8,1:2|0:0,0:0:0:0: +384,64,116175,2,0,P|340:56|296:64,1,90,0|0,1:0|0:0,0:0:0:0: +211,171,116505,1,0,1:0:0:0: +439,181,116670,2,0,L|448:84,1,90,8|0,0:0|0:0,0:0:0:0: +372,296,116999,6,2,L|304:292,1,67.5000025749208,2|0,0:1|0:0,0:0:0:0: +136,252,117329,6,2,P|196:260|212:172,1,168.75,0|0,0:0|0:0,0:0:0:0: +192,148,117659,1,2,0:3:0:0: +164,132,117741,1,2,0:3:0:0: +132,124,117824,1,2,1:3:0:0: +100,132,117906,1,2,0:3:0:0: +72,148,117988,2,0,L|52:56,1,90,2|8,0:3|0:0,0:0:0:0: +36,244,118318,5,0,1:0:0:0: +76,344,118483,1,0,1:0:0:0: +184,352,118648,1,0,1:0:0:0: +244,264,118813,1,0,1:0:0:0: +244,264,118895,1,0,1:0:0:0: +244,264,118977,2,0,L|288:260,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +332,328,119307,2,0,L|376:324,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +412,252,119637,5,4,1:2:0:0: +256,192,119719,12,0,122274,0:0:0:0: +256,192,140735,6,0,L|228:156,1,45,4|0,1:2|0:0,0:0:0:0: +152,132,141065,2,0,P|129:129|104:136,1,45 +48,192,141395,2,0,P|40:236|52:280,1,90,8|8,0:0|0:0,0:0:0:0: +196,352,142054,6,0,L|308:340,1,90,8|8,0:0|1:2,0:0:0:0: +336,280,142549,1,0,0:0:0:0: +404,324,142713,1,8,0:0:0:0: +404,324,142878,1,8,0:0:0:0: +292,120,143373,5,0,1:0:0:0: +212,104,143538,1,0,0:0:0:0: +140,140,143702,1,0,0:0:0:0: +120,220,143867,1,0,0:0:0:0: +144,296,144032,2,0,P|184:320|228:316,1,90,10|8,0:0|0:0,0:0:0:0: +372,212,144691,6,0,P|327:209|290:232,1,90,10|8,0:0|1:2,0:0:0:0: +348,288,145186,1,0,0:0:0:0: +452,220,145351,1,10,0:0:0:0: +452,220,145516,1,8,0:0:0:0: +328,36,146010,5,2,1:2:0:0: +264,88,146175,1,0,0:0:0:0: +184,108,146340,1,0,0:0:0:0: +104,88,146505,1,0,0:0:0:0: +44,36,146669,1,8,0:0:0:0: +44,36,146999,1,8,0:0:0:0: +44,36,147329,6,0,L|24:84,1,45,8|0,0:0|0:0,0:0:0:0: +52,156,147658,2,0,L|71:204,1,45,8|0,1:2|0:0,0:0:0:0: +144,236,147988,1,8,0:0:0:0: +144,236,148153,1,8,0:0:0:0: +316,64,148647,5,0,1:0:0:0: +380,116,148812,1,0,0:0:0:0: +408,192,148977,1,0,0:0:0:0: +380,268,149142,1,0,0:0:0:0: +316,320,149307,2,0,L|224:316,1,90,10|8,0:0|0:0,0:0:0:0: +64,248,149966,5,10,0:0:0:0: +144,236,150131,1,0,0:0:0:0: +188,168,150296,1,8,1:2:0:0: +192,88,150461,1,0,0:0:0:0: +140,24,150626,2,0,P|120:16|96:20,1,45,10|0,0:0|0:0,0:0:0:0: +260,132,150955,2,0,P|280:140|304:136,1,45,2|0,0:0|0:0,0:0:0:0: +476,48,151285,6,0,L|484:160,1,112.5,4|0,1:2|0:0,0:0:0:0: +464,236,151779,1,0,0:0:0:0: +436,308,151944,2,0,P|380:320|324:308,1,112.5,8|8,0:0|0:0,0:0:0:0: +76,308,152604,6,0,P|132:320|188:308,1,112.5,8|8,0:0|1:2,0:0:0:0: +256,88,153263,1,8,0:0:0:0: +256,168,153428,1,8,0:0:0:0: +256,168,153922,5,4,1:2:0:0: +256,248,154087,1,0,0:0:0:0: +324,128,154252,1,0,0:0:0:0: +188,128,154417,1,0,0:0:0:0: +332,212,154582,2,0,L|388:204,1,56.25,10|0,0:0|0:0,0:0:0:0: +492,152,154911,2,0,L|436:144,1,56.25,8|0,0:0|0:0,0:0:0:0: +324,128,155241,5,10,0:0:0:0: +180,212,155406,1,0,0:0:0:0: +332,212,155571,1,8,1:2:0:0: +188,128,155735,1,0,0:0:0:0: +256,248,155900,1,10,0:0:0:0: +256,248,156065,2,0,L|256:304,2,56.25,0|0|0,0:0|0:0|0:0,0:0:0:0: +180,212,156560,6,0,L|124:204,1,56.25,4|0,1:2|0:0,0:0:0:0: +20,152,156889,2,0,L|76:144,1,56.25,0|0,0:0|0:0,0:0:0:0: +188,128,157219,2,0,P|212:72|192:16,1,112.5,8|8,0:0|0:0,0:0:0:0: +132,72,157713,1,0,0:0:0:0: +180,212,157878,6,0,L|236:208,1,56.25,8|0,0:0|0:0,0:0:0:0: +360,252,158208,2,8,L|304:248,1,56.25,8|0,1:2|0:0,0:0:0:0: +168,292,158538,2,0,L|160:356,2,56.25,8|8|0,0:0|0:0|0:0,0:0:0:0: +180,212,159032,1,0,0:0:0:0: +144,140,159197,6,0,P|104:128|36:148,1,112.5,2|0,1:2|0:0,0:0:0:0: +12,220,159691,1,0,0:0:0:0: +36,296,159856,2,0,P|60:316|92:324,1,56.25,8|0,0:0|0:0,0:0:0:0: +215,264,160186,2,0,P|189:273|168:292,1,56.25,8|0,0:0|0:0,0:0:0:0: +228,344,160516,6,0,L|284:340,1,56.25,10|0,0:0|0:0,0:0:0:0: +328,276,160845,2,0,L|384:272,1,56.25,8|0,1:2|0:0,0:0:0:0: +428,208,161175,1,8,0:0:0:0: +440,128,161340,1,8,0:0:0:0: +400,60,161505,1,2,0:0:0:0: +328,28,161669,1,0,0:0:0:0: +212,76,161834,6,0,P|200:120|208:164,1,90,2|0,1:2|1:0,0:0:0:0: +300,308,162163,2,0,P|312:264|304:220,1,90,2|0,1:2|1:0,0:0:0:0: +140,236,162493,2,0,P|184:248|228:240,1,90,2|0,1:2|1:0,0:0:0:0: +372,148,162823,2,0,P|328:136|284:144,1,90,2|0,1:2|1:0,0:0:0:0: +104,316,163152,5,2,1:2:0:0: +78,297,163235,1,0,1:0:0:0: +60,270,163317,1,0,1:0:0:0: +54,239,163399,1,0,1:0:0:0: +58,207,163482,1,2,1:2:0:0: +74,180,163564,1,0,1:0:0:0: +98,159,163647,1,0,1:0:0:0: +127,149,163729,1,0,1:0:0:0: +158,150,163812,2,0,L|208:160,1,45,2|0,1:2|1:0,0:0:0:0: +344,184,163976,2,0,L|294:194,1,45,0|0,1:0|1:0,0:0:0:0: +140,236,164141,1,4,1:2:0:0: +140,236,164471,6,0,L|232:252,1,90,4|0,1:2|0:0,0:0:0:0: +344,184,164801,1,8,0:0:0:0: +380,284,164965,1,0,0:0:0:0: +368,104,165130,2,0,P|324:104|284:128,1,90,0|0,0:0|1:0,0:0:0:0: +356,360,165460,2,0,P|400:360|440:336,1,90,8|0,0:0|0:0,0:0:0:0: +432,208,165790,5,0,1:0:0:0: +292,260,165954,1,0,0:0:0:0: +344,184,166119,1,8,0:0:0:0: +204,236,166284,1,0,1:0:0:0: +204,236,166366,1,0,0:0:0:0: +204,236,166449,2,0,L|216:328,1,90,0|0,0:0|1:0,0:0:0:0: +120,208,166779,2,0,L|131:118,1,90,8|0,0:0|0:0,0:0:0:0: +204,236,167108,5,0,1:0:0:0: +32,216,167273,1,0,0:0:0:0: +130,118,167438,1,8,0:0:0:0: +110,298,167603,1,0,0:0:0:0: +110,298,167685,1,0,0:0:0:0: +110,298,167768,2,0,L|121:208,1,90,0|0,0:0|1:0,0:0:0:0: +304,40,168097,2,0,L|315:130,1,90,8|0,0:0|0:0,0:0:0:0: +328,236,168427,5,0,1:0:0:0: +184,148,168592,1,0,0:0:0:0: +314,129,168757,1,8,0:0:0:0: +197,254,168921,1,0,1:0:0:0: +197,254,169004,1,0,0:0:0:0: +197,254,169086,2,0,P|220:292|260:312,1,90,0|0,0:0|1:0,0:0:0:0: +409,210,169416,2,0,P|365:211|328:236,1,90,8|0,0:0|0:0,0:0:0:0: +488,232,169746,6,0,P|487:192|464:149,1,90,0|0,1:0|0:0,0:0:0:0: +314,129,170075,1,8,0:0:0:0: +409,210,170240,1,0,0:0:0:0: +332,40,170405,2,0,L|240:36,1,90,0|0,0:0|1:0,0:0:0:0: +68,144,170735,2,0,L|157:140,1,90,8|0,0:0|0:0,0:0:0:0: +314,129,171064,5,0,1:0:0:0: +332,40,171229,1,0,0:0:0:0: +324,216,171394,1,8,0:0:0:0: +306,305,171559,1,0,1:0:0:0: +257,178,171724,1,0,0:0:0:0: +168,160,171888,1,0,1:0:0:0: +384,164,172053,1,8,0:0:0:0: +473,182,172218,1,0,0:0:0:0: +306,305,172383,6,0,L|216:312,1,90,0|0,1:0|0:0,0:0:0:0: +60,172,172713,1,8,0:0:0:0: +120,260,172877,1,0,0:0:0:0: +168,160,173042,2,0,L|172:68,1,90,0|0,0:0|1:0,0:0:0:0: +309,216,173372,2,0,L|306:306,1,90,8|0,0:0|0:0,0:0:0:0: +120,260,173702,5,0,1:0:0:0: +152,256,173784,1,0,1:0:0:0: +184,252,173866,1,0,1:0:0:0: +309,216,174031,1,8,0:0:0:0: +103,168,174196,1,0,1:0:0:0: +135,164,174279,1,0,1:0:0:0: +167,160,174361,1,0,1:0:0:0: +292,124,174526,1,0,1:0:0:0: +87,76,174691,1,8,1:2:0:0: +119,72,174773,1,0,1:0:0:0: +151,68,174855,1,0,1:0:0:0: +276,32,175020,6,0,L|368:40,1,90,0|0,1:0|0:0,0:0:0:0: +448,108,175350,1,8,0:0:0:0: +292,124,175515,1,0,0:0:0:0: +292,124,175597,1,0,0:0:0:0: +292,124,175680,2,0,L|308:216,1,90,0|0,0:0|1:0,0:0:0:0: +328,320,176009,1,8,0:0:0:0: +408,248,176174,1,0,0:0:0:0: +220,300,176339,6,0,P|176:304|128:292,1,90,0|0,1:0|0:0,0:0:0:0: +16,120,176669,1,8,0:0:0:0: +120,152,176834,1,0,1:0:0:0: +120,152,176916,1,0,0:0:0:0: +120,152,176998,2,0,L|124:200,1,45 +212,176,177163,2,0,L|239:215,1,45,0|0,1:0|0:0,0:0:0:0: +292,124,177328,2,0,P|302:79|283:30,1,90,8|0,0:0|0:0,0:0:0:0: +344,192,177658,6,0,P|372:156|376:104,1,90,0|0,1:0|0:0,0:0:0:0: +212,88,177987,1,8,0:0:0:0: +272,228,178152,1,0,0:0:0:0: +272,228,178235,1,0,0:0:0:0: +272,228,178317,1,0,0:0:0:0: +292,124,178482,1,0,1:0:0:0: +180,180,178647,1,8,0:0:0:0: +200,284,178812,1,0,0:0:0:0: +292,124,178976,5,0,1:0:0:0: +288,92,179059,1,0,0:0:0:0: +280,60,179141,2,0,P|248:24|208:14,1,90,0|8,0:0|0:0,0:0:0:0: +22,65,179471,2,0,P|67:71|112:68,1,90,0|0,1:0|0:0,0:0:0:0: +212,88,179801,1,0,1:0:0:0: +22,65,179965,1,8,0:0:0:0: +180,180,180130,5,0,0:0:0:0: +180,180,180213,1,0,0:0:0:0: +180,180,180295,2,0,P|184:224|172:272,1,90,0|0,1:0|0:0,0:0:0:0: +76,216,180625,2,0,P|72:172|84:124,1,90,8|0,0:0|0:0,0:0:0:0: +380,240,180954,2,0,P|384:284|372:332,1,90,0|0,0:0|1:0,0:0:0:0: +276,276,181284,2,0,P|272:232|284:184,1,90,8|0,0:0|0:0,0:0:0:0: +374,129,181614,5,0,1:0:0:0: +300,352,181779,2,0,L|204:348,2,90,0|8|0,0:0|0:0|1:0,0:0:0:0: +448,180,182273,1,2,0:0:0:0: +448,180,182438,1,2,1:2:0:0: +276,276,182603,1,10,0:0:0:0: +276,276,182768,1,2,0:0:0:0: +96,200,182932,6,0,L|88:108,1,90,0|0,1:0|0:0,0:0:0:0: +96,200,183262,1,8,0:0:0:0: +12,68,183427,2,0,P|72:24|164:68,1,180,0|0,0:0|1:0,0:0:0:0: +140,272,183921,2,0,P|92:284|52:271,1,90,8|0,0:0|0:0,0:0:0:0: +176,156,184251,5,0,1:0:0:0: +208,152,184334,1,0,1:0:0:0: +240,148,184416,1,0,1:0:0:0: +308,64,184581,1,8,0:0:0:0: +296,240,184746,1,0,1:0:0:0: +312,268,184828,1,0,1:0:0:0: +336,284,184910,1,0,1:0:0:0: +368,292,184993,1,0,1:0:0:0: +400,288,185075,1,0,1:0:0:0: +464,184,185240,1,8,0:0:0:0: +468,152,185323,1,0,0:0:0:0: +472,120,185405,2,0,L|464:76,1,45,0|0,1:0|1:0,0:0:0:0: +388,96,185570,6,0,P|360:132|316:148,1,90,4|0,1:2|0:0,0:0:0:0: +224,46,185899,2,0,P|268:43|308:63,1,90,8|0,0:0|0:0,0:0:0:0: +296,240,186229,1,0,0:0:0:0: +308,64,186394,1,0,1:0:0:0: +296,240,186559,2,0,L|312:332,1,90,8|0,0:0|0:0,0:0:0:0: +464,184,186888,6,0,P|420:180|372:188,1,90,0|0,1:0|0:0,0:0:0:0: +296,240,187218,1,8,0:0:0:0: +136,292,187383,2,0,P|94:277|54:249,1,90,0|0,1:0|0:0,0:0:0:0: +21,159,187713,1,0,1:0:0:0: +104,8,187877,2,0,L|124:96,1,90,10|0,0:0|0:0,0:0:0:0: +124,96,188207,6,0,P|152:132|196:148,1,90,0|0,1:0|0:0,0:0:0:0: +287,46,188537,2,0,P|243:43|204:63,1,90,8|0,0:0|0:0,0:0:0:0: +216,240,188866,1,2,0:0:0:0: +204,64,189031,1,0,1:0:0:0: +216,240,189196,2,0,L|200:332,1,90,8|0,0:0|0:0,0:0:0:0: +40,240,189526,5,2,1:2:0:0: +128,192,189691,1,0,0:0:0:0: +216,240,189855,1,8,0:0:0:0: +304,192,190020,1,0,1:0:0:0: +392,240,190185,2,0,L|400:332,1,90,2|0,0:0|1:0,0:0:0:0: +464,168,190515,2,0,L|456:76,1,90,8|0,0:0|0:0,0:0:0:0: +392,240,190844,6,0,P|364:272|312:292,1,90,2|0,1:2|0:0,0:0:0:0: +220,140,191174,2,0,P|248:108|296:92,1,90,8|0,0:0|0:0,0:0:0:0: +324,96,191421,1,0,0:0:0:0: +356,104,191504,2,0,L|340:16,1,90,0|0,0:0|1:0,0:0:0:0: +256,276,191834,2,0,L|272:364,1,90,8|0,0:0|0:0,0:0:0:0: +392,240,192163,5,0,1:0:0:0: +356,104,192328,1,0,0:0:0:0: +220,140,192493,1,8,0:0:0:0: +256,276,192658,1,0,1:0:0:0: +305,191,192823,1,0,0:0:0:0: +212,56,192987,1,0,1:0:0:0: +200,220,193152,1,10,0:0:0:0: +200,220,193482,6,0,P|156:228|108:220,1,90,0|0,1:0|0:0,0:0:0:0: +88,116,193812,1,8,0:0:0:0: +16,192,193976,1,0,0:0:0:0: +16,192,194059,1,0,0:0:0:0: +16,192,194141,2,0,L|28:288,1,90,2|0,0:0|1:0,0:0:0:0: +188,309,194471,2,0,L|200:220,1,90,8|0,0:0|0:0,0:0:0:0: +216,112,194801,5,2,1:2:0:0: +216,112,194883,1,0,1:0:0:0: +216,112,194965,1,0,1:0:0:0: +361,25,195130,1,8,0:0:0:0: +294,180,195295,1,0,1:0:0:0: +294,180,195377,1,0,1:0:0:0: +294,180,195460,1,2,0:0:0:0: +256,16,195625,1,0,1:0:0:0: +384,127,195790,1,10,1:2:0:0: +416,132,195872,1,0,1:0:0:0: +448,140,195954,2,0,L|452:84,1,45,0|0,1:0|1:0,0:0:0:0: +416,216,196119,6,0,P|412:264|432:312,1,90,4|0,1:2|0:0,0:0:0:0: +304,268,196449,2,0,P|308:220|288:172,1,90,8|0,0:0|0:0,0:0:0:0: +216,112,196779,2,0,L|120:104,1,90,0|0,0:0|1:0,0:0:0:0: +52,248,197108,2,0,L|141:255,1,90,8|0,0:0|0:0,0:0:0:0: +304,268,197438,5,0,1:0:0:0: +416,216,197603,1,0,0:0:0:0: +408,340,197768,1,8,0:0:0:0: +332,180,197932,1,0,1:0:0:0: +332,180,198015,1,0,0:0:0:0: +332,180,198097,2,0,P|360:140|400:120,1,90,0|0,0:0|1:0,0:0:0:0: +484,284,198427,1,10,0:0:0:0: +304,268,198592,1,2,0:0:0:0: +416,216,198757,6,0,P|428:172|420:124,1,90,2|0,1:2|0:0,0:0:0:0: +344,52,199086,1,8,0:0:0:0: +332,180,199251,1,0,0:0:0:0: +164,236,199416,2,0,P|152:192|160:144,1,90,0|0,0:0|1:0,0:0:0:0: +236,72,199746,1,8,0:0:0:0: +248,200,199910,1,0,0:0:0:0: +156,328,200075,6,0,L|56:320,1,90,2|0,1:2|0:0,0:0:0:0: +164,236,200405,1,8,0:0:0:0: +256,292,200570,2,0,P|300:296|344:284,1,90,0|0,1:0|0:0,0:0:0:0: +432,220,200899,2,0,L|460:308,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +392,120,201394,5,4,1:2:0:0: +396,32,201559,1,0,1:0:0:0: +316,72,201724,1,0,1:0:0:0: +256,6,201888,1,0,1:0:0:0: +228,91,202053,1,0,1:0:0:0: +139,87,202218,1,0,1:0:0:0: +179,166,202383,1,0,1:0:0:0: +113,226,202548,1,0,1:0:0:0: +197,253,202713,5,4,1:2:0:0: +193,342,202877,1,0,1:0:0:0: +272,302,203042,1,0,1:0:0:0: +332,367,203207,1,0,1:0:0:0: +359,283,203372,1,2,1:2:0:0: +448,287,203537,1,2,1:2:0:0: +407,208,203702,1,2,1:2:0:0: +472,147,203866,1,2,1:2:0:0: +387,121,204031,5,4,1:2:0:0: +360,100,204114,1,0,1:0:0:0: +344,72,204196,1,0,1:0:0:0: +336,40,204279,1,0,1:0:0:0: +340,8,204361,1,0,1:0:0:0: +316,28,204443,1,0,1:0:0:0: +284,32,204526,1,0,1:0:0:0: +252,28,204608,1,0,1:0:0:0: +228,8,204691,2,0,L|184:20,7,45,4|0|0|0|0|0|0|0,1:2|1:0|1:0|1:0|1:0|1:0|1:0|1:0,0:0:0:0: +112,56,205350,5,4,1:2:0:0: +100,84,205432,1,0,1:0:0:0: +96,116,205515,1,0,1:0:0:0: +100,148,205597,1,0,1:0:0:0: +112,176,205680,1,0,1:0:0:0: +124,204,205762,1,0,1:0:0:0: +128,236,205844,1,0,1:0:0:0: +124,268,205927,1,0,1:0:0:0: +112,296,206009,2,0,L|71:313,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +192,312,206339,2,0,L|175:353,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +256,264,206669,5,4,1:2:0:0: +256,192,206751,12,0,209306,0:0:0:0: diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 3cd425ea44..24843f8c32 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -290,8 +290,12 @@ namespace osu.Game.Beatmaps.Formats string[] split = line.Split(','); EventType type; + if (!Enum.TryParse(split[0], out type)) - throw new InvalidDataException($@"Unknown event type {split[0]}"); + { + Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + return; + } switch (type) { diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index f6e2bf6966..1dcafb4669 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -10,6 +10,7 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.IO.File; +using osu.Framework.Logging; using osu.Game.Storyboards; namespace osu.Game.Beatmaps.Formats @@ -83,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - throw new InvalidDataException($@"Unknown event type {split[0]}"); + Logger.Log($"A storyboard event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From a5c17ae26d81b778c2b8e87f2c1c074d7bf72267 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 10:14:36 +0900 Subject: [PATCH 116/645] Don't use GetDecoder --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 98464b8d91..7e0374023e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -486,12 +486,13 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeInvalidEvents() { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + using (var normalResStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var normalStream = new StreamReader(normalResStream)) using (var resStream = TestResources.OpenResource("invalid-events.osu")) using (var stream = new StreamReader(resStream)) { - var decoder = Decoder.GetDecoder(stream); var goodBeatmap = decoder.Decode(normalStream); Beatmap badBeatmap = null; From 1fc7ddf621611e9d773fb5b0df218d8a18992681 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 5 Aug 2019 18:14:41 -0700 Subject: [PATCH 117/645] Fix text depth regression --- osu.Game/Screens/Select/FooterButton.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 90bc902ad8..15088f0eb3 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -67,16 +67,6 @@ namespace osu.Game.Screens.Select Shear = SHEARING; Children = new Drawable[] { - TextContainer = new Container - { - Size = new Vector2(100 - SHEAR_WIDTH, 50), - Shear = -SHEARING, - Child = SpriteText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - }, box = new Box { RelativeSizeAxes = Axes.Both, @@ -90,6 +80,16 @@ namespace osu.Game.Screens.Select EdgeSmoothness = new Vector2(2, 0), RelativeSizeAxes = Axes.X, }, + TextContainer = new Container + { + Size = new Vector2(100 - SHEAR_WIDTH, 50), + Shear = -SHEARING, + Child = SpriteText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, }; } From b8c38d4dfd5ba9a8cd3acc70ab0f0fcda7495cb7 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 10:36:26 +0900 Subject: [PATCH 118/645] remove unnecessary assert --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 7e0374023e..bbc3b05d89 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -494,9 +494,8 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var stream = new StreamReader(resStream)) { var goodBeatmap = decoder.Decode(normalStream); - Beatmap badBeatmap = null; + var badBeatmap = decoder.Decode(stream); - Assert.DoesNotThrow(() => badBeatmap = decoder.Decode(stream)); Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); } } From 2c32d886d7cf77e7615ebe93a7afadb00b1d81ef Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 10:39:54 +0900 Subject: [PATCH 119/645] Add better asserts --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index bbc3b05d89..e88c3c8ecc 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -496,6 +496,8 @@ namespace osu.Game.Tests.Beatmaps.Formats var goodBeatmap = decoder.Decode(normalStream); var badBeatmap = decoder.Decode(stream); + Assert.AreEqual(goodBeatmap.Breaks[0].Duration, badBeatmap.Breaks[0].Duration); + Assert.AreEqual(goodBeatmap.Metadata.BackgroundFile, badBeatmap.Metadata.BackgroundFile); Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); } } From 66b02c02831a2004c53b755d0159fea08c9bf2ad Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 12:27:10 +0900 Subject: [PATCH 120/645] log type as well --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 24843f8c32..c92c0ba22d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats if (!Enum.TryParse(split[0], out type)) { - Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A beatmap {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); return; } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 1dcafb4669..512eea0822 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - Logger.Log($"A storyboard event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A storyboard {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From 497d2cb67784287c5217fe0c5279bfab7748bab7 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 12:35:18 +0900 Subject: [PATCH 121/645] shorten tests and rename --- .../Formats/LegacyBeatmapDecoderTest.cs | 13 +- osu.Game.Tests/Resources/invalid-events.osu | 992 +----------------- osu.Game.Tests/Resources/valid-events.osu | 12 + 3 files changed, 19 insertions(+), 998 deletions(-) create mode 100644 osu.Game.Tests/Resources/valid-events.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index e88c3c8ecc..49a6f646ba 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -488,17 +488,16 @@ namespace osu.Game.Tests.Beatmaps.Formats { var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; - using (var normalResStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) - using (var normalStream = new StreamReader(normalResStream)) - using (var resStream = TestResources.OpenResource("invalid-events.osu")) - using (var stream = new StreamReader(resStream)) + using (var goodResStream = TestResources.OpenResource("valid-events.osu")) + using (var goodStream = new StreamReader(goodResStream)) + using (var badResStream = TestResources.OpenResource("invalid-events.osu")) + using (var badStream = new StreamReader(badResStream)) { - var goodBeatmap = decoder.Decode(normalStream); - var badBeatmap = decoder.Decode(stream); + var goodBeatmap = decoder.Decode(goodStream); + var badBeatmap = decoder.Decode(badStream); Assert.AreEqual(goodBeatmap.Breaks[0].Duration, badBeatmap.Breaks[0].Duration); Assert.AreEqual(goodBeatmap.Metadata.BackgroundFile, badBeatmap.Metadata.BackgroundFile); - Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); } } } diff --git a/osu.Game.Tests/Resources/invalid-events.osu b/osu.Game.Tests/Resources/invalid-events.osu index a8e767585c..df86b26dba 100644 --- a/osu.Game.Tests/Resources/invalid-events.osu +++ b/osu.Game.Tests/Resources/invalid-events.osu @@ -1,43 +1,5 @@ osu file format v14 -[General] -AudioFilename: 03. Renatus - Soleily 192kbps.mp3 -AudioLeadIn: 0 -PreviewTime: 164471 -Countdown: 0 -SampleSet: Soft -StackLeniency: 0.7 -Mode: 0 -LetterboxInBreaks: 0 -WidescreenStoryboard: 0 - -[Editor] -Bookmarks: 11505,22054,32604,43153,53703,64252,74802,85351,95901,106450,116999,119637,130186,140735,151285,161834,164471,175020,185570,196119,206669,209306 -DistanceSpacing: 1.8 -BeatDivisor: 4 -GridSize: 4 -TimelineZoom: 2 - -[Metadata] -Title:Renatus -TitleUnicode:Renatus -Artist:Soleily -ArtistUnicode:Soleily -Creator:Gamu -Version:Insane -Source: -Tags:MBC7 Unisphere 地球ヤバイEP Chikyu Yabai -BeatmapID:557821 -BeatmapSetID:241526 - -[Difficulty] -HPDrainRate:6.5 -CircleSize:4 -OverallDifficulty:8 -ApproachRate:9 -SliderMultiplier:1.8 -SliderTickRate:2 - [Events] bad,event,this,should,fail //Background and Video events @@ -45,960 +7,8 @@ bad,event,this,should,fail //Break Periods 2,122474,140135 //Storyboard Layer 0 (Background) +this,is,also,bad //Storyboard Layer 1 (Fail) //Storyboard Layer 2 (Pass) //Storyboard Layer 3 (Foreground) //Storyboard Sound Samples - -[TimingPoints] -956,329.67032967033,4,2,0,60,1,0 -20736,-100,4,2,0,65,0,0 -22054,-100,4,2,0,70,0,0 -43153,-100,4,2,0,60,0,0 -48428,-100,4,2,0,50,0,0 -52879,-100,4,2,0,50,0,0 -53373,-100,4,2,0,60,0,0 -53703,-100,4,2,0,70,0,1 -74719,-100,4,2,0,70,0,0 -74802,-100,4,2,0,70,0,1 -95901,-100,4,2,0,70,0,0 -116999,-133.333333333333,4,2,0,50,0,0 -117164,-133.333333333333,4,2,0,30,0,0 -117329,-79.9999999999999,4,2,0,50,0,0 -117659,-100,4,2,0,50,0,0 -118977,-100,4,2,0,60,0,0 -119307,-100,4,2,0,70,0,0 -119637,659.340659340659,4,2,0,80,1,0 -119966,-100,4,2,0,70,0,0 -120296,-100,4,2,0,60,0,0 -120626,-100,4,2,0,50,0,0 -120955,-100,4,2,0,40,0,0 -121285,-100,4,2,0,30,0,0 -121615,-100,4,2,0,20,0,0 -121944,-100,4,2,0,10,0,0 -122274,-100,4,2,0,5,0,0 -140735,-100,4,2,0,50,0,0 -151285,-80,4,2,0,60,0,0 -161834,329.67032967033,4,2,0,65,1,0 -164141,-100,4,2,0,70,0,0 -164471,-100,4,2,0,70,0,1 -185487,-100,4,2,0,70,0,0 -185570,-100,4,2,0,70,0,1 -206669,659.340659340659,4,2,0,80,1,0 -206998,-100,4,2,0,70,0,0 -207328,-100,4,2,0,60,0,0 -207658,-100,4,2,0,50,0,0 -207987,-100,4,2,0,40,0,0 -208317,-100,4,2,0,30,0,0 -208647,-100,4,2,0,20,0,0 -208976,-100,4,2,0,10,0,0 -209306,-100,4,2,0,5,0,0 - - -[Colours] -Combo1 : 142,199,255 -Combo2 : 255,128,128 -Combo3 : 128,255,255 -Combo4 : 128,255,128 -Combo5 : 255,187,255 -Combo6 : 255,177,140 -Combo7 : 100,100,100,100 - -[HitObjects] -192,168,956,6,0,P|184:128|200:80,1,90,4|0,1:2|0:0,0:0:0:0: -304,56,1285,1,8,0:0:0:0: -244,236,1450,2,0,P|204:252|156:244,1,90,2|0,0:0|0:0,0:0:0:0: -276,156,1780,2,0,P|310:181|329:226,1,90,2|8,1:2|0:0,0:0:0:0: -300,328,2109,1,2,0:0:0:0: -192,332,2274,6,0,L|144:340,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -388,300,2604,1,8,0:0:0:0: -244,236,2769,1,0,1:0:0:0: -232,208,2851,1,0,0:0:0:0: -224,176,2934,1,0,0:0:0:0: -228,144,3016,1,0,0:0:0:0: -244,116,3098,1,0,1:0:0:0: -332,52,3263,2,0,P|376:48|424:56,1,90,8|0,0:0|0:0,0:0:0:0: -488,228,3593,5,0,1:0:0:0: -460,240,3675,1,0,0:0:0:0: -428,236,3758,1,0,0:0:0:0: -292,160,3923,2,0,P|288:204|300:252,1,90,8|0,0:0|0:0,0:0:0:0: -316,276,4170,1,0,0:0:0:0: -344,292,4252,2,0,L|388:300,1,45,0|0,0:0|0:0,0:0:0:0: -288,356,4417,2,0,L|244:364,1,45,0|0,1:0|0:0,0:0:0:0: -168,328,4582,2,0,P|124:324|72:332,1,90,8|0,0:0|0:0,0:0:0:0: -24,188,4912,5,0,1:0:0:0: -56,192,4994,1,0,0:0:0:0: -88,196,5076,1,0,0:0:0:0: -148,108,5241,1,8,0:0:0:0: -188,240,5406,1,0,1:0:0:0: -188,240,5488,1,0,0:0:0:0: -188,240,5571,2,0,L|168:328,1,90,0|0,0:0|1:0,0:0:0:0: -260,216,5901,2,0,P|236:180|188:164,1,90,8|0,0:0|0:0,0:0:0:0: -248,296,6230,6,0,L|348:292,1,90,0|0,1:0|0:0,0:0:0:0: -504,232,6560,1,8,0:0:0:0: -400,204,6725,1,0,0:0:0:0: -392,176,6807,1,0,0:0:0:0: -384,144,6890,1,0,0:0:0:0: -376,116,6972,1,0,0:0:0:0: -368,88,7054,1,0,1:0:0:0: -188,48,7219,2,0,L|208:140,1,90,8|0,0:0|0:0,0:0:0:0: -248,296,7549,5,0,1:0:0:0: -207,135,7714,1,0,0:0:0:0: -156,232,7879,1,8,0:0:0:0: -316,191,8043,1,0,1:0:0:0: -316,191,8126,1,0,0:0:0:0: -316,191,8208,2,0,L|372:200,1,45,0|0,0:0|0:0,0:0:0:0: -492,200,8373,2,0,L|447:207,1,45,0|0,1:0|0:0,0:0:0:0: -408,136,8538,2,0,P|396:92|400:48,1,90,8|0,0:0|0:0,0:0:0:0: -260,32,8868,5,0,1:0:0:0: -252,64,8950,1,0,0:0:0:0: -236,92,9032,2,0,P|204:116|148:128,1,90,0|8,0:0|0:0,0:0:0:0: -28,188,9362,1,0,0:0:0:0: -60,196,9445,1,0,0:0:0:0: -88,212,9527,2,0,P|112:244|124:300,1,90,0|0,0:0|1:0,0:0:0:0: -112,128,9857,2,0,P|152:156|184:196,1,90,8|0,0:0|0:0,0:0:0:0: -216,288,10186,5,0,1:0:0:0: -216,288,10269,1,0,0:0:0:0: -216,288,10351,1,0,0:0:0:0: -268,192,10516,1,8,0:0:0:0: -356,128,10681,1,0,1:0:0:0: -388,120,10763,1,0,0:0:0:0: -420,128,10846,2,0,P|440:168|436:220,1,90,0|0,0:0|1:0,0:0:0:0: -332,328,11175,2,0,L|280:332,1,45,8|8,0:0|0:0,0:0:0:0: -216,288,11340,2,0,L|164:292,1,45,0|0,1:0|0:0,1:0:0:0: -100,248,11505,5,4,1:2:0:0: -148,116,11670,1,2,0:0:0:0: -268,192,11835,1,10,0:0:0:0: -136,328,11999,2,0,L|44:336,1,90,2|0,0:0|0:0,0:0:0:0: -216,288,12329,1,2,1:2:0:0: -148,116,12494,1,10,0:0:0:0: -100,248,12659,1,2,0:0:0:0: -268,192,12824,5,0,1:0:0:0: -268,192,12906,1,0,0:0:0:0: -268,192,12988,1,0,0:0:0:0: -340,272,13153,2,0,P|384:276|432:264,1,90,8|0,0:0|1:0,0:0:0:0: -452,244,13401,1,0,0:0:0:0: -468,216,13483,2,0,L|476:124,1,90,0|0,0:0|1:0,0:0:0:0: -368,32,13813,2,0,L|360:121,1,90,8|0,0:0|0:0,0:0:0:0: -340,272,14142,6,0,L|316:316,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -452,244,14472,1,8,0:0:0:0: -268,192,14637,1,0,0:0:0:0: -236,188,14719,1,0,0:0:0:0: -204,192,14802,2,0,P|172:228|160:272,1,90,0|0,0:0|1:0,0:0:0:0: -128,140,15131,2,0,P|160:104|172:60,1,90,8|0,0:0|0:0,0:0:0:0: -64,52,15461,6,0,L|20:68,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -171,64,15791,1,8,0:0:0:0: -264,8,15956,2,0,L|356:12,1,90,0|0,1:0|0:0,0:0:0:0: -452,56,16285,1,0,1:0:0:0: -296,140,16450,2,0,L|206:136,1,90,8|0,0:0|0:0,0:0:0:0: -108,184,16780,6,0,P|92:224|96:272,1,90,0|0,1:0|0:0,0:0:0:0: -200,244,17109,1,8,0:0:0:0: -108,108,17274,2,0,L|12:116,1,90,0|0,0:0|0:0,0:0:0:0: -200,244,17604,1,0,1:0:0:0: -296,140,17769,2,0,L|385:132,1,90,8|0,0:0|0:0,0:0:0:0: -480,184,18098,5,0,1:0:0:0: -488,216,18181,1,0,0:0:0:0: -496,248,18263,2,0,L|492:340,1,90,0|8,0:0|0:0,0:0:0:0: -404,224,18593,2,0,L|396:176,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -304,264,18923,1,0,1:0:0:0: -200,244,19087,2,0,P|156:240|108:248,1,90,8|0,0:0|0:0,0:0:0:0: -296,140,19417,6,0,P|340:144|388:136,1,90,0|0,1:0|0:0,0:0:0:0: -440,44,19747,1,8,0:0:0:0: -404,224,19912,1,0,0:0:0:0: -404,224,19994,1,0,0:0:0:0: -404,224,20076,2,0,L|412:320,1,90,0|0,0:0|1:0,0:0:0:0: -200,244,20406,2,0,L|192:154,1,90,8|0,0:0|0:0,0:0:0:0: -184,44,20736,5,4,1:2:0:0: -152,40,20818,1,0,0:0:0:0: -120,48,20901,1,0,0:0:0:0: -96,68,20983,1,0,0:0:0:0: -76,92,21065,1,2,0:3:0:0: -64,120,21148,1,0,0:0:0:0: -60,152,21230,1,0,1:0:0:0: -64,184,21313,1,0,0:0:0:0: -76,212,21395,2,0,L|96:252,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -144,316,21725,2,0,L|188:324,3,45,0|0|2|0,0:0|0:0|0:3|0:0,0:0:0:0: -268,340,22054,6,0,L|364:336,1,90,4|0,1:2|0:0,0:0:0:0: -452,280,22384,1,8,0:0:0:0: -512,188,22549,2,0,P|516:144|504:96,1,90,2|0,0:0|0:0,0:0:0:0: -340,24,22879,2,0,P|336:68|348:116,1,90,2|8,1:2|0:0,0:0:0:0: -420,192,23208,1,2,0:0:0:0: -328,252,23373,6,0,L|232:240,1,90,0|0,1:0|0:0,0:0:0:0: -64,256,23703,1,8,0:0:0:0: -144,184,23868,2,0,P|148:140|136:88,1,90,0|0,1:0|0:0,0:0:0:0: -40,52,24197,1,2,1:2:0:0: -139,95,24362,1,8,0:0:0:0: -216,20,24527,1,0,0:0:0:0: -315,63,24692,6,0,P|360:72|408:68,1,90,2|0,1:2|0:0,0:0:0:0: -492,132,25021,1,8,0:0:0:0: -412,204,25186,2,0,P|403:249|407:297,1,90,2|0,0:0|0:0,0:0:0:0: -268,328,25516,2,0,P|277:283|273:235,1,90,2|8,1:2|0:0,0:0:0:0: -232,140,25846,2,0,P|187:131|139:135,1,90,2|0,0:0|1:0,0:0:0:0: -64,208,26175,5,2,0:0:0:0: -44,316,26340,1,8,0:0:0:0: -148,280,26505,1,2,1:2:0:0: -456,208,26835,1,2,1:2:0:0: -476,316,26999,1,10,0:0:0:0: -372,280,27164,1,2,0:0:0:0: -356,172,27329,6,0,L|380:80,1,90,0|0,1:0|0:0,0:0:0:0: -456,208,27659,1,8,0:0:0:0: -300,236,27824,1,2,0:0:0:0: -300,236,27906,1,0,0:0:0:0: -300,236,27988,2,0,L|208:228,1,90,0|2,0:0|1:2,0:0:0:0: -140,312,28318,1,8,0:0:0:0: -372,280,28483,2,0,L|464:272,1,90,2|0,0:0|1:0,0:0:0:0: -500,136,28813,5,2,0:0:0:0: -432,56,28977,1,8,0:0:0:0: -328,24,29142,2,0,P|284:24|236:28,1,90,2|0,1:2|0:0,0:0:0:0: -80,144,29472,1,2,1:2:0:0: -116,44,29637,1,10,0:0:0:0: -184,128,29802,1,2,0:0:0:0: -20,88,29966,6,0,P|1:164|73:227,1,180,2|10,1:2|0:0,0:0:0:0: -184,128,30461,2,0,P|227:120|276:124,1,90,2|0,0:0|0:0,0:0:0:0: -392,188,30791,1,2,1:2:0:0: -272,260,30956,1,8,0:0:0:0: -396,328,31120,1,0,0:0:0:0: -256,348,31285,5,2,1:2:0:0: -224,344,31368,1,0,1:0:0:0: -192,340,31450,2,0,L|172:248,1,90,2|0,1:2|1:0,0:0:0:0: -8,136,31780,2,0,L|27:223,1,90,2|0,1:2|0:0,0:0:0:0: -56,328,32109,1,2,1:2:0:0: -108,192,32274,1,2,1:2:0:0: -100,160,32357,1,0,1:0:0:0: -92,132,32439,1,2,1:2:0:0: -84,104,32521,1,0,1:0:0:0: -76,72,32604,6,0,P|100:112|148:136,1,90,4|0,1:2|0:0,0:0:0:0: -240,168,32934,1,8,0:0:0:0: -336,124,33098,2,0,L|344:80,2,45,2|0|0,0:0|0:0|0:0,0:0:0:0: -264,248,33428,2,0,P|220:248|176:220,1,90,2|8,1:2|0:0,0:0:0:0: -260,84,33758,1,2,0:0:0:0: -344,212,33923,5,0,1:0:0:0: -344,212,34005,1,0,0:0:0:0: -344,212,34087,1,0,0:0:0:0: -440,160,34252,1,8,0:0:0:0: -312,320,34417,2,0,P|272:336|220:324,1,90,0|0,1:0|0:0,0:0:0:0: -156,176,34747,2,0,P|196:160|248:172,2,90,2|8|0,1:2|0:0|0:0,0:0:0:0: -132,280,35241,5,2,1:2:0:0: -132,280,35324,1,0,0:0:0:0: -132,280,35406,2,0,L|120:376,1,90,0|8,0:0|0:0,0:0:0:0: -312,320,35736,2,0,L|300:230,1,90,2|0,0:0|0:0,0:0:0:0: -316,124,36065,1,2,1:2:0:0: -400,192,36230,1,8,0:0:0:0: -300,230,36395,2,0,P|255:231|211:224,1,90,2|0,0:0|1:0,0:0:0:0: -24,132,36725,5,0,0:0:0:0: -132,152,36890,1,8,0:0:0:0: -60,232,37054,1,2,1:2:0:0: -60,232,37137,1,0,0:0:0:0: -60,232,37219,1,0,0:0:0:0: -92,56,37384,2,0,L|184:44,1,90,2|10,1:2|0:0,0:0:0:0: -316,124,37714,2,0,L|226:135,1,90,2|0,0:0|1:0,0:0:0:0: -60,232,38043,6,0,P|52:276|64:328,1,90,0|8,0:0|0:0,0:0:0:0: -220,152,38373,2,0,P|176:144|124:156,1,90,2|0,0:0|0:0,0:0:0:0: -176,252,38703,1,2,1:2:0:0: -323,213,38868,2,0,L|316:124,1,90,8|2,0:0|0:0,0:0:0:0: -332,320,39197,5,0,1:0:0:0: -424,260,39362,1,2,0:0:0:0: -260,272,39527,2,0,P|246:313|256:360,1,90,8|2,0:0|1:2,0:0:0:0: -408,336,39857,1,0,0:0:0:0: -176,252,40021,2,0,L|80:260,2,90,2|10|2,1:2|0:0|0:0,0:0:0:0: -324,212,40516,5,2,1:2:0:0: -324,212,40598,1,0,1:0:0:0: -324,212,40681,1,0,1:0:0:0: -200,336,40846,1,2,1:2:0:0: -236,188,41010,1,2,1:2:0:0: -236,188,41093,1,0,1:0:0:0: -236,188,41175,1,0,1:0:0:0: -281,357,41340,1,2,1:2:0:0: -176,252,41505,1,2,1:2:0:0: -176,252,41587,1,0,1:0:0:0: -176,252,41670,1,0,1:0:0:0: -344,297,41835,5,2,1:2:0:0: -432,232,41999,1,2,1:2:0:0: -444,204,42082,1,0,1:0:0:0: -448,172,42164,1,0,1:0:0:0: -444,140,42247,1,0,1:0:0:0: -432,112,42329,2,0,L|440:64,2,45,2|0|0,1:2|1:0|1:0,0:0:0:0: -236,188,42659,1,0,0:0:0:0: -340,172,42824,1,2,0:3:0:0: -272,88,42988,1,0,0:0:0:0: -132,160,43153,6,0,P|148:248|220:296,1,180,4|8,1:2|0:0,0:0:0:0: -324,320,43648,2,0,L|336:364,2,45,0|0|0,0:0|0:0|0:0,0:0:0:0: -292,216,43977,1,0,1:0:0:0: -396,240,44142,2,0,P|440:244|488:232,1,90,8|0,0:0|0:0,0:0:0:0: -328,124,44472,6,0,P|284:120|236:132,1,90,0|0,1:0|0:0,0:0:0:0: -168,212,44802,1,8,0:0:0:0: -192,316,44966,1,0,1:0:0:0: -140,220,45131,1,0,0:0:0:0: -83,310,45296,1,0,1:0:0:0: -114,205,45461,1,8,0:0:0:0: -10,229,45626,1,0,0:0:0:0: -106,176,45791,6,0,P|113:133|108:85,1,90,0|0,1:0|0:0,0:0:0:0: -204,136,46120,1,8,0:0:0:0: -256,40,46285,1,0,0:0:0:0: -256,40,46368,1,0,0:0:0:0: -256,40,46450,2,0,L|356:44,1,90,0|0,0:0|1:0,0:0:0:0: -501,124,46780,2,0,L|412:128,1,90,8|0,0:0|0:0,0:0:0:0: -324,192,47109,5,0,1:0:0:0: -356,296,47274,1,0,0:0:0:0: -284,216,47439,1,8,0:0:0:0: -269,323,47604,1,0,1:0:0:0: -237,220,47769,1,0,0:0:0:0: -178,311,47934,1,0,1:0:0:0: -191,203,48098,1,8,0:0:0:0: -99,261,48263,1,0,0:0:0:0: -156,168,48428,6,0,B|176:112|136:64|136:64|200:96,1,180,4|8,1:2|0:0,0:0:0:0: -300,124,48923,2,0,L|392:120,1,90,0|0,0:0|0:0,0:0:0:0: -468,48,49252,1,0,1:0:0:0: -390,120,49417,2,0,P|390:164|406:208,1,90,8|0,0:0|0:0,0:0:0:0: -352,344,49747,6,0,P|352:300|336:256,1,90,4|0,1:2|0:0,0:0:0:0: -240,208,50076,1,8,0:0:0:0: -163,320,50241,2,0,P|207:324|252:316,1,90,0|0,1:0|0:0,0:0:0:0: -240,208,50571,1,0,1:0:0:0: -76,296,50736,2,0,P|76:340|92:384,1,90,8|0,0:0|0:0,0:0:0:0: -312,164,51065,6,0,P|236:124|160:184,1,180,4|8,1:2|0:0,0:0:0:0: -247,297,51560,2,0,L|240:208,1,90,0|0,0:0|0:0,0:0:0:0: -224,48,51890,1,0,1:0:0:0: -332,56,52054,2,0,L|366:58,5,30,8|0|0|0|0|0,0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0: -408,64,52384,6,0,P|420:108|416:156,1,90,0|0,1:0|0:0,0:0:0:0: -360,260,52714,1,8,0:0:0:0: -247,297,52879,2,0,B|203:281|159:297|159:297|115:313|71:297,1,180,0|0,1:0|1:0,0:0:0:0: -116,196,53373,1,8,0:0:0:0: -120,164,53456,1,0,0:0:0:0: -124,132,53538,1,0,0:0:0:0: -128,100,53620,1,0,0:0:0:0: -132,68,53703,5,4,1:2:0:0: -40,136,53868,1,0,0:0:0:0: -204,160,54032,2,0,L|304:152,1,90,8|0,0:0|0:0,0:0:0:0: -408,64,54362,1,0,0:0:0:0: -408,64,54445,1,0,0:0:0:0: -408,64,54527,2,0,P|404:112|416:160,1,90,0|8,1:0|0:0,0:0:0:0: -484,236,54857,1,0,0:0:0:0: -428,328,55021,5,0,1:0:0:0: -328,296,55186,1,0,0:0:0:0: -328,296,55269,1,0,0:0:0:0: -328,296,55351,1,8,0:0:0:0: -416,300,55516,1,0,1:0:0:0: -472,208,55681,1,0,0:0:0:0: -316,268,55846,1,0,1:0:0:0: -460,180,56010,1,8,0:0:0:0: -304,240,56175,1,0,0:0:0:0: -404,272,56340,5,0,1:0:0:0: -448,152,56505,1,0,0:0:0:0: -448,152,56587,1,0,0:0:0:0: -448,152,56670,2,0,P|456:112|448:60,1,90,8|0,0:0|0:0,0:0:0:0: -268,28,56999,2,0,P|260:68|268:120,1,90,0|0,0:0|1:0,0:0:0:0: -404,272,57329,2,0,P|444:280|496:272,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: -304,240,57824,5,0,0:0:0:0: -252,336,57988,1,8,0:0:0:0: -196,244,58153,1,0,1:0:0:0: -24,256,58318,1,0,0:0:0:0: -116,200,58483,1,0,1:0:0:0: -136,60,58648,1,8,0:0:0:0: -192,152,58813,1,0,0:0:0:0: -304,240,58977,6,0,P|348:252|396:248,1,90,0|0,1:0|0:0,0:0:0:0: -456,116,59307,2,0,P|412:104|364:108,1,90,8|0,0:0|0:0,0:0:0:0: -273,161,59637,1,0,0:0:0:0: -136,60,59802,1,0,1:0:0:0: -192,152,59966,1,8,0:0:0:0: -23,177,60131,1,0,0:0:0:0: -129,203,60296,5,0,1:0:0:0: -88,304,60461,2,0,P|132:311|176:303,1,90,0|8,0:0|0:0,0:0:0:0: -304,240,60791,1,0,1:0:0:0: -304,240,60873,1,0,0:0:0:0: -304,240,60956,2,0,L|312:288,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -384,256,61285,2,0,L|392:304,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -464,272,61615,5,2,1:2:0:0: -488,168,61780,1,2,0:0:0:0: -428,80,61945,1,10,0:0:0:0: -332,32,62109,2,0,P|288:28|240:36,1,90,2|0,0:0|0:0,0:0:0:0: -28,216,62439,1,2,1:2:0:0: -88,304,62604,1,10,0:0:0:0: -184,352,62769,2,0,P|228:356|276:348,1,90,2|0,0:0|1:0,0:0:0:0: -384,256,63098,6,0,P|409:219|426:174,1,90,2|8,0:0|0:0,0:0:0:0: -428,80,63428,2,0,L|420:36,2,45,2|0|0,1:2|0:0|0:0,0:0:0:0: -456,288,63758,1,2,1:2:0:0: -324,200,63923,1,10,1:2:0:0: -292,204,64005,1,0,1:0:0:0: -260,208,64087,1,2,1:2:0:0: -228,212,64170,1,0,1:0:0:0: -196,216,64252,5,4,1:2:0:0: -104,160,64417,1,0,0:0:0:0: -228,296,64582,2,0,L|320:284,1,90,8|0,0:0|0:0,0:0:0:0: -344,112,64912,1,0,0:0:0:0: -344,112,64994,1,0,0:0:0:0: -344,112,65076,2,0,L|254:123,1,90,0|8,1:0|0:0,0:0:0:0: -144,284,65406,2,0,P|148:328|176:364,1,90,0|0,0:0|1:0,0:0:0:0: -196,216,65736,5,0,0:0:0:0: -196,216,65818,1,0,0:0:0:0: -196,216,65901,2,0,P|155:198|110:205,1,90,8|0,0:0|1:0,0:0:0:0: -36,284,66230,1,0,0:0:0:0: -4,180,66395,1,0,1:0:0:0: -132,24,66560,1,8,0:0:0:0: -100,128,66725,1,0,0:0:0:0: -24,48,66890,5,0,1:0:0:0: -212,108,67054,1,0,0:0:0:0: -212,108,67137,1,0,0:0:0:0: -212,108,67219,2,0,L|300:92,1,90,8|0,0:0|0:0,0:0:0:0: -472,144,67549,2,0,L|384:160,1,90,0|0,0:0|1:0,0:0:0:0: -196,216,67879,2,0,P|240:216|288:240,1,90,8|0,0:0|0:0,0:0:0:0: -324,336,68208,5,0,1:0:0:0: -144,288,68373,1,0,0:0:0:0: -58,170,68538,1,8,0:0:0:0: -196,215,68703,1,0,1:0:0:0: -58,260,68868,1,0,0:0:0:0: -144,142,69032,2,0,L|138:108,2,30,0|0|0,1:0|0:0|0:0,0:0:0:0: -144,142,69197,2,0,P|184:124|232:132,1,90,8|0,0:0|0:0,0:0:0:0: -312,248,69527,6,0,L|324:338,1,90,0|0,1:0|0:0,0:0:0:0: -436,248,69857,1,8,0:0:0:0: -432,216,69939,1,0,0:0:0:0: -428,184,70021,1,0,0:0:0:0: -328,120,70186,1,0,0:0:0:0: -324,152,70269,1,0,0:0:0:0: -320,184,70351,1,0,1:0:0:0: -316,216,70434,1,0,0:0:0:0: -312,248,70516,2,0,L|320:300,1,45,8|0,0:0|0:0,0:0:0:0: -244,340,70681,2,0,L|237:295,1,45,0|0,0:0|0:0,0:0:0:0: -216,224,70846,6,0,P|168:216|124:224,1,90,0|0,1:0|0:0,0:0:0:0: -40,288,71175,1,8,0:0:0:0: -2,95,71340,2,0,P|-4:139|4:184,1,90,0|0,1:0|0:0,0:0:0:0: -164,304,71670,1,0,1:0:0:0: -312,248,71835,1,8,0:0:0:0: -244,340,71999,1,0,0:0:0:0: -216,224,72164,6,0,L|228:132,1,90,0|0,1:0|0:0,0:0:0:0: -332,148,72494,2,0,L|344:56,1,90,8|0,0:0|0:0,0:0:0:0: -312,248,72824,1,0,0:0:0:0: -164,304,72988,1,0,1:0:0:0: -332,336,73153,1,8,0:0:0:0: -360,324,73236,1,0,0:0:0:0: -384,304,73318,1,0,0:0:0:0: -399,276,73401,1,0,0:0:0:0: -403,244,73483,6,0,L|396:200,3,45,4|0|2|0,1:2|0:0|0:0|1:0,0:0:0:0: -420,112,73813,2,0,L|427:68,3,45,2|0|2|0,1:2|0:0|1:2|0:0,0:0:0:0: -352,16,74142,2,0,L|345:60,3,45,0|0|2|0,0:0|1:0|1:2|0:0,0:0:0:0: -332,148,74472,1,2,1:2:0:0: -332,148,74554,1,0,1:0:0:0: -332,148,74637,1,2,1:2:0:0: -332,148,74719,1,0,1:0:0:0: -332,148,74802,6,0,P|360:216|320:312,1,180,4|2,1:2|0:3,0:0:0:0: -190,310,75296,2,0,P|151:231|180:148,1,180,4|0,1:2|0:0,0:0:0:0: -256,56,75791,1,0,0:0:0:0: -332,148,75956,1,2,0:3:0:0: -179,148,76120,5,4,1:2:0:0: -336,64,76285,1,4,1:2:0:0: -256,224,76450,1,2,0:3:0:0: -176,64,76615,1,4,1:2:0:0: -256,140,76780,2,0,L|256:324,1,180,2|0,0:0|0:0,0:0:0:0: -364,300,77274,1,2,0:3:0:0: -148,300,77439,6,0,P|104:316|76:356,1,90,4|0,1:2|0:0,0:0:0:0: -24,252,77769,2,0,L|16:208,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -96,212,78098,2,0,L|104:168,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -32,128,78428,2,0,L|24:84,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -104,88,78758,5,2,1:2:0:0: -204,132,78923,1,0,0:0:0:0: -236,124,79005,1,0,0:0:0:0: -268,116,79087,2,0,L|280:68,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -348,100,79417,2,0,L|360:52,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -428,84,79747,1,8,1:2:0:0: -460,76,79829,1,0,1:0:0:0: -492,68,79912,1,0,1:0:0:0: -492,260,80076,6,0,P|400:248|328:296,1,180,4|2,1:2|0:3,0:0:0:0: -144,236,80571,2,0,P|236:248|308:200,1,180,4|0,1:2|0:0,0:0:0:0: -348,100,81065,2,0,P|348:56|336:8,1,90,0|2,0:0|0:3,0:0:0:0: -140,48,81395,5,4,1:2:0:0: -244,68,81560,1,4,1:2:0:0: -144,236,81725,1,2,0:3:0:0: -176,133,81890,1,4,1:2:0:0: -184,304,82054,2,0,P|100:300|68:220,1,180,2|0,0:0|0:0,0:0:0:0: -100,116,82549,1,2,0:3:0:0: -264,244,82714,6,0,L|272:340,1,90,4|0,1:2|0:0,0:0:0:0: -380,316,83043,1,8,0:0:0:0: -396,288,83126,1,0,0:0:0:0: -400,256,83208,1,0,0:0:0:0: -396,224,83291,1,0,0:0:0:0: -380,196,83373,2,0,L|336:176,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -272,148,83703,1,8,0:0:0:0: -256,120,83785,1,0,0:0:0:0: -252,88,83868,1,0,0:0:0:0: -256,56,83950,1,0,0:0:0:0: -272,28,84032,6,0,L|316:8,3,45,2|0|0|0,1:2|0:0|0:0|0:0,0:0:0:0: -360,72,84362,2,0,L|408:72,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -421,149,84692,2,0,L|464:169,3,45,2|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -443,244,85021,2,0,L|473:281,3,45,8|0|0|0,1:2|1:0|0:0|0:0,0:0:0:0: -422,339,85351,6,0,L|240:348,1,180,4|2,1:2|0:3,0:0:0:0: -76,172,85846,2,0,L|255:163,1,180,4|0,1:2|0:0,0:0:0:0: -421,149,86340,2,0,P|435:107|428:56,1,90,0|2,0:0|0:3,0:0:0:0: -228,56,86670,5,4,1:2:0:0: -280,192,86835,1,4,1:2:0:0: -328,96,86999,1,2,0:3:0:0: -180,152,87164,1,4,1:2:0:0: -28,100,87330,2,0,P|16:56|20:8,1,90,2|0,0:0|0:0,0:0:0:0: -0,180,87659,1,0,0:0:0:0: -28,284,87824,1,2,0:3:0:0: -108,352,87988,6,0,P|152:360|196:356,1,90,4|0,1:2|0:0,0:0:0:0: -276,284,88318,1,8,0:0:0:0: -304,272,88401,1,0,0:0:0:0: -336,268,88483,1,0,0:0:0:0: -368,272,88565,1,0,0:0:0:0: -396,284,88648,2,0,L|432:312,1,45,0|0,0:0|0:0,0:0:0:0: -488,252,88813,2,0,L|452:224,1,45,0|0,1:0|0:0,0:0:0:0: -400,164,88977,2,0,L|396:116,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -316,64,89307,6,0,L|320:160,1,90,2|0,1:2|0:0,0:0:0:0: -276,284,89637,1,8,0:0:0:0: -248,296,89719,1,0,0:0:0:0: -216,300,89802,1,0,1:0:0:0: -184,296,89884,1,0,0:0:0:0: -156,284,89966,2,0,L|120:256,1,45,0|0,0:0|0:0,0:0:0:0: -176,200,90131,2,0,L|140:172,1,45,0|0,1:0|0:0,0:0:0:0: -196,116,90296,2,0,L|160:88,3,45,8|0|0|0,1:2|1:0|1:0|0:0,0:0:0:0: -92,44,90626,6,0,P|48:44|24:160,1,180,4|2,1:2|0:3,0:0:0:0: -156,284,91120,2,0,B|200:300|244:284|244:284|288:268|332:284,1,180,4|0,1:2|0:0,0:0:0:0: -176,200,91615,2,0,P|176:156|196:116,1,90,0|2,0:0|0:3,0:0:0:0: -264,28,91945,6,0,L|353:39,1,90,4|0,1:2|1:0,0:0:0:0: -453,159,92274,2,0,L|364:148,1,90,2|4,0:3|1:2,0:0:0:0: -268,196,92604,2,0,P|260:268|328:348,1,180,2|0,0:0|0:0,0:0:0:0: -364,248,93098,1,2,0:3:0:0: -176,200,93263,5,4,1:2:0:0: -72,228,93428,1,0,1:0:0:0: -152,92,93593,1,0,1:0:0:0: -256,64,93758,1,0,1:0:0:0: -336,200,93923,5,0,1:0:0:0: -440,228,94087,1,0,1:0:0:0: -360,92,94252,1,0,1:0:0:0: -256,64,94417,1,0,1:0:0:0: -176,200,94582,5,2,1:2:0:0: -168,228,94664,1,0,1:0:0:0: -168,260,94747,1,0,1:0:0:0: -172,292,94829,1,0,1:0:0:0: -192,316,94912,1,0,1:0:0:0: -220,328,94994,1,0,1:0:0:0: -252,332,95076,1,0,1:0:0:0: -280,320,95159,1,0,1:0:0:0: -300,296,95241,2,0,L|308:248,3,45,2|0|0|0,1:2|1:0|1:0|1:0,0:0:0:0: -312,172,95571,2,0,L|304:127,3,45,0|0|0|0,1:0|1:0|1:0|1:0,0:0:0:0: -256,64,95901,6,0,P|208:56|164:60,1,90,4|0,1:2|0:0,0:0:0:0: -76,116,96230,1,8,0:0:0:0: -60,224,96395,1,0,0:0:0:0: -60,224,96477,1,0,0:0:0:0: -160,184,96642,1,0,0:0:0:0: -160,184,96725,1,0,1:0:0:0: -63,26,96890,2,0,L|76:116,1,90,8|0,0:0|0:0,0:0:0:0: -136,272,97219,5,0,1:0:0:0: -168,268,97302,1,0,0:0:0:0: -200,264,97384,1,0,0:0:0:0: -232,260,97466,1,0,0:0:0:0: -264,256,97549,1,8,0:0:0:0: -384,136,97714,1,0,1:0:0:0: -376,168,97796,1,0,0:0:0:0: -380,200,97879,1,0,0:0:0:0: -392,228,97961,1,0,0:0:0:0: -416,248,98043,2,0,P|464:260|512:260,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: -231,105,98538,6,0,L|188:116,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -376,56,98868,2,0,L|420:64,1,45,8|0,0:0|0:0,0:0:0:0: -384,136,99032,1,0,0:0:0:0: -384,136,99115,2,0,P|340:128|304:92,1,90,0|0,0:0|0:0,0:0:0:0: -303,18,99362,2,0,L|207:26,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: -452,88,99857,5,0,1:0:0:0: -465,116,99939,1,0,0:0:0:0: -466,147,100021,1,0,0:0:0:0: -456,177,100104,1,0,0:0:0:0: -436,201,100186,2,0,P|416:213|389:216,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -320,188,100516,2,0,P|300:176|273:173,3,45,0|0|0|0,0:0|1:0|1:0|0:0,0:0:0:0: -204,200,100846,2,0,P|192:220|189:247,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -188,320,101175,6,0,P|143:322|100:310,1,90,0|0,1:0|0:0,0:0:0:0: -76,292,101423,1,0,0:0:0:0: -76,292,101505,1,8,0:0:0:0: -76,292,101587,2,0,L|72:248,1,45 -12,68,101835,2,0,L|6:24,2,45,0|0|0,0:0|0:0|1:0,0:0:0:0: -104,140,102164,2,0,L|171:132,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -224,124,102494,6,0,P|236:164|232:216,1,90,0|0,1:0|0:0,0:0:0:0: -288,296,102824,1,8,0:0:0:0: -288,296,102906,1,0,0:0:0:0: -288,296,102988,2,0,P|328:284|380:288,1,90,0|0,1:0|0:0,0:0:0:0: -404,304,103236,1,0,0:0:0:0: -424,328,103318,1,0,1:0:0:0: -448,188,103483,2,0,L|440:140,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -424,72,103813,5,0,1:0:0:0: -324,112,103977,1,0,0:0:0:0: -324,112,104060,1,0,0:0:0:0: -324,112,104142,2,0,P|280:116|232:104,1,90,8|0,0:0|0:0,0:0:0:0: -160,28,104472,1,0,0:0:0:0: -216,208,104637,1,0,1:0:0:0: -216,208,104719,1,0,0:0:0:0: -216,208,104802,1,8,0:0:0:0: -352,240,104966,1,0,0:0:0:0: -384,244,105049,1,0,0:0:0:0: -416,248,105131,6,0,L|460:240,4,45,0|0|0|0|8,1:0|0:0|0:0|0:0|0:0,0:0:0:0: -272,288,105626,1,0,1:0:0:0: -264,320,105708,1,0,0:0:0:0: -256,352,105791,2,0,L|204:356,5,30,0|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: -156,332,106120,2,0,L|104:336,5,30,8|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: -56,312,106450,5,4,1:2:0:0: -4,188,106615,1,0,0:0:0:0: -168,220,106780,2,0,P|127:232|79:228,1,90,8|0,0:0|0:0,0:0:0:0: -112,124,107109,1,0,0:0:0:0: -272,216,107274,2,0,L|264:316,1,90,0|8,1:0|0:0,0:0:0:0: -400,268,107604,1,0,0:0:0:0: -428,132,107769,5,0,1:0:0:0: -428,132,107851,1,0,0:0:0:0: -428,132,107934,1,0,0:0:0:0: -428,132,108016,1,0,0:0:0:0: -428,132,108098,1,8,0:0:0:0: -332,84,108263,2,0,P|288:80|232:88,1,90,0|0,1:0|0:0,0:0:0:0: -112,124,108593,1,0,1:0:0:0: -148,264,108758,1,8,0:0:0:0: -16,236,108923,1,0,0:0:0:0: -264,126,109087,6,0,L|272:216,1,90,0|0,1:0|0:0,0:0:0:0: -452,224,109417,2,0,L|460:320,1,90,8|0,0:0|0:0,0:0:0:0: -360,232,109747,1,0,0:0:0:0: -348,56,109912,1,0,1:0:0:0: -416,140,110076,1,8,0:0:0:0: -256,112,110241,2,0,P|212:120|160:112,1,90,0|0,0:0|1:0,0:0:0:0: -348,56,110571,6,0,L|331:150,1,90,0|8,0:0|0:0,0:0:0:0: -208,328,110901,2,0,L|191:239,1,90,0|0,1:0|0:0,0:0:0:0: -184,216,111148,1,0,1:0:0:0: -178,194,111230,1,0,1:0:0:0: -68,272,111395,1,8,0:0:0:0: -56,136,111560,1,0,1:0:0:0: -178,194,111725,6,0,P|219:203|267:199,1,90,4|0,1:2|0:0,0:0:0:0: -364,148,112054,1,8,0:0:0:0: -384,256,112219,2,0,P|406:291|443:322,1,90,0|0,0:0|0:0,0:0:0:0: -488,224,112549,1,0,1:0:0:0: -304,232,112714,2,0,L|208:224,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: -208,328,113208,6,0,L|112:320,1,90,0|8,0:0|0:0,0:0:0:0: -26,184,113538,2,0,L|116:192,1,90,0|0,1:0|0:0,0:0:0:0: -304,232,113868,1,0,1:0:0:0: -116,192,114032,1,8,0:0:0:0: -224,132,114197,1,0,0:0:0:0: -208,328,114362,6,0,B|272:360|320:312|320:312|340:368,1,180,4|8,1:2|0:0,0:0:0:0: -304,232,114857,2,0,P|300:184|308:140,1,90,0|0,0:0|0:0,0:0:0:0: -384,64,115186,1,0,1:0:0:0: -307,143,115351,1,8,0:0:0:0: -256,48,115516,1,0,0:0:0:0: -456,24,115681,6,0,B|482:101|420:136|420:136|440:184,1,180,4|8,1:2|0:0,0:0:0:0: -384,64,116175,2,0,P|340:56|296:64,1,90,0|0,1:0|0:0,0:0:0:0: -211,171,116505,1,0,1:0:0:0: -439,181,116670,2,0,L|448:84,1,90,8|0,0:0|0:0,0:0:0:0: -372,296,116999,6,2,L|304:292,1,67.5000025749208,2|0,0:1|0:0,0:0:0:0: -136,252,117329,6,2,P|196:260|212:172,1,168.75,0|0,0:0|0:0,0:0:0:0: -192,148,117659,1,2,0:3:0:0: -164,132,117741,1,2,0:3:0:0: -132,124,117824,1,2,1:3:0:0: -100,132,117906,1,2,0:3:0:0: -72,148,117988,2,0,L|52:56,1,90,2|8,0:3|0:0,0:0:0:0: -36,244,118318,5,0,1:0:0:0: -76,344,118483,1,0,1:0:0:0: -184,352,118648,1,0,1:0:0:0: -244,264,118813,1,0,1:0:0:0: -244,264,118895,1,0,1:0:0:0: -244,264,118977,2,0,L|288:260,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -332,328,119307,2,0,L|376:324,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -412,252,119637,5,4,1:2:0:0: -256,192,119719,12,0,122274,0:0:0:0: -256,192,140735,6,0,L|228:156,1,45,4|0,1:2|0:0,0:0:0:0: -152,132,141065,2,0,P|129:129|104:136,1,45 -48,192,141395,2,0,P|40:236|52:280,1,90,8|8,0:0|0:0,0:0:0:0: -196,352,142054,6,0,L|308:340,1,90,8|8,0:0|1:2,0:0:0:0: -336,280,142549,1,0,0:0:0:0: -404,324,142713,1,8,0:0:0:0: -404,324,142878,1,8,0:0:0:0: -292,120,143373,5,0,1:0:0:0: -212,104,143538,1,0,0:0:0:0: -140,140,143702,1,0,0:0:0:0: -120,220,143867,1,0,0:0:0:0: -144,296,144032,2,0,P|184:320|228:316,1,90,10|8,0:0|0:0,0:0:0:0: -372,212,144691,6,0,P|327:209|290:232,1,90,10|8,0:0|1:2,0:0:0:0: -348,288,145186,1,0,0:0:0:0: -452,220,145351,1,10,0:0:0:0: -452,220,145516,1,8,0:0:0:0: -328,36,146010,5,2,1:2:0:0: -264,88,146175,1,0,0:0:0:0: -184,108,146340,1,0,0:0:0:0: -104,88,146505,1,0,0:0:0:0: -44,36,146669,1,8,0:0:0:0: -44,36,146999,1,8,0:0:0:0: -44,36,147329,6,0,L|24:84,1,45,8|0,0:0|0:0,0:0:0:0: -52,156,147658,2,0,L|71:204,1,45,8|0,1:2|0:0,0:0:0:0: -144,236,147988,1,8,0:0:0:0: -144,236,148153,1,8,0:0:0:0: -316,64,148647,5,0,1:0:0:0: -380,116,148812,1,0,0:0:0:0: -408,192,148977,1,0,0:0:0:0: -380,268,149142,1,0,0:0:0:0: -316,320,149307,2,0,L|224:316,1,90,10|8,0:0|0:0,0:0:0:0: -64,248,149966,5,10,0:0:0:0: -144,236,150131,1,0,0:0:0:0: -188,168,150296,1,8,1:2:0:0: -192,88,150461,1,0,0:0:0:0: -140,24,150626,2,0,P|120:16|96:20,1,45,10|0,0:0|0:0,0:0:0:0: -260,132,150955,2,0,P|280:140|304:136,1,45,2|0,0:0|0:0,0:0:0:0: -476,48,151285,6,0,L|484:160,1,112.5,4|0,1:2|0:0,0:0:0:0: -464,236,151779,1,0,0:0:0:0: -436,308,151944,2,0,P|380:320|324:308,1,112.5,8|8,0:0|0:0,0:0:0:0: -76,308,152604,6,0,P|132:320|188:308,1,112.5,8|8,0:0|1:2,0:0:0:0: -256,88,153263,1,8,0:0:0:0: -256,168,153428,1,8,0:0:0:0: -256,168,153922,5,4,1:2:0:0: -256,248,154087,1,0,0:0:0:0: -324,128,154252,1,0,0:0:0:0: -188,128,154417,1,0,0:0:0:0: -332,212,154582,2,0,L|388:204,1,56.25,10|0,0:0|0:0,0:0:0:0: -492,152,154911,2,0,L|436:144,1,56.25,8|0,0:0|0:0,0:0:0:0: -324,128,155241,5,10,0:0:0:0: -180,212,155406,1,0,0:0:0:0: -332,212,155571,1,8,1:2:0:0: -188,128,155735,1,0,0:0:0:0: -256,248,155900,1,10,0:0:0:0: -256,248,156065,2,0,L|256:304,2,56.25,0|0|0,0:0|0:0|0:0,0:0:0:0: -180,212,156560,6,0,L|124:204,1,56.25,4|0,1:2|0:0,0:0:0:0: -20,152,156889,2,0,L|76:144,1,56.25,0|0,0:0|0:0,0:0:0:0: -188,128,157219,2,0,P|212:72|192:16,1,112.5,8|8,0:0|0:0,0:0:0:0: -132,72,157713,1,0,0:0:0:0: -180,212,157878,6,0,L|236:208,1,56.25,8|0,0:0|0:0,0:0:0:0: -360,252,158208,2,8,L|304:248,1,56.25,8|0,1:2|0:0,0:0:0:0: -168,292,158538,2,0,L|160:356,2,56.25,8|8|0,0:0|0:0|0:0,0:0:0:0: -180,212,159032,1,0,0:0:0:0: -144,140,159197,6,0,P|104:128|36:148,1,112.5,2|0,1:2|0:0,0:0:0:0: -12,220,159691,1,0,0:0:0:0: -36,296,159856,2,0,P|60:316|92:324,1,56.25,8|0,0:0|0:0,0:0:0:0: -215,264,160186,2,0,P|189:273|168:292,1,56.25,8|0,0:0|0:0,0:0:0:0: -228,344,160516,6,0,L|284:340,1,56.25,10|0,0:0|0:0,0:0:0:0: -328,276,160845,2,0,L|384:272,1,56.25,8|0,1:2|0:0,0:0:0:0: -428,208,161175,1,8,0:0:0:0: -440,128,161340,1,8,0:0:0:0: -400,60,161505,1,2,0:0:0:0: -328,28,161669,1,0,0:0:0:0: -212,76,161834,6,0,P|200:120|208:164,1,90,2|0,1:2|1:0,0:0:0:0: -300,308,162163,2,0,P|312:264|304:220,1,90,2|0,1:2|1:0,0:0:0:0: -140,236,162493,2,0,P|184:248|228:240,1,90,2|0,1:2|1:0,0:0:0:0: -372,148,162823,2,0,P|328:136|284:144,1,90,2|0,1:2|1:0,0:0:0:0: -104,316,163152,5,2,1:2:0:0: -78,297,163235,1,0,1:0:0:0: -60,270,163317,1,0,1:0:0:0: -54,239,163399,1,0,1:0:0:0: -58,207,163482,1,2,1:2:0:0: -74,180,163564,1,0,1:0:0:0: -98,159,163647,1,0,1:0:0:0: -127,149,163729,1,0,1:0:0:0: -158,150,163812,2,0,L|208:160,1,45,2|0,1:2|1:0,0:0:0:0: -344,184,163976,2,0,L|294:194,1,45,0|0,1:0|1:0,0:0:0:0: -140,236,164141,1,4,1:2:0:0: -140,236,164471,6,0,L|232:252,1,90,4|0,1:2|0:0,0:0:0:0: -344,184,164801,1,8,0:0:0:0: -380,284,164965,1,0,0:0:0:0: -368,104,165130,2,0,P|324:104|284:128,1,90,0|0,0:0|1:0,0:0:0:0: -356,360,165460,2,0,P|400:360|440:336,1,90,8|0,0:0|0:0,0:0:0:0: -432,208,165790,5,0,1:0:0:0: -292,260,165954,1,0,0:0:0:0: -344,184,166119,1,8,0:0:0:0: -204,236,166284,1,0,1:0:0:0: -204,236,166366,1,0,0:0:0:0: -204,236,166449,2,0,L|216:328,1,90,0|0,0:0|1:0,0:0:0:0: -120,208,166779,2,0,L|131:118,1,90,8|0,0:0|0:0,0:0:0:0: -204,236,167108,5,0,1:0:0:0: -32,216,167273,1,0,0:0:0:0: -130,118,167438,1,8,0:0:0:0: -110,298,167603,1,0,0:0:0:0: -110,298,167685,1,0,0:0:0:0: -110,298,167768,2,0,L|121:208,1,90,0|0,0:0|1:0,0:0:0:0: -304,40,168097,2,0,L|315:130,1,90,8|0,0:0|0:0,0:0:0:0: -328,236,168427,5,0,1:0:0:0: -184,148,168592,1,0,0:0:0:0: -314,129,168757,1,8,0:0:0:0: -197,254,168921,1,0,1:0:0:0: -197,254,169004,1,0,0:0:0:0: -197,254,169086,2,0,P|220:292|260:312,1,90,0|0,0:0|1:0,0:0:0:0: -409,210,169416,2,0,P|365:211|328:236,1,90,8|0,0:0|0:0,0:0:0:0: -488,232,169746,6,0,P|487:192|464:149,1,90,0|0,1:0|0:0,0:0:0:0: -314,129,170075,1,8,0:0:0:0: -409,210,170240,1,0,0:0:0:0: -332,40,170405,2,0,L|240:36,1,90,0|0,0:0|1:0,0:0:0:0: -68,144,170735,2,0,L|157:140,1,90,8|0,0:0|0:0,0:0:0:0: -314,129,171064,5,0,1:0:0:0: -332,40,171229,1,0,0:0:0:0: -324,216,171394,1,8,0:0:0:0: -306,305,171559,1,0,1:0:0:0: -257,178,171724,1,0,0:0:0:0: -168,160,171888,1,0,1:0:0:0: -384,164,172053,1,8,0:0:0:0: -473,182,172218,1,0,0:0:0:0: -306,305,172383,6,0,L|216:312,1,90,0|0,1:0|0:0,0:0:0:0: -60,172,172713,1,8,0:0:0:0: -120,260,172877,1,0,0:0:0:0: -168,160,173042,2,0,L|172:68,1,90,0|0,0:0|1:0,0:0:0:0: -309,216,173372,2,0,L|306:306,1,90,8|0,0:0|0:0,0:0:0:0: -120,260,173702,5,0,1:0:0:0: -152,256,173784,1,0,1:0:0:0: -184,252,173866,1,0,1:0:0:0: -309,216,174031,1,8,0:0:0:0: -103,168,174196,1,0,1:0:0:0: -135,164,174279,1,0,1:0:0:0: -167,160,174361,1,0,1:0:0:0: -292,124,174526,1,0,1:0:0:0: -87,76,174691,1,8,1:2:0:0: -119,72,174773,1,0,1:0:0:0: -151,68,174855,1,0,1:0:0:0: -276,32,175020,6,0,L|368:40,1,90,0|0,1:0|0:0,0:0:0:0: -448,108,175350,1,8,0:0:0:0: -292,124,175515,1,0,0:0:0:0: -292,124,175597,1,0,0:0:0:0: -292,124,175680,2,0,L|308:216,1,90,0|0,0:0|1:0,0:0:0:0: -328,320,176009,1,8,0:0:0:0: -408,248,176174,1,0,0:0:0:0: -220,300,176339,6,0,P|176:304|128:292,1,90,0|0,1:0|0:0,0:0:0:0: -16,120,176669,1,8,0:0:0:0: -120,152,176834,1,0,1:0:0:0: -120,152,176916,1,0,0:0:0:0: -120,152,176998,2,0,L|124:200,1,45 -212,176,177163,2,0,L|239:215,1,45,0|0,1:0|0:0,0:0:0:0: -292,124,177328,2,0,P|302:79|283:30,1,90,8|0,0:0|0:0,0:0:0:0: -344,192,177658,6,0,P|372:156|376:104,1,90,0|0,1:0|0:0,0:0:0:0: -212,88,177987,1,8,0:0:0:0: -272,228,178152,1,0,0:0:0:0: -272,228,178235,1,0,0:0:0:0: -272,228,178317,1,0,0:0:0:0: -292,124,178482,1,0,1:0:0:0: -180,180,178647,1,8,0:0:0:0: -200,284,178812,1,0,0:0:0:0: -292,124,178976,5,0,1:0:0:0: -288,92,179059,1,0,0:0:0:0: -280,60,179141,2,0,P|248:24|208:14,1,90,0|8,0:0|0:0,0:0:0:0: -22,65,179471,2,0,P|67:71|112:68,1,90,0|0,1:0|0:0,0:0:0:0: -212,88,179801,1,0,1:0:0:0: -22,65,179965,1,8,0:0:0:0: -180,180,180130,5,0,0:0:0:0: -180,180,180213,1,0,0:0:0:0: -180,180,180295,2,0,P|184:224|172:272,1,90,0|0,1:0|0:0,0:0:0:0: -76,216,180625,2,0,P|72:172|84:124,1,90,8|0,0:0|0:0,0:0:0:0: -380,240,180954,2,0,P|384:284|372:332,1,90,0|0,0:0|1:0,0:0:0:0: -276,276,181284,2,0,P|272:232|284:184,1,90,8|0,0:0|0:0,0:0:0:0: -374,129,181614,5,0,1:0:0:0: -300,352,181779,2,0,L|204:348,2,90,0|8|0,0:0|0:0|1:0,0:0:0:0: -448,180,182273,1,2,0:0:0:0: -448,180,182438,1,2,1:2:0:0: -276,276,182603,1,10,0:0:0:0: -276,276,182768,1,2,0:0:0:0: -96,200,182932,6,0,L|88:108,1,90,0|0,1:0|0:0,0:0:0:0: -96,200,183262,1,8,0:0:0:0: -12,68,183427,2,0,P|72:24|164:68,1,180,0|0,0:0|1:0,0:0:0:0: -140,272,183921,2,0,P|92:284|52:271,1,90,8|0,0:0|0:0,0:0:0:0: -176,156,184251,5,0,1:0:0:0: -208,152,184334,1,0,1:0:0:0: -240,148,184416,1,0,1:0:0:0: -308,64,184581,1,8,0:0:0:0: -296,240,184746,1,0,1:0:0:0: -312,268,184828,1,0,1:0:0:0: -336,284,184910,1,0,1:0:0:0: -368,292,184993,1,0,1:0:0:0: -400,288,185075,1,0,1:0:0:0: -464,184,185240,1,8,0:0:0:0: -468,152,185323,1,0,0:0:0:0: -472,120,185405,2,0,L|464:76,1,45,0|0,1:0|1:0,0:0:0:0: -388,96,185570,6,0,P|360:132|316:148,1,90,4|0,1:2|0:0,0:0:0:0: -224,46,185899,2,0,P|268:43|308:63,1,90,8|0,0:0|0:0,0:0:0:0: -296,240,186229,1,0,0:0:0:0: -308,64,186394,1,0,1:0:0:0: -296,240,186559,2,0,L|312:332,1,90,8|0,0:0|0:0,0:0:0:0: -464,184,186888,6,0,P|420:180|372:188,1,90,0|0,1:0|0:0,0:0:0:0: -296,240,187218,1,8,0:0:0:0: -136,292,187383,2,0,P|94:277|54:249,1,90,0|0,1:0|0:0,0:0:0:0: -21,159,187713,1,0,1:0:0:0: -104,8,187877,2,0,L|124:96,1,90,10|0,0:0|0:0,0:0:0:0: -124,96,188207,6,0,P|152:132|196:148,1,90,0|0,1:0|0:0,0:0:0:0: -287,46,188537,2,0,P|243:43|204:63,1,90,8|0,0:0|0:0,0:0:0:0: -216,240,188866,1,2,0:0:0:0: -204,64,189031,1,0,1:0:0:0: -216,240,189196,2,0,L|200:332,1,90,8|0,0:0|0:0,0:0:0:0: -40,240,189526,5,2,1:2:0:0: -128,192,189691,1,0,0:0:0:0: -216,240,189855,1,8,0:0:0:0: -304,192,190020,1,0,1:0:0:0: -392,240,190185,2,0,L|400:332,1,90,2|0,0:0|1:0,0:0:0:0: -464,168,190515,2,0,L|456:76,1,90,8|0,0:0|0:0,0:0:0:0: -392,240,190844,6,0,P|364:272|312:292,1,90,2|0,1:2|0:0,0:0:0:0: -220,140,191174,2,0,P|248:108|296:92,1,90,8|0,0:0|0:0,0:0:0:0: -324,96,191421,1,0,0:0:0:0: -356,104,191504,2,0,L|340:16,1,90,0|0,0:0|1:0,0:0:0:0: -256,276,191834,2,0,L|272:364,1,90,8|0,0:0|0:0,0:0:0:0: -392,240,192163,5,0,1:0:0:0: -356,104,192328,1,0,0:0:0:0: -220,140,192493,1,8,0:0:0:0: -256,276,192658,1,0,1:0:0:0: -305,191,192823,1,0,0:0:0:0: -212,56,192987,1,0,1:0:0:0: -200,220,193152,1,10,0:0:0:0: -200,220,193482,6,0,P|156:228|108:220,1,90,0|0,1:0|0:0,0:0:0:0: -88,116,193812,1,8,0:0:0:0: -16,192,193976,1,0,0:0:0:0: -16,192,194059,1,0,0:0:0:0: -16,192,194141,2,0,L|28:288,1,90,2|0,0:0|1:0,0:0:0:0: -188,309,194471,2,0,L|200:220,1,90,8|0,0:0|0:0,0:0:0:0: -216,112,194801,5,2,1:2:0:0: -216,112,194883,1,0,1:0:0:0: -216,112,194965,1,0,1:0:0:0: -361,25,195130,1,8,0:0:0:0: -294,180,195295,1,0,1:0:0:0: -294,180,195377,1,0,1:0:0:0: -294,180,195460,1,2,0:0:0:0: -256,16,195625,1,0,1:0:0:0: -384,127,195790,1,10,1:2:0:0: -416,132,195872,1,0,1:0:0:0: -448,140,195954,2,0,L|452:84,1,45,0|0,1:0|1:0,0:0:0:0: -416,216,196119,6,0,P|412:264|432:312,1,90,4|0,1:2|0:0,0:0:0:0: -304,268,196449,2,0,P|308:220|288:172,1,90,8|0,0:0|0:0,0:0:0:0: -216,112,196779,2,0,L|120:104,1,90,0|0,0:0|1:0,0:0:0:0: -52,248,197108,2,0,L|141:255,1,90,8|0,0:0|0:0,0:0:0:0: -304,268,197438,5,0,1:0:0:0: -416,216,197603,1,0,0:0:0:0: -408,340,197768,1,8,0:0:0:0: -332,180,197932,1,0,1:0:0:0: -332,180,198015,1,0,0:0:0:0: -332,180,198097,2,0,P|360:140|400:120,1,90,0|0,0:0|1:0,0:0:0:0: -484,284,198427,1,10,0:0:0:0: -304,268,198592,1,2,0:0:0:0: -416,216,198757,6,0,P|428:172|420:124,1,90,2|0,1:2|0:0,0:0:0:0: -344,52,199086,1,8,0:0:0:0: -332,180,199251,1,0,0:0:0:0: -164,236,199416,2,0,P|152:192|160:144,1,90,0|0,0:0|1:0,0:0:0:0: -236,72,199746,1,8,0:0:0:0: -248,200,199910,1,0,0:0:0:0: -156,328,200075,6,0,L|56:320,1,90,2|0,1:2|0:0,0:0:0:0: -164,236,200405,1,8,0:0:0:0: -256,292,200570,2,0,P|300:296|344:284,1,90,0|0,1:0|0:0,0:0:0:0: -432,220,200899,2,0,L|460:308,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: -392,120,201394,5,4,1:2:0:0: -396,32,201559,1,0,1:0:0:0: -316,72,201724,1,0,1:0:0:0: -256,6,201888,1,0,1:0:0:0: -228,91,202053,1,0,1:0:0:0: -139,87,202218,1,0,1:0:0:0: -179,166,202383,1,0,1:0:0:0: -113,226,202548,1,0,1:0:0:0: -197,253,202713,5,4,1:2:0:0: -193,342,202877,1,0,1:0:0:0: -272,302,203042,1,0,1:0:0:0: -332,367,203207,1,0,1:0:0:0: -359,283,203372,1,2,1:2:0:0: -448,287,203537,1,2,1:2:0:0: -407,208,203702,1,2,1:2:0:0: -472,147,203866,1,2,1:2:0:0: -387,121,204031,5,4,1:2:0:0: -360,100,204114,1,0,1:0:0:0: -344,72,204196,1,0,1:0:0:0: -336,40,204279,1,0,1:0:0:0: -340,8,204361,1,0,1:0:0:0: -316,28,204443,1,0,1:0:0:0: -284,32,204526,1,0,1:0:0:0: -252,28,204608,1,0,1:0:0:0: -228,8,204691,2,0,L|184:20,7,45,4|0|0|0|0|0|0|0,1:2|1:0|1:0|1:0|1:0|1:0|1:0|1:0,0:0:0:0: -112,56,205350,5,4,1:2:0:0: -100,84,205432,1,0,1:0:0:0: -96,116,205515,1,0,1:0:0:0: -100,148,205597,1,0,1:0:0:0: -112,176,205680,1,0,1:0:0:0: -124,204,205762,1,0,1:0:0:0: -128,236,205844,1,0,1:0:0:0: -124,268,205927,1,0,1:0:0:0: -112,296,206009,2,0,L|71:313,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -192,312,206339,2,0,L|175:353,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -256,264,206669,5,4,1:2:0:0: -256,192,206751,12,0,209306,0:0:0:0: diff --git a/osu.Game.Tests/Resources/valid-events.osu b/osu.Game.Tests/Resources/valid-events.osu new file mode 100644 index 0000000000..ed3614b4ed --- /dev/null +++ b/osu.Game.Tests/Resources/valid-events.osu @@ -0,0 +1,12 @@ +osu file format v14 + +[Events] +//Background and Video events +0,0,"machinetop_background.jpg",0,0 +//Break Periods +2,122474,140135 +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples From ee6a90c48da5c6a1a9612358f68a0011e3095a4d Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 5 Aug 2019 20:43:30 -0700 Subject: [PATCH 122/645] Fix back button hover sounds playing in unclickable area --- osu.Game/Graphics/UserInterface/BackButton.cs | 4 ++-- osu.Game/Graphics/UserInterface/TwoLayerButton.cs | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index 48bf0848ae..c4735b4a16 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -22,8 +22,8 @@ namespace osu.Game.Graphics.UserInterface Child = button = new TwoLayerButton { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, Text = @"back", Icon = OsuIcon.LeftCircle, Action = () => Action?.Invoke() diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index c74d00cd1e..75d3847417 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -15,6 +15,7 @@ using System; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Game.Screens.Select; namespace osu.Game.Graphics.UserInterface { @@ -28,7 +29,9 @@ namespace osu.Game.Graphics.UserInterface private const int transform_time = 600; private const int pulse_length = 250; - private const float shear = 0.1f; + private const float SHEAR_WIDTH = 5f; + + private static readonly Vector2 shearing = new Vector2(SHEAR_WIDTH / Footer.HEIGHT, 0); public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); @@ -56,7 +59,7 @@ namespace osu.Game.Graphics.UserInterface c1.Origin = c1.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopLeft : Anchor.TopRight; c2.Origin = c2.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopRight : Anchor.TopLeft; - X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shear * 0.5f : 0; + X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shearing.X * 0.5f : 0; Remove(c1); Remove(c2); @@ -70,6 +73,7 @@ namespace osu.Game.Graphics.UserInterface public TwoLayerButton() { Size = SIZE_RETRACTED; + Shear = shearing; Children = new Drawable[] { @@ -82,7 +86,6 @@ namespace osu.Game.Graphics.UserInterface new Container { RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), Masking = true, MaskingSmoothness = 2, EdgeEffect = new EdgeEffectParameters @@ -105,6 +108,7 @@ namespace osu.Game.Graphics.UserInterface { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Shear = -shearing, }, } }, @@ -119,7 +123,6 @@ namespace osu.Game.Graphics.UserInterface new Container { RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), Masking = true, MaskingSmoothness = 2, EdgeEffect = new EdgeEffectParameters @@ -144,6 +147,7 @@ namespace osu.Game.Graphics.UserInterface { Origin = Anchor.Centre, Anchor = Anchor.Centre, + Shear = -shearing, } } }, @@ -188,7 +192,6 @@ namespace osu.Game.Graphics.UserInterface var flash = new Box { RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), Colour = Color4.White.Opacity(0.5f), }; Add(flash); From 11aa3544c49ca6c6d4adc86216eae8ac693c038b Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 5 Aug 2019 20:57:17 -0700 Subject: [PATCH 123/645] Fix shear width naming --- osu.Game/Graphics/UserInterface/TwoLayerButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index 75d3847417..b56dd201c2 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -29,9 +29,9 @@ namespace osu.Game.Graphics.UserInterface private const int transform_time = 600; private const int pulse_length = 250; - private const float SHEAR_WIDTH = 5f; + private const float shear_width = 5f; - private static readonly Vector2 shearing = new Vector2(SHEAR_WIDTH / Footer.HEIGHT, 0); + private static readonly Vector2 shearing = new Vector2(shear_width / Footer.HEIGHT, 0); public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); From dd701eaa6292586c181b35a9cc79bc1e0e677732 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 6 Aug 2019 14:10:03 +0300 Subject: [PATCH 124/645] Safely cancel the completion task on restart or immediate exit --- osu.Game/Screens/Play/Player.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8dc16af575..2f7f793bbf 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -255,7 +255,7 @@ namespace osu.Game.Screens.Play private void performImmediateExit() { // if a restart has been requested, cancel any pending completion (user has shown intent to restart). - onCompletionEvent = null; + onCompletionEvent?.Cancel(); ValidForResume = false; @@ -275,12 +275,8 @@ namespace osu.Game.Screens.Play sampleRestart?.Play(); - // if a restart has been requested, cancel any pending completion (user has shown intent to restart). - onCompletionEvent = null; - - ValidForResume = false; RestartRequested?.Invoke(); - this.Exit(); + performImmediateExit(); } private ScheduledDelegate onCompletionEvent; @@ -306,8 +302,6 @@ namespace osu.Game.Screens.Play scoreManager.Import(score).Wait(); this.Push(CreateResults(score)); - - onCompletionEvent = null; }); } } @@ -471,9 +465,9 @@ namespace osu.Game.Screens.Play public override bool OnExiting(IScreen next) { - if (onCompletionEvent != null) + if (onCompletionEvent != null && !onCompletionEvent.Cancelled && !onCompletionEvent.Completed) + // proceed to result screen if beatmap already finished playing { - // Proceed to result screen if beatmap already finished playing onCompletionEvent.RunTask(); return true; } From 2a68bb2749bf36bc632a1881f124dbbdcc592c96 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 6 Aug 2019 14:11:43 +0300 Subject: [PATCH 125/645] onCompletionEvent -> pushResults --- osu.Game/Screens/Play/Player.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2f7f793bbf..d0ef3bc104 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -255,7 +255,7 @@ namespace osu.Game.Screens.Play private void performImmediateExit() { // if a restart has been requested, cancel any pending completion (user has shown intent to restart). - onCompletionEvent?.Cancel(); + pushResults?.Cancel(); ValidForResume = false; @@ -279,12 +279,12 @@ namespace osu.Game.Screens.Play performImmediateExit(); } - private ScheduledDelegate onCompletionEvent; + private ScheduledDelegate pushResults; private void onCompletion() { // Only show the completion screen if the player hasn't failed - if (ScoreProcessor.HasFailed || onCompletionEvent != null) + if (ScoreProcessor.HasFailed || pushResults != null) return; ValidForResume = false; @@ -293,7 +293,7 @@ namespace osu.Game.Screens.Play using (BeginDelayedSequence(1000)) { - onCompletionEvent = Schedule(delegate + pushResults = Schedule(delegate { if (!this.IsCurrentScreen()) return; @@ -465,10 +465,10 @@ namespace osu.Game.Screens.Play public override bool OnExiting(IScreen next) { - if (onCompletionEvent != null && !onCompletionEvent.Cancelled && !onCompletionEvent.Completed) + if (pushResults != null && !pushResults.Cancelled && !pushResults.Completed) // proceed to result screen if beatmap already finished playing { - onCompletionEvent.RunTask(); + pushResults.RunTask(); return true; } From dda078277a80aa9a465c9edf7ea7b12df3e04f4d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Aug 2019 23:05:12 +0900 Subject: [PATCH 126/645] Minor variable name changes --- osu.Game/Screens/Play/Player.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d0ef3bc104..96b8073d11 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -255,7 +255,7 @@ namespace osu.Game.Screens.Play private void performImmediateExit() { // if a restart has been requested, cancel any pending completion (user has shown intent to restart). - pushResults?.Cancel(); + completionProgressDelegate?.Cancel(); ValidForResume = false; @@ -279,12 +279,12 @@ namespace osu.Game.Screens.Play performImmediateExit(); } - private ScheduledDelegate pushResults; + private ScheduledDelegate completionProgressDelegate; private void onCompletion() { // Only show the completion screen if the player hasn't failed - if (ScoreProcessor.HasFailed || pushResults != null) + if (ScoreProcessor.HasFailed || completionProgressDelegate != null) return; ValidForResume = false; @@ -293,7 +293,7 @@ namespace osu.Game.Screens.Play using (BeginDelayedSequence(1000)) { - pushResults = Schedule(delegate + completionProgressDelegate = Schedule(delegate { if (!this.IsCurrentScreen()) return; @@ -465,10 +465,10 @@ namespace osu.Game.Screens.Play public override bool OnExiting(IScreen next) { - if (pushResults != null && !pushResults.Cancelled && !pushResults.Completed) - // proceed to result screen if beatmap already finished playing + if (completionProgressDelegate != null && !completionProgressDelegate.Cancelled && !completionProgressDelegate.Completed) { - pushResults.RunTask(); + // proceed to result screen if beatmap already finished playing + completionProgressDelegate.RunTask(); return true; } From ffb6794b4ebea7651ed29418f5339964e4208ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=BCbner?= Date: Tue, 6 Aug 2019 16:11:13 +0200 Subject: [PATCH 127/645] formatting inspection --- osu.Game/Online/Chat/ChannelManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 30135d5b8b..b5d8879e50 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -222,6 +222,7 @@ namespace osu.Game.Online.Chat } var channel = availableChannels.Where(c => c.Name == content || c.Name == $"#{content}").FirstOrDefault(); + if (channel == null) { target.AddNewMessages(new ErrorMessage($"Channel '{content}' not found.")); From 3cfbbac5dc9ae96335a476b829b46de88b4f2299 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 6 Aug 2019 17:47:31 +0300 Subject: [PATCH 128/645] Expand requests --- osu.Game/Online/API/Requests/GetUserRequest.cs | 7 +++++-- .../Online/API/Requests/GetUserScoresRequest.cs | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserRequest.cs b/osu.Game/Online/API/Requests/GetUserRequest.cs index 37ed0574f1..18fb4bb7db 100644 --- a/osu.Game/Online/API/Requests/GetUserRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRequest.cs @@ -2,18 +2,21 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Users; +using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { public class GetUserRequest : APIRequest { private readonly long? userId; + private readonly RulesetInfo ruleset; - public GetUserRequest(long? userId = null) + public GetUserRequest(long? userId = null, RulesetInfo ruleset = null) { this.userId = userId; + this.ruleset = ruleset; } - protected override string Target => userId.HasValue ? $@"users/{userId}" : @"me"; + protected override string Target => userId.HasValue ? (ruleset != null ? $@"users/{userId}/{ruleset.ShortName}" : $@"users/{userId}") : @"me"; } } diff --git a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs index d41966fe1b..7b4d66e7b2 100644 --- a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs @@ -2,7 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using osu.Framework.IO.Network; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { @@ -10,12 +12,24 @@ namespace osu.Game.Online.API.Requests { private readonly long userId; private readonly ScoreType type; + private readonly RulesetInfo ruleset; - public GetUserScoresRequest(long userId, ScoreType type, int page = 0, int itemsPerPage = 5) + public GetUserScoresRequest(long userId, ScoreType type, int page = 0, int itemsPerPage = 5, RulesetInfo ruleset = null) : base(page, itemsPerPage) { this.userId = userId; this.type = type; + this.ruleset = ruleset; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + if (ruleset != null) + req.AddParameter("mode", ruleset.ShortName); + + return req; } protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLowerInvariant()}"; From 91b9a496f5c1e3a60fee8136473ee64098c94d20 Mon Sep 17 00:00:00 2001 From: Joehu Date: Tue, 6 Aug 2019 18:29:07 -0700 Subject: [PATCH 129/645] Remove now unnecessary .gitmodules and .travis.yml --- .gitmodules | 0 .travis.yml | 2 -- 2 files changed, 2 deletions(-) delete mode 100644 .gitmodules delete mode 100644 .travis.yml diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ce353d9b27..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,2 +0,0 @@ -language: csharp -solution: osu.sln \ No newline at end of file From 616de1830a4c4200fba87a0ef8758e9cea0a6907 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 12:20:49 +0900 Subject: [PATCH 130/645] Less sheep --- osu.Game/Screens/Select/FooterButton.cs | 6 +++--- osu.Game/Screens/Select/FooterButtonMods.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 15088f0eb3..c1478aa4ce 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Select { public static readonly float SHEAR_WIDTH = 7.5f; - protected static readonly Vector2 SHEARING = new Vector2(SHEAR_WIDTH / Footer.HEIGHT, 0); + protected static readonly Vector2 SHEAR = new Vector2(SHEAR_WIDTH / Footer.HEIGHT, 0); public string Text { @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Select public FooterButton() { AutoSizeAxes = Axes.Both; - Shear = SHEARING; + Shear = SHEAR; Children = new Drawable[] { box = new Box @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Select TextContainer = new Container { Size = new Vector2(100 - SHEAR_WIDTH, 50), - Shear = -SHEARING, + Shear = -SHEAR, Child = SpriteText = new OsuSpriteText { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 58d92dbca6..29b1364944 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Select { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Shear = -SHEARING, + Shear = -SHEAR, Child = modDisplay = new FooterModDisplay { DisplayUnrankedText = false, From c16e84e5e64dda14c07afe74ba14adb940b8438c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 06:35:57 +0300 Subject: [PATCH 131/645] Fix unability to get local user with specific ruleset --- osu.Game/Online/API/Requests/GetUserRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetUserRequest.cs b/osu.Game/Online/API/Requests/GetUserRequest.cs index 18fb4bb7db..acf9aefa19 100644 --- a/osu.Game/Online/API/Requests/GetUserRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRequest.cs @@ -17,6 +17,6 @@ namespace osu.Game.Online.API.Requests this.ruleset = ruleset; } - protected override string Target => userId.HasValue ? (ruleset != null ? $@"users/{userId}/{ruleset.ShortName}" : $@"users/{userId}") : @"me"; + protected override string Target => userId.HasValue ? (ruleset != null ? $@"users/{userId}/{ruleset.ShortName}" : $@"users/{userId}") : ruleset != null ? $@"me/{ruleset.ShortName}" : $@"me"; } } From 6ed9c983ff1b8f37e981764370d2f9b255a024ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 12:36:00 +0900 Subject: [PATCH 132/645] Rename shear variable --- osu.Game/Graphics/UserInterface/TwoLayerButton.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index b56dd201c2..aa96796cf1 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -31,7 +31,7 @@ namespace osu.Game.Graphics.UserInterface private const float shear_width = 5f; - private static readonly Vector2 shearing = new Vector2(shear_width / Footer.HEIGHT, 0); + private static readonly Vector2 shear = new Vector2(shear_width / Footer.HEIGHT, 0); public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); @@ -59,7 +59,7 @@ namespace osu.Game.Graphics.UserInterface c1.Origin = c1.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopLeft : Anchor.TopRight; c2.Origin = c2.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopRight : Anchor.TopLeft; - X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shearing.X * 0.5f : 0; + X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shear.X * 0.5f : 0; Remove(c1); Remove(c2); @@ -73,7 +73,7 @@ namespace osu.Game.Graphics.UserInterface public TwoLayerButton() { Size = SIZE_RETRACTED; - Shear = shearing; + Shear = shear; Children = new Drawable[] { @@ -108,7 +108,7 @@ namespace osu.Game.Graphics.UserInterface { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Shear = -shearing, + Shear = -shear, }, } }, @@ -147,7 +147,7 @@ namespace osu.Game.Graphics.UserInterface { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Shear = -shearing, + Shear = -shear, } } }, From 24f9872315e094d1526aca7226878f42911a1e59 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 06:45:39 +0300 Subject: [PATCH 133/645] Fix unnecessary scores loading --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index a6cc2b0500..ec2697447a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Scores = null; - if (beatmap?.OnlineBeatmapID.HasValue != true) + if (beatmap?.OnlineBeatmapID.HasValue != true || beatmap?.Status <= BeatmapSetOnlineStatus.Pending) return; loadingAnimation.Show(); From b1c78c43f382a6aae24e2ddcb8ac102013243999 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 06:57:46 +0300 Subject: [PATCH 134/645] Simplify target string --- osu.Game/Online/API/Requests/GetUserRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetUserRequest.cs b/osu.Game/Online/API/Requests/GetUserRequest.cs index acf9aefa19..31b7e95b39 100644 --- a/osu.Game/Online/API/Requests/GetUserRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRequest.cs @@ -17,6 +17,6 @@ namespace osu.Game.Online.API.Requests this.ruleset = ruleset; } - protected override string Target => userId.HasValue ? (ruleset != null ? $@"users/{userId}/{ruleset.ShortName}" : $@"users/{userId}") : ruleset != null ? $@"me/{ruleset.ShortName}" : $@"me"; + protected override string Target => userId.HasValue ? $@"users/{userId}/{ruleset?.ShortName}" : $@"me/{ruleset?.ShortName}"; } } From b9384d7a53cb5e59074ff2b538b90084664c3d6b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 07:00:50 +0300 Subject: [PATCH 135/645] Remove unnecessary null check --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index ec2697447a..4bbcd8d631 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Scores = null; - if (beatmap?.OnlineBeatmapID.HasValue != true || beatmap?.Status <= BeatmapSetOnlineStatus.Pending) + if (beatmap?.OnlineBeatmapID.HasValue != true || beatmap.Status <= BeatmapSetOnlineStatus.Pending) return; loadingAnimation.Show(); From b064df91a7065b1b28091208f3638418b1b4df40 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 08:33:55 +0300 Subject: [PATCH 136/645] Initial implementation --- .../TestSceneLeaderboardScopeSelector.cs | 37 +++++ .../BeatmapSet/LeaderboardScopeSelector.cs | 157 ++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs create mode 100644 osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs new file mode 100644 index 0000000000..f4c0d32946 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs @@ -0,0 +1,37 @@ +// 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.Overlays.BeatmapSet; +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Game.Screens.Select.Leaderboards; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneLeaderboardScopeSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(LeaderboardScopeSelector), + }; + + public TestSceneLeaderboardScopeSelector() + { + LeaderboardScopeSelector selector; + Bindable scope = new Bindable(); + + Add(selector = new LeaderboardScopeSelector + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Current = { BindTarget = scope } + }); + + AddStep(@"Select global", () => scope.Value = BeatmapLeaderboardScope.Global); + AddStep(@"Select country", () => scope.Value = BeatmapLeaderboardScope.Country); + AddStep(@"Select friend", () => scope.Value = BeatmapLeaderboardScope.Friend); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs new file mode 100644 index 0000000000..c74c7cbc2b --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -0,0 +1,157 @@ +// 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.UserInterface; +using osu.Game.Screens.Select.Leaderboards; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osuTK; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Sprites; +using osu.Framework.Extensions; +using osu.Game.Graphics; +using osu.Framework.Allocation; +using osuTK.Graphics; +using osu.Framework.Input.Events; +using osu.Framework.Graphics.Colour; + +namespace osu.Game.Overlays.BeatmapSet +{ + public class LeaderboardScopeSelector : TabControl + { + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(BeatmapLeaderboardScope value) => new ScopeSelectorTabItem(value); + + public LeaderboardScopeSelector() + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + + AddItem(BeatmapLeaderboardScope.Global); + AddItem(BeatmapLeaderboardScope.Country); + AddItem(BeatmapLeaderboardScope.Friend); + + AddInternal(new Line + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + }); + } + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20, 0), + }; + + private class ScopeSelectorTabItem : TabItem + { + private const float transition_duration = 100; + + private readonly Box box; + + protected readonly OsuSpriteText Text; + + public ScopeSelectorTabItem(BeatmapLeaderboardScope value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + Text = new OsuSpriteText + { + Margin = new MarginPadding { Bottom = 8 }, + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + Text = value.GetDescription() + " Ranking", + Font = OsuFont.GetFont(weight: FontWeight.Regular), + }, + box = new Box + { + RelativeSizeAxes = Axes.X, + Height = 5, + Scale = new Vector2(1f, 0f), + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + }, + new HoverClickSounds() + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + box.Colour = colours.Blue; + } + + protected override bool OnHover(HoverEvent e) + { + Text.FadeColour(Color4.LightSkyBlue); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + Text.FadeColour(Color4.White); + } + + protected override void OnActivated() + { + box.ScaleTo(new Vector2(1f), transition_duration); + Text.Font = Text.Font.With(weight: FontWeight.Black); + } + + protected override void OnDeactivated() + { + box.ScaleTo(new Vector2(1f, 0f), transition_duration); + Text.Font = Text.Font.With(weight: FontWeight.Regular); + } + } + + private class Line : GridContainer + { + public Line() + { + Height = 1; + RelativeSizeAxes = Axes.X; + Width = 0.8f; + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(mode: GridSizeMode.Relative, size: 0.4f), + new Dimension(), + }; + Content = new[] + { + new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(Color4.Transparent, Color4.Gray), + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(Color4.Gray, Color4.Transparent), + }, + } + }; + } + } + } +} From 1d42f0959af01834fbd4f86bd08c84b2f6b14932 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 08:46:27 +0300 Subject: [PATCH 137/645] ModIcon improvements --- osu.Game/Overlays/Mods/ModButton.cs | 2 +- osu.Game/Rulesets/UI/ModIcon.cs | 23 ++++++----------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index fa1ee500a8..7b8745cf42 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -96,7 +96,7 @@ namespace osu.Game.Overlays.Mods } } - foregroundIcon.Highlighted = Selected; + foregroundIcon.Highlighted.Value = Selected; SelectionChanged?.Invoke(SelectedMod); return true; diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 86feea09a8..5bb1de7a38 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -11,11 +11,14 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osuTK; +using osu.Framework.Bindables; namespace osu.Game.Rulesets.UI { public class ModIcon : Container, IHasTooltip { + public readonly BindableBool Highlighted = new BindableBool(); + private readonly SpriteIcon modIcon; private readonly SpriteIcon background; @@ -97,26 +100,12 @@ namespace osu.Game.Rulesets.UI highlightedColour = colours.PinkLight; break; } - - applyStyle(); } - private bool highlighted; - - public bool Highlighted + protected override void LoadComplete() { - get => highlighted; - - set - { - highlighted = value; - applyStyle(); - } - } - - private void applyStyle() - { - background.Colour = highlighted ? highlightedColour : backgroundColour; + base.LoadComplete(); + Highlighted.BindValueChanged(highlighted => background.Colour = highlighted.NewValue ? highlightedColour : backgroundColour, true); } } } From a99d6536c22011b34879899017d789b296ad6fba Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 08:49:04 +0300 Subject: [PATCH 138/645] CI fix --- .../Visual/Online/TestSceneLeaderboardScopeSelector.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs index f4c0d32946..cc3b2ac68b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs @@ -19,10 +19,9 @@ namespace osu.Game.Tests.Visual.Online public TestSceneLeaderboardScopeSelector() { - LeaderboardScopeSelector selector; Bindable scope = new Bindable(); - Add(selector = new LeaderboardScopeSelector + Add(new LeaderboardScopeSelector { Anchor = Anchor.Centre, Origin = Anchor.Centre, From 487979b0164091f9c2928204e660d218ca9faada Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 7 Aug 2019 09:31:07 +0300 Subject: [PATCH 139/645] Add Testing --- .../Visual/Online/TestSceneUserRequest.cs | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs new file mode 100644 index 0000000000..18d6028cb8 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs @@ -0,0 +1,109 @@ +// 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.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mania; +using osu.Game.Users; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Taiko; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneUserRequest : OsuTestScene + { + [Resolved] + private IAPIProvider api { get; set; } + + private readonly Bindable user = new Bindable(); + private GetUserRequest request; + private readonly DimmedLoadingLayer loading; + + public TestSceneUserRequest() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new UserTestContainer + { + User = { BindTarget = user } + }, + loading = new DimmedLoadingLayer + { + Alpha = 0 + } + } + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AddStep(@"local user", () => getUser()); + AddStep(@"local user with taiko ruleset", () => getUser(ruleset: new TaikoRuleset().RulesetInfo)); + AddStep(@"cookiezi", () => getUser(124493)); + AddStep(@"cookiezi with mania ruleset", () => getUser(124493, new ManiaRuleset().RulesetInfo)); + } + + private void getUser(long? userId = null, RulesetInfo ruleset = null) + { + loading.Show(); + + request?.Cancel(); + request = new GetUserRequest(userId, ruleset); + request.Success += user => + { + this.user.Value = user; + loading.Hide(); + }; + api.Queue(request); + } + + private class UserTestContainer : FillFlowContainer + { + public readonly Bindable User = new Bindable(); + + public UserTestContainer() + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Vertical; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + User.BindValueChanged(onUserUpdate, true); + } + + private void onUserUpdate(ValueChangedEvent user) + { + Clear(); + + AddRange(new Drawable[] + { + new SpriteText + { + Text = $@"Username: {user.NewValue?.Username}" + }, + new SpriteText + { + Text = $@"RankedScore: {user.NewValue?.Statistics.RankedScore}" + }, + }); + } + } + } +} From 606e977e2d27427229ba09ef62b064b9c4fd826c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 16:07:41 +0900 Subject: [PATCH 140/645] Fix twitter link shortener being used --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52fc29cb98..c4d676f4be 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ If you are not interested in developing the game, you can still consume our [bin | ------------- | ------------- | - **Linux** users are recommended to self-compile until we have official deployment in place. -- **iOS** users can join the [TestFlight beta program](https://t.co/PasE1zrHhw) (note that due to high demand this is regularly full). +- **iOS** users can join the [TestFlight beta program](https://testflight.apple.com/join/2tLcjWlF) (note that due to high demand this is regularly full). - **Android** users can self-compile, and expect a public beta soon. If your platform is not listed above, there is still a chance you can manually build it by following the instructions below. From 669c2462eca3cae95a5944e2581585eeb7d5312c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 16:25:38 +0900 Subject: [PATCH 141/645] Don't consider the type --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index c92c0ba22d..24843f8c32 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats if (!Enum.TryParse(split[0], out type)) { - Logger.Log($"A beatmap {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); return; } From c0d3d47c2995dc581f716b4a17ecad8f2d742064 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 16:49:53 +0900 Subject: [PATCH 142/645] Don't consider type for storyboards either --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 512eea0822..1dcafb4669 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - Logger.Log($"A storyboard {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A storyboard event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From c6d481238d91e63051c920ea6f1d670f28e673cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 16:56:22 +0900 Subject: [PATCH 143/645] Move QuadBatch to a local variable to stop resharper complaining --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index cb0c2fafe5..7247bafd23 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -155,12 +155,13 @@ namespace osu.Game.Rulesets.Mods private Vector2 flashlightSize; private float flashlightDim; - private readonly VertexBatch quadBatch = new QuadBatch(1, 1); private readonly Action addAction; public FlashlightDrawNode(Flashlight source) : base(source) { + var quadBatch = new QuadBatch(1, 1); + addAction = v => quadBatch.Add(new PositionAndColourVertex { Position = v.Position, From 7bcec31ea370d87a1a58958c0a405f3ff780de0c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 17:08:41 +0900 Subject: [PATCH 144/645] mention that the event was the type --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 24843f8c32..b1261855f2 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats if (!Enum.TryParse(split[0], out type)) { - Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Unknown beatmap event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); return; } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 512eea0822..584388333d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - Logger.Log($"A storyboard {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From b0e06597159d5259965c6b716f0a35c092645827 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 17:33:30 +0900 Subject: [PATCH 145/645] Dispose instead --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 7247bafd23..4f939362bb 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -155,13 +155,12 @@ namespace osu.Game.Rulesets.Mods private Vector2 flashlightSize; private float flashlightDim; + private readonly VertexBatch quadBatch = new QuadBatch(1, 1); private readonly Action addAction; public FlashlightDrawNode(Flashlight source) : base(source) { - var quadBatch = new QuadBatch(1, 1); - addAction = v => quadBatch.Add(new PositionAndColourVertex { Position = v.Position, @@ -194,6 +193,12 @@ namespace osu.Game.Rulesets.Mods shader.Unbind(); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + quadBatch?.Dispose(); + } } } } From 38df49995ce77e2176b491375144a80227579f58 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 18:29:50 +0900 Subject: [PATCH 146/645] Fix cursor scale not matching osu-stable --- .../UI/OsuPlayfieldAdjustmentContainer.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index f7888f8022..9c8be868b0 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -13,13 +13,15 @@ namespace osu.Game.Rulesets.Osu.UI protected override Container Content => content; private readonly Container content; + private const float playfield_size_adjust = 0.8f; + public OsuPlayfieldAdjustmentContainer() { Anchor = Anchor.Centre; Origin = Anchor.Centre; // Calculated from osu!stable as 512 (default gamefield size) / 640 (default window size) - Size = new Vector2(0.8f); + Size = new Vector2(playfield_size_adjust); InternalChild = new Container { @@ -41,7 +43,19 @@ namespace osu.Game.Rulesets.Osu.UI { base.Update(); + // The following calculation results in a constant of 1.6 when OsuPlayfieldAdjustmentContainer + // is consuming the full game_size. This matches the osu-stable "magic ratio". + // + // game_size = DrawSizePreservingFillContainer.TargetSize = new Vector2(1024, 768) + // + // Parent is a 4:3 aspect enforced, using height as the constricting dimension + // Parent.ChildSize.X = min(game_size.X, game_size.Y * (4 / 3)) * playfield_size_adjust + // Parent.ChildSize.X = 819.2 + // + // Scale = 819.2 / 512 + // Scale = 1.6 Scale = new Vector2(Parent.ChildSize.X / OsuPlayfield.BASE_SIZE.X); + // Size = 0.625 Size = Vector2.Divide(Vector2.One, Scale); } } From da15e19912783b3848d9315ed365013c712dfa2c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 18:40:58 +0900 Subject: [PATCH 147/645] return on storyboard side --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 584388333d..f950437e75 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -83,8 +83,12 @@ namespace osu.Game.Beatmaps.Formats storyboardSprite = null; EventType type; + if (!Enum.TryParse(split[0], out type)) + { Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); + return; + } switch (type) { From ec13143ab3ffffebc718b97e3cd1964d4b88905a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 18:45:56 +0900 Subject: [PATCH 148/645] Add further xmldoc --- osu.Game/Skinning/LegacySkin.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 19f04c9b7a..3eda76e40f 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.UI; using osuTK; using osuTK.Graphics; @@ -360,6 +361,10 @@ namespace osu.Game.Skinning } } + /// + /// A sprite which is displayed within the playfield, but historically was not considered part of the playfield. + /// Performs scale adjustment to undo the scale applied by (osu! ruleset specifically). + /// private class NonPlayfieldSprite : Sprite { public override Texture Texture @@ -368,7 +373,8 @@ namespace osu.Game.Skinning set { if (value != null) - value.ScaleAdjust *= 2f; + // stable "magic ratio". see OsuPlayfieldAdjustmentContainer for full explanation. + value.ScaleAdjust *= 1.6f; base.Texture = value; } } From 15a592e25eec64efd0d7e53ae9d52356a4dbf6ec Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 19:25:40 +0900 Subject: [PATCH 149/645] Just assert doesn't throw and don't catch at LegacyDecoder --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 10 ++-------- osu.Game.Tests/Resources/valid-events.osu | 12 ------------ osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 9 +-------- 3 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 osu.Game.Tests/Resources/valid-events.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 49a6f646ba..535320530d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -484,20 +484,14 @@ namespace osu.Game.Tests.Beatmaps.Formats } [Test] - public void TestDecodeInvalidEvents() + public void TestInvalidEventStillPasses() { var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; - using (var goodResStream = TestResources.OpenResource("valid-events.osu")) - using (var goodStream = new StreamReader(goodResStream)) using (var badResStream = TestResources.OpenResource("invalid-events.osu")) using (var badStream = new StreamReader(badResStream)) { - var goodBeatmap = decoder.Decode(goodStream); - var badBeatmap = decoder.Decode(badStream); - - Assert.AreEqual(goodBeatmap.Breaks[0].Duration, badBeatmap.Breaks[0].Duration); - Assert.AreEqual(goodBeatmap.Metadata.BackgroundFile, badBeatmap.Metadata.BackgroundFile); + Assert.DoesNotThrow(() => decoder.Decode(badStream)); } } } diff --git a/osu.Game.Tests/Resources/valid-events.osu b/osu.Game.Tests/Resources/valid-events.osu deleted file mode 100644 index ed3614b4ed..0000000000 --- a/osu.Game.Tests/Resources/valid-events.osu +++ /dev/null @@ -1,12 +0,0 @@ -osu file format v14 - -[Events] -//Background and Video events -0,0,"machinetop_background.jpg",0,0 -//Break Periods -2,122474,140135 -//Storyboard Layer 0 (Background) -//Storyboard Layer 1 (Fail) -//Storyboard Layer 2 (Pass) -//Storyboard Layer 3 (Foreground) -//Storyboard Sound Samples diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 7999c82761..17e278c48e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -43,14 +43,7 @@ namespace osu.Game.Beatmaps.Formats continue; } - try - { - ParseLine(output, section, line); - } - catch (Exception e) - { - Logger.Error(e, $"Failed to process line \"{line}\" into {output}"); - } + ParseLine(output, section, line); } } From 994c1f21ec5d9391787d73a79b4e5846e2627c08 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 7 Aug 2019 19:33:16 +0900 Subject: [PATCH 150/645] Output stacked positions for conversion values --- .../OsuBeatmapConversionTest.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 392170f0a8..8f975b14a2 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -8,7 +8,6 @@ using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.UI; using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Osu.Tests @@ -31,22 +30,22 @@ namespace osu.Game.Rulesets.Osu.Tests { case Slider slider: foreach (var nested in slider.NestedHitObjects) - yield return createConvertValue(nested); + yield return createConvertValue((OsuHitObject)nested); break; default: - yield return createConvertValue(hitObject); + yield return createConvertValue((OsuHitObject)hitObject); break; } - ConvertValue createConvertValue(HitObject obj) => new ConvertValue + ConvertValue createConvertValue(OsuHitObject obj) => new ConvertValue { StartTime = obj.StartTime, EndTime = (obj as IHasEndTime)?.EndTime ?? obj.StartTime, - X = (obj as IHasPosition)?.X ?? OsuPlayfield.BASE_SIZE.X / 2, - Y = (obj as IHasPosition)?.Y ?? OsuPlayfield.BASE_SIZE.Y / 2, + X = obj.StackedPosition.X, + Y = obj.StackedPosition.Y }; } From 42de5934f6f93c95049f254d748256ca9eb7d8b0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 7 Aug 2019 19:33:35 +0900 Subject: [PATCH 151/645] Fix incorrect hitobject indices --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 7bb1f42802..a9f8b87fb4 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -211,14 +211,14 @@ namespace osu.Game.Rulesets.Osu.Beatmaps if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance) { currHitObject.StackHeight++; - startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[i].StartTime; + startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[j].StartTime; } else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.EndPosition) < stack_distance) { //Case for sliders - bump notes down and right, rather than up and left. sliderStack++; beatmap.HitObjects[j].StackHeight -= sliderStack; - startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[i].StartTime; + startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[j].StartTime; } } } From b8ccba02f2017dea054b3fce5413e90dff08670c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 19:33:54 +0900 Subject: [PATCH 152/645] Log to runtime instead --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 17e278c48e..8365fb17d3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -43,7 +43,14 @@ namespace osu.Game.Beatmaps.Formats continue; } - ParseLine(output, section, line); + try + { + ParseLine(output, section, line); + } + catch (Exception e) + { + Logger.Log($"Failed to process line \"{line}\" into {output}", LoggingTarget.Runtime, LogLevel.Important); + } } } From bc3a340286afb799b3af13197fd10f950b0e19f2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 7 Aug 2019 19:35:39 +0900 Subject: [PATCH 153/645] Fix incorrect path position being used for old stacking algorithm --- .../OsuBeatmapConversionTest.cs | 1 + .../Beatmaps/OsuBeatmapProcessor.cs | 8 +- .../old-stacking-expected-conversion.json | 278 ++++++++++++++++++ .../Testing/Beatmaps/old-stacking.osu | 40 +++ 4 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking-expected-conversion.json create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking.osu diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 8f975b14a2..e9fdf924c3 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Osu.Tests [TestCase("slider-ticks")] [TestCase("repeat-slider")] [TestCase("uneven-repeat-slider")] + [TestCase("old-stacking")] public void Test(string name) => base.Test(name); protected override IEnumerable CreateConvertValue(HitObject hitObject) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index a9f8b87fb4..bb19b783aa 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; +using osuTK; namespace osu.Game.Rulesets.Osu.Beatmaps { @@ -208,12 +209,17 @@ namespace osu.Game.Rulesets.Osu.Beatmaps if (beatmap.HitObjects[j].StartTime - stackThreshold > startTime) break; + // The start position of the hitobject, or the position at the end of the path if the hitobject is a slider + Vector2 position2 = currHitObject is Slider currSlider + ? currSlider.Position + currSlider.Path.PositionAt(1) + : currHitObject.Position; + if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance) { currHitObject.StackHeight++; startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[j].StartTime; } - else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.EndPosition) < stack_distance) + else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, position2) < stack_distance) { //Case for sliders - bump notes down and right, rather than up and left. sliderStack++; diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking-expected-conversion.json b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking-expected-conversion.json new file mode 100644 index 0000000000..b994cbd85a --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking-expected-conversion.json @@ -0,0 +1,278 @@ +{ + "Mappings": [{ + "StartTime": 32165, + "Objects": [{ + "StartTime": 32165, + "EndTime": 32165, + "X": 32, + "Y": 320 + }] + }, + { + "StartTime": 32517, + "Objects": [{ + "StartTime": 32517, + "EndTime": 32517, + "X": 246.396057, + "Y": 182.396057 + }] + }, + { + "StartTime": 32605, + "Objects": [{ + "StartTime": 32605, + "EndTime": 32605, + "X": 249.597382, + "Y": 185.597382 + }] + }, + { + "StartTime": 32693, + "Objects": [{ + "StartTime": 32693, + "EndTime": 32693, + "X": 252.798691, + "Y": 188.798691 + }] + }, + { + "StartTime": 32781, + "Objects": [{ + "StartTime": 32781, + "EndTime": 32781, + "X": 256, + "Y": 192 + }] + }, + { + "StartTime": 33248, + "Objects": [{ + "StartTime": 33248, + "EndTime": 33248, + "X": 39.3960648, + "Y": 76.3960648 + }] + }, + { + "StartTime": 33307, + "Objects": [{ + "StartTime": 33307, + "EndTime": 33307, + "X": 42.5973778, + "Y": 79.597374 + }] + }, + { + "StartTime": 33383, + "Objects": [{ + "StartTime": 33383, + "EndTime": 33383, + "X": 45.798687, + "Y": 82.79869 + }] + }, + { + "StartTime": 33459, + "Objects": [{ + "StartTime": 33459, + "EndTime": 33459, + "X": 49, + "Y": 86 + }, + { + "StartTime": 33635, + "EndTime": 33635, + "X": 123.847847, + "Y": 85.7988 + }, + { + "StartTime": 33811, + "EndTime": 33811, + "X": 198.6957, + "Y": 85.5975952 + }, + { + "StartTime": 33988, + "EndTime": 33988, + "X": 273.9688, + "Y": 85.39525 + }, + { + "StartTime": 34164, + "EndTime": 34164, + "X": 348.816681, + "Y": 85.19404 + }, + { + "StartTime": 34246, + "EndTime": 34246, + "X": 398.998718, + "Y": 85.05914 + } + ] + }, + { + "StartTime": 34341, + "Objects": [{ + "StartTime": 34341, + "EndTime": 34341, + "X": 401.201324, + "Y": 88.20131 + }] + }, + { + "StartTime": 34400, + "Objects": [{ + "StartTime": 34400, + "EndTime": 34400, + "X": 404.402618, + "Y": 91.402626 + }] + }, + { + "StartTime": 34459, + "Objects": [{ + "StartTime": 34459, + "EndTime": 34459, + "X": 407.603943, + "Y": 94.6039352 + }] + }, + { + "StartTime": 34989, + "Objects": [{ + "StartTime": 34989, + "EndTime": 34989, + "X": 163, + "Y": 138 + }, + { + "StartTime": 35018, + "EndTime": 35018, + "X": 188, + "Y": 138 + } + ] + }, + { + "StartTime": 35106, + "Objects": [{ + "StartTime": 35106, + "EndTime": 35106, + "X": 163, + "Y": 138 + }, + { + "StartTime": 35135, + "EndTime": 35135, + "X": 188, + "Y": 138 + } + ] + }, + { + "StartTime": 35224, + "Objects": [{ + "StartTime": 35224, + "EndTime": 35224, + "X": 163, + "Y": 138 + }, + { + "StartTime": 35253, + "EndTime": 35253, + "X": 188, + "Y": 138 + } + ] + }, + { + "StartTime": 35695, + "Objects": [{ + "StartTime": 35695, + "EndTime": 35695, + "X": 166, + "Y": 76 + }, + { + "StartTime": 35871, + "EndTime": 35871, + "X": 240.99855, + "Y": 75.53417 + }, + { + "StartTime": 36011, + "EndTime": 36011, + "X": 315.9971, + "Y": 75.0683441 + } + ] + }, + { + "StartTime": 36106, + "Objects": [{ + "StartTime": 36106, + "EndTime": 36106, + "X": 315, + "Y": 75 + }, + { + "StartTime": 36282, + "EndTime": 36282, + "X": 240.001526, + "Y": 75.47769 + }, + { + "StartTime": 36422, + "EndTime": 36422, + "X": 165.003052, + "Y": 75.95539 + } + ] + }, + { + "StartTime": 36518, + "Objects": [{ + "StartTime": 36518, + "EndTime": 36518, + "X": 166, + "Y": 76 + }, + { + "StartTime": 36694, + "EndTime": 36694, + "X": 240.99855, + "Y": 75.53417 + }, + { + "StartTime": 36834, + "EndTime": 36834, + "X": 315.9971, + "Y": 75.0683441 + } + ] + }, + { + "StartTime": 36929, + "Objects": [{ + "StartTime": 36929, + "EndTime": 36929, + "X": 315, + "Y": 75 + }, + { + "StartTime": 37105, + "EndTime": 37105, + "X": 240.001526, + "Y": 75.47769 + }, + { + "StartTime": 37245, + "EndTime": 37245, + "X": 165.003052, + "Y": 75.95539 + } + ] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking.osu b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking.osu new file mode 100644 index 0000000000..4bc9226d67 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/old-stacking.osu @@ -0,0 +1,40 @@ +osu file format v3 + +[Difficulty] +HPDrainRate:3 +CircleSize:5 +OverallDifficulty:8 +ApproachRate:8 +SliderMultiplier:1.5 +SliderTickRate:2 + +[TimingPoints] +48,352.941176470588,4,1,1,100,1,0 + +[HitObjects] +// Hit circles +32,320,32165,5,2,0:0:0:0: +256,192,32517,5,0,0:0:0:0: +256,192,32605,1,0,0:0:0:0: +256,192,32693,1,0,0:0:0:0: +256,192,32781,1,0,0:0:0:0: + +// Hit circles on slider endpoints +49,86,33248,1,0,0:0:0:0: +49,86,33307,1,0,0:0:0:0: +49,86,33383,1,0,0:0:0:0: +49,86,33459,2,0,L|421:85,1,350 +398,85,34341,1,0,0:0:0:0: +398,85,34400,1,0,0:0:0:0: +398,85,34459,1,0,0:0:0:0: + +// Sliders +163,138,34989,2,0,L|196:138,1,25 +163,138,35106,2,0,L|196:138,1,25 +163,138,35224,2,0,L|196:138,1,25 + +// Reversed sliders +166,76,35695,2,0,L|327:75,1,150 +315,75,36106,2,0,L|158:76,1,150 +166,76,36518,2,0,L|327:75,1,150 +315,75,36929,2,0,L|158:76,1,150 From bde89adcb72b85fb76476065e017b8533ea79338 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 19:45:29 +0900 Subject: [PATCH 154/645] show exception message --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 8365fb17d3..d6d6804d16 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -49,7 +49,7 @@ namespace osu.Game.Beatmaps.Formats } catch (Exception e) { - Logger.Log($"Failed to process line \"{line}\" into {output}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Failed to process line \"{line}\" into {output}: {e.Message}", LoggingTarget.Runtime, LogLevel.Important); } } } From 2ab288902759280a2258a07fdd2dbb501d2f398b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Aug 2019 19:56:17 +0900 Subject: [PATCH 155/645] 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 e64102c401..c4cdffa8a5 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -63,6 +63,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index cf325b77be..02bf053468 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 66f398a927..5b43a6f46f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From c2b3c28c798e2994402ba2fbacd72d9093a99e94 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 7 Aug 2019 16:15:53 +0300 Subject: [PATCH 156/645] Use IsBreakTime for checking if currently in a break Rather than iterating over all breaks to find which is in current time --- osu.Game/Screens/Play/Player.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 96b8073d11..e7398be176 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -66,6 +66,8 @@ namespace osu.Game.Screens.Play private SampleChannel sampleRestart; + private BreakOverlay breakOverlay; + protected ScoreProcessor ScoreProcessor { get; private set; } protected DrawableRuleset DrawableRuleset { get; private set; } @@ -134,7 +136,7 @@ namespace osu.Game.Screens.Play } } }, - new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) + breakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -411,8 +413,7 @@ namespace osu.Game.Screens.Play PauseOverlay.Hide(); // breaks and time-based conditions may allow instant resume. - double time = GameplayClockContainer.GameplayClock.CurrentTime; - if (Beatmap.Value.Beatmap.Breaks.Any(b => b.Contains(time)) || time < Beatmap.Value.Beatmap.HitObjects.First().StartTime) + if (breakOverlay.IsBreakTime.Value || GameplayClockContainer.GameplayClock.CurrentTime < Beatmap.Value.Beatmap.HitObjects.First().StartTime) completeResume(); else DrawableRuleset.RequestResume(completeResume); From d3657d82cd042e13c1ea848c003b7e094483575b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 7 Aug 2019 16:28:16 +0300 Subject: [PATCH 157/645] Simplify final check for break time --- osu.Game/Screens/Play/BreakOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 93267e5f2a..ea9bba9c95 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -153,7 +153,7 @@ namespace osu.Game.Screens.Play // If the current break doesn't have effects, IsBreakTime should be false. // We also assume that the overlay's fade out transform is "not break time". var currentBreak = breaks[CurrentBreakIndex]; - isBreakTime.Value = currentBreak.HasEffect && time >= currentBreak.StartTime && time <= currentBreak.EndTime - fade_duration; + isBreakTime.Value = currentBreak.HasEffect && currentBreak.Contains(time); } private void initializeBreaks() From ba269a49eef92af0c1ab44dcc73950ed7a8156b4 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 7 Aug 2019 16:59:35 +0300 Subject: [PATCH 158/645] Expose break fade duration and add it in the calculation --- osu.Game/Beatmaps/Timing/BreakPeriod.cs | 4 +++- osu.Game/Screens/Play/BreakOverlay.cs | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/Timing/BreakPeriod.cs b/osu.Game/Beatmaps/Timing/BreakPeriod.cs index 856a5fefd4..5d79c7a86b 100644 --- a/osu.Game/Beatmaps/Timing/BreakPeriod.cs +++ b/osu.Game/Beatmaps/Timing/BreakPeriod.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 osu.Game.Screens.Play; + namespace osu.Game.Beatmaps.Timing { public class BreakPeriod @@ -35,6 +37,6 @@ namespace osu.Game.Beatmaps.Timing /// /// The time to check in milliseconds. /// Whether the time falls within this . - public bool Contains(double time) => time >= StartTime && time <= EndTime; + public bool Contains(double time) => time >= StartTime && time <= EndTime - BreakOverlay.BREAK_FADE_DURATION; } } diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index ea9bba9c95..444b1bd210 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -17,7 +17,11 @@ namespace osu.Game.Screens.Play { public class BreakOverlay : Container { - private const double fade_duration = BreakPeriod.MIN_BREAK_DURATION / 2; + /// + /// The duration of the break overlay fading. + /// + public const double BREAK_FADE_DURATION = BreakPeriod.MIN_BREAK_DURATION / 2; + private const float remaining_time_container_max_size = 0.3f; private const int vertical_margin = 25; @@ -172,25 +176,25 @@ namespace osu.Game.Screens.Play using (BeginAbsoluteSequence(b.StartTime, true)) { - fadeContainer.FadeIn(fade_duration); - breakArrows.Show(fade_duration); + fadeContainer.FadeIn(BREAK_FADE_DURATION); + breakArrows.Show(BREAK_FADE_DURATION); remainingTimeAdjustmentBox - .ResizeWidthTo(remaining_time_container_max_size, fade_duration, Easing.OutQuint) - .Delay(b.Duration - fade_duration) + .ResizeWidthTo(remaining_time_container_max_size, BREAK_FADE_DURATION, Easing.OutQuint) + .Delay(b.Duration - BREAK_FADE_DURATION) .ResizeWidthTo(0); remainingTimeBox - .ResizeWidthTo(0, b.Duration - fade_duration) + .ResizeWidthTo(0, b.Duration - BREAK_FADE_DURATION) .Then() .ResizeWidthTo(1); remainingTimeCounter.CountTo(b.Duration).CountTo(0, b.Duration); - using (BeginDelayedSequence(b.Duration - fade_duration, true)) + using (BeginDelayedSequence(b.Duration - BREAK_FADE_DURATION, true)) { - fadeContainer.FadeOut(fade_duration); - breakArrows.Hide(fade_duration); + fadeContainer.FadeOut(BREAK_FADE_DURATION); + breakArrows.Hide(BREAK_FADE_DURATION); } } } From 167a81f40a3561b34f3bfb2e5c6acadb93f891c1 Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 7 Aug 2019 18:12:11 +0200 Subject: [PATCH 159/645] add special skin hit "animations" --- .../Resources/special-skin/hit0-0@2x.png | Bin 0 -> 4020 bytes .../Resources/special-skin/hit100-0@2x.png | Bin 0 -> 5653 bytes .../Resources/special-skin/hit300-0@2x.png | Bin 0 -> 5004 bytes .../Resources/special-skin/hit50-0@2x.png | Bin 0 -> 3861 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-0@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2ed3a7fa3d5bc0aa43098e9247fa3f6a7c6f80 GIT binary patch literal 4020 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..777af3bd415263824913549c5c4c708c4d6e450a GIT binary patch literal 5653 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 Wr=9MwmK5XvL>cIqJgU`pj`<%3F8Egf literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7ee45a7057ca5f1e11d9bea30375c92e139cf01e GIT binary patch literal 5004 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 F_J2M}_?iF! literal 0 HcmV?d00001 From d5b26b86dafbe9b870b50dd23b74f68ad101471d Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 7 Aug 2019 22:18:10 +0300 Subject: [PATCH 160/645] Fix storyboard not showing on disabled user dim --- osu.Game/Graphics/Containers/UserDimContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 03de5f651f..dd5134168f 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -76,9 +76,9 @@ namespace osu.Game.Graphics.Containers /// protected virtual void UpdateVisuals() { - ContentDisplayed = ShowDimContent; + ContentDisplayed = !EnableUserDim.Value || ShowDimContent; - dimContent.FadeTo((ContentDisplayed) ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); + dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); dimContent.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); } } From 40a33b338201d543c27e97f7769e1731d5461352 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 10:41:23 +0900 Subject: [PATCH 161/645] Move IsLoaded check to more correct place --- osu.Game/Screens/Play/BreakOverlay.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 444b1bd210..78690f156f 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -40,7 +40,8 @@ namespace osu.Game.Screens.Play isBreakTime.Value = false; CurrentBreakIndex = 0; - initializeBreaks(); + if (IsLoaded) + initializeBreaks(); } } @@ -162,8 +163,6 @@ namespace osu.Game.Screens.Play private void initializeBreaks() { - if (!IsLoaded) return; // we need a clock. - FinishTransforms(true); Scheduler.CancelDelayedTasks(); From 99f5ca07ce8562e87fa4dae3de9a24c77805cacf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 10:42:54 +0900 Subject: [PATCH 162/645] Remove redundant comment --- osu.Game/Screens/Play/BreakOverlay.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 78690f156f..2d014db210 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -154,9 +154,6 @@ namespace osu.Game.Screens.Play CurrentBreakIndex--; } - // This ensures that IsBreakTime is generally consistent with the overlay's transforms during a break. - // If the current break doesn't have effects, IsBreakTime should be false. - // We also assume that the overlay's fade out transform is "not break time". var currentBreak = breaks[CurrentBreakIndex]; isBreakTime.Value = currentBreak.HasEffect && currentBreak.Contains(time); } From 7d42561da93c7f816de3f71e6de32f1d46848250 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 12:58:20 +0900 Subject: [PATCH 163/645] Remove linq usage in BreakOverlay update --- osu.Game/Screens/Play/BreakOverlay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 2d014db210..6fdee85f45 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -138,7 +137,7 @@ namespace osu.Game.Screens.Play private void updateBreakTimeBindable() { - if (breaks?.Any() != true) + if (breaks == null || breaks.Count == 0) return; var time = Clock.CurrentTime; From ffed642929e7ec23ba8e3c60c252a9d0522c9327 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 07:08:51 +0300 Subject: [PATCH 164/645] Implement MatchBeatmapPanel --- .../Screens/Multi/Match/Components/Header.cs | 16 ++++++ .../Match/Components/MatchBeatmapPanel.cs | 49 +++++++++++++++++++ .../Screens/Multi/Match/MatchSubScreen.cs | 2 + 3 files changed, 67 insertions(+) create mode 100644 osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 73994fa369..629a19e5e8 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -29,6 +29,10 @@ namespace osu.Game.Screens.Multi.Match.Components public Action RequestBeatmapSelection; + public BindableBool ShowBeatmapPanel = new BindableBool(); + + private MatchBeatmapPanel beatmapPanel; + public Header() { RelativeSizeAxes = Axes.X; @@ -55,6 +59,12 @@ namespace osu.Game.Screens.Multi.Match.Components RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.4f), Color4.Black.Opacity(0.6f)), }, + beatmapPanel = new MatchBeatmapPanel + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Margin = new MarginPadding { Right = 100 }, + } } }, new Box @@ -114,6 +124,12 @@ namespace osu.Game.Screens.Multi.Match.Components beatmapButton.Action = () => RequestBeatmapSelection?.Invoke(); } + protected override void LoadComplete() + { + base.LoadComplete(); + ShowBeatmapPanel.BindValueChanged(value => beatmapPanel.FadeTo(value.NewValue ? 1 : 0, 200, Easing.OutQuint), true); + } + private class BeatmapSelectButton : HeaderButton { [Resolved(typeof(Room), nameof(Room.RoomID))] diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs new file mode 100644 index 0000000000..916115f11b --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Direct; +using osu.Game.Rulesets; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class MatchBeatmapPanel : MultiplayerComposite + { + [Resolved] + private IAPIProvider api { get; set; } + + [Resolved] + private RulesetStore rulesets { get; set; } + + private GetBeatmapSetRequest request; + + public MatchBeatmapPanel() + { + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load() + { + CurrentItem.BindValueChanged(item => + { + var id = item.NewValue?.Beatmap.OnlineBeatmapID ?? 0; + + if (id != 0) + { + request?.Cancel(); + request = new GetBeatmapSetRequest(id, BeatmapSetLookupType.BeatmapId); + request.Success += beatmap => + { + ClearInternal(); + AddInternal(new DirectGridPanel(beatmap.ToBeatmapSet(rulesets))); + }; + api.Queue(request); + } + }, true); + } + } +} diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 5469d4c8c8..16c6b412fa 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -148,12 +148,14 @@ namespace osu.Game.Screens.Multi.Match if (tab.NewValue is SettingsMatchPage) { + header.ShowBeatmapPanel.Value = false; settings.Show(); info.FadeOut(fade_duration, Easing.OutQuint); bottomRow.FadeOut(fade_duration, Easing.OutQuint); } else { + header.ShowBeatmapPanel.Value = true; settings.Hide(); info.FadeIn(fade_duration, Easing.OutQuint); bottomRow.FadeIn(fade_duration, Easing.OutQuint); From a4459972b6f00d3e533a769468cecf4a7e5462ad Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 07:15:30 +0300 Subject: [PATCH 165/645] Remove ViewBeatmapButton --- .../Visual/Multiplayer/TestSceneMatchInfo.cs | 2 +- .../Screens/Multi/Match/Components/Info.cs | 8 +--- .../Match/Components/ViewBeatmapButton.cs | 46 ------------------- 3 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs index 3f0c0b07b7..a6c036a876 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Multiplayer typeof(Info), typeof(HeaderButton), typeof(ReadyButton), - typeof(ViewBeatmapButton) + typeof(MatchBeatmapPanel) }; [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index a185c4db50..74f000c21f 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -28,7 +28,6 @@ namespace osu.Game.Screens.Multi.Match.Components private void load() { ReadyButton readyButton; - ViewBeatmapButton viewBeatmapButton; HostInfo hostInfo; InternalChildren = new Drawable[] @@ -80,7 +79,6 @@ namespace osu.Game.Screens.Multi.Match.Components Direction = FillDirection.Horizontal, Children = new Drawable[] { - viewBeatmapButton = new ViewBeatmapButton(), readyButton = new ReadyButton { Action = () => OnStart?.Invoke() @@ -91,11 +89,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentItem.BindValueChanged(item => - { - viewBeatmapButton.Beatmap.Value = item.NewValue?.Beatmap; - readyButton.Beatmap.Value = item.NewValue?.Beatmap; - }, true); + CurrentItem.BindValueChanged(item => readyButton.Beatmap.Value = item.NewValue?.Beatmap, true); hostInfo.Host.BindTo(Host); } diff --git a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs b/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs deleted file mode 100644 index 8d1ff21124..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/ViewBeatmapButton.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Game.Beatmaps; -using osuTK; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class ViewBeatmapButton : HeaderButton - { - public readonly Bindable Beatmap = new Bindable(); - - [Resolved(CanBeNull = true)] - private OsuGame osuGame { get; set; } - - public ViewBeatmapButton() - { - RelativeSizeAxes = Axes.Y; - Size = new Vector2(200, 1); - - Text = "View beatmap"; - } - - [BackgroundDependencyLoader] - private void load() - { - if (osuGame != null) - Beatmap.BindValueChanged(beatmap => updateAction(beatmap.NewValue), true); - } - - private void updateAction(BeatmapInfo beatmap) - { - if (beatmap == null) - { - Enabled.Value = false; - return; - } - - Action = () => osuGame.ShowBeatmap(beatmap.OnlineBeatmapID ?? 0); - Enabled.Value = true; - } - } -} From 77df6a0cb7ef7736808811d4c2033d5882d8aa6a Mon Sep 17 00:00:00 2001 From: Joehu Date: Wed, 7 Aug 2019 21:16:36 -0700 Subject: [PATCH 166/645] Remove unused direct placeholder screen --- osu.Game/Screens/Direct/OnlineListing.cs | 9 --------- osu.Game/Screens/Menu/MainMenu.cs | 2 -- 2 files changed, 11 deletions(-) delete mode 100644 osu.Game/Screens/Direct/OnlineListing.cs diff --git a/osu.Game/Screens/Direct/OnlineListing.cs b/osu.Game/Screens/Direct/OnlineListing.cs deleted file mode 100644 index 8376383674..0000000000 --- a/osu.Game/Screens/Direct/OnlineListing.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Screens.Direct -{ - public class OnlineListing : ScreenWhiteBox - { - } -} diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index fc8ddd8bd4..499b5089f6 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -14,7 +14,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Charts; -using osu.Game.Screens.Direct; using osu.Game.Screens.Edit; using osu.Game.Screens.Multi; using osu.Game.Screens.Select; @@ -65,7 +64,6 @@ namespace osu.Game.Screens.Menu buttons = new ButtonSystem { OnChart = delegate { this.Push(new ChartListing()); }, - OnDirect = delegate { this.Push(new OnlineListing()); }, OnEdit = delegate { this.Push(new Editor()); }, OnSolo = onSolo, OnMulti = delegate { this.Push(new Multiplayer()); }, From a345955f45c51d4ecaeb9cc728db1f30ce40d1f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 13:57:04 +0900 Subject: [PATCH 167/645] Add mentions linking ScoreProcessor apply/revert methods together --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2e863f7edb..ba2375bec1 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -313,6 +313,9 @@ namespace osu.Game.Rulesets.Scoring /// /// Applies the score change of a to this . /// + /// + /// Any changes applied via this method can be reverted via . + /// /// The to apply. protected virtual void ApplyResult(JudgementResult result) { @@ -357,7 +360,7 @@ namespace osu.Game.Rulesets.Scoring } /// - /// Reverts the score change of a that was applied to this . + /// Reverts the score change of a that was applied to this via . /// /// The judgement scoring result. protected virtual void RevertResult(JudgementResult result) From ac2060f1cf4d1befc59d2b56531d58736f0dd021 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 8 Aug 2019 14:44:04 +0900 Subject: [PATCH 168/645] Throw exceptions and let LegacyDecoder handle them --- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 153 ++++----- .../Formats/LegacyStoryboardDecoder.cs | 6 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 323 +++++++++--------- 3 files changed, 223 insertions(+), 259 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index b1261855f2..02d969b571 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -5,7 +5,6 @@ using System; using System.IO; using System.Linq; using osu.Framework.IO.File; -using osu.Framework.Logging; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Beatmaps.ControlPoints; @@ -292,10 +291,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - { - Logger.Log($"Unknown beatmap event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); - return; - } + throw new InvalidDataException($@"Unknown event type: {split[0]}"); switch (type) { @@ -323,90 +319,79 @@ namespace osu.Game.Beatmaps.Formats private void handleTimingPoint(string line) { - try + string[] split = line.Split(','); + + double time = getOffsetTime(Parsing.ParseDouble(split[0].Trim())); + double beatLength = Parsing.ParseDouble(split[1].Trim()); + double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1; + + TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple; + if (split.Length >= 3) + timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)Parsing.ParseInt(split[2]); + + LegacySampleBank sampleSet = defaultSampleBank; + if (split.Length >= 4) + sampleSet = (LegacySampleBank)Parsing.ParseInt(split[3]); + + int customSampleBank = 0; + if (split.Length >= 5) + customSampleBank = Parsing.ParseInt(split[4]); + + int sampleVolume = defaultSampleVolume; + if (split.Length >= 6) + sampleVolume = Parsing.ParseInt(split[5]); + + bool timingChange = true; + if (split.Length >= 7) + timingChange = split[6][0] == '1'; + + bool kiaiMode = false; + bool omitFirstBarSignature = false; + + if (split.Length >= 8) { - string[] split = line.Split(','); - - double time = getOffsetTime(Parsing.ParseDouble(split[0].Trim())); - double beatLength = Parsing.ParseDouble(split[1].Trim()); - double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1; - - TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple; - if (split.Length >= 3) - timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)Parsing.ParseInt(split[2]); - - LegacySampleBank sampleSet = defaultSampleBank; - if (split.Length >= 4) - sampleSet = (LegacySampleBank)Parsing.ParseInt(split[3]); - - int customSampleBank = 0; - if (split.Length >= 5) - customSampleBank = Parsing.ParseInt(split[4]); - - int sampleVolume = defaultSampleVolume; - if (split.Length >= 6) - sampleVolume = Parsing.ParseInt(split[5]); - - bool timingChange = true; - if (split.Length >= 7) - timingChange = split[6][0] == '1'; - - bool kiaiMode = false; - bool omitFirstBarSignature = false; - - if (split.Length >= 8) - { - EffectFlags effectFlags = (EffectFlags)Parsing.ParseInt(split[7]); - kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai); - omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine); - } - - string stringSampleSet = sampleSet.ToString().ToLowerInvariant(); - if (stringSampleSet == @"none") - stringSampleSet = @"normal"; - - if (timingChange) - { - var controlPoint = CreateTimingControlPoint(); - controlPoint.Time = time; - controlPoint.BeatLength = beatLength; - controlPoint.TimeSignature = timeSignature; - - handleTimingControlPoint(controlPoint); - } - - handleDifficultyControlPoint(new DifficultyControlPoint - { - Time = time, - SpeedMultiplier = speedMultiplier, - AutoGenerated = timingChange - }); - - handleEffectControlPoint(new EffectControlPoint - { - Time = time, - KiaiMode = kiaiMode, - OmitFirstBarLine = omitFirstBarSignature, - AutoGenerated = timingChange - }); - - handleSampleControlPoint(new LegacySampleControlPoint - { - Time = time, - SampleBank = stringSampleSet, - SampleVolume = sampleVolume, - CustomSampleBank = customSampleBank, - AutoGenerated = timingChange - }); + EffectFlags effectFlags = (EffectFlags)Parsing.ParseInt(split[7]); + kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai); + omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine); } - catch (FormatException) + + string stringSampleSet = sampleSet.ToString().ToLowerInvariant(); + if (stringSampleSet == @"none") + stringSampleSet = @"normal"; + + if (timingChange) { - Logger.Log("A timing point could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); + var controlPoint = CreateTimingControlPoint(); + controlPoint.Time = time; + controlPoint.BeatLength = beatLength; + controlPoint.TimeSignature = timeSignature; + + handleTimingControlPoint(controlPoint); } - catch (OverflowException) + + handleDifficultyControlPoint(new DifficultyControlPoint { - Logger.Log("A timing point could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); - } + Time = time, + SpeedMultiplier = speedMultiplier, + AutoGenerated = timingChange + }); + + handleEffectControlPoint(new EffectControlPoint + { + Time = time, + KiaiMode = kiaiMode, + OmitFirstBarLine = omitFirstBarSignature, + AutoGenerated = timingChange + }); + + handleSampleControlPoint(new LegacySampleControlPoint + { + Time = time, + SampleBank = stringSampleSet, + SampleVolume = sampleVolume, + CustomSampleBank = customSampleBank, + AutoGenerated = timingChange + }); } private void handleTimingControlPoint(TimingControlPoint newPoint) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index f950437e75..3ae1c3ef12 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -10,7 +10,6 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.IO.File; -using osu.Framework.Logging; using osu.Game.Storyboards; namespace osu.Game.Beatmaps.Formats @@ -85,10 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - { - Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); - return; - } + throw new InvalidDataException($@"Unknown event type: {split[0]}"); switch (type) { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index d70c1bf7d3..442e37edf5 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -10,7 +10,6 @@ using osu.Game.Beatmaps.Formats; using osu.Game.Audio; using System.Linq; using JetBrains.Annotations; -using osu.Framework.Logging; using osu.Framework.MathUtils; namespace osu.Game.Rulesets.Objects.Legacy @@ -41,208 +40,192 @@ namespace osu.Game.Rulesets.Objects.Legacy [CanBeNull] public override HitObject Parse(string text) { - try + string[] split = text.Split(','); + + Vector2 pos = new Vector2((int)Parsing.ParseFloat(split[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE)); + + double startTime = Parsing.ParseDouble(split[2]) + Offset; + + ConvertHitObjectType type = (ConvertHitObjectType)Parsing.ParseInt(split[3]); + + int comboOffset = (int)(type & ConvertHitObjectType.ComboOffset) >> 4; + type &= ~ConvertHitObjectType.ComboOffset; + + bool combo = type.HasFlag(ConvertHitObjectType.NewCombo); + type &= ~ConvertHitObjectType.NewCombo; + + var soundType = (LegacySoundType)Parsing.ParseInt(split[4]); + var bankInfo = new SampleBankInfo(); + + HitObject result = null; + + if (type.HasFlag(ConvertHitObjectType.Circle)) { - string[] split = text.Split(','); + result = CreateHit(pos, combo, comboOffset); - Vector2 pos = new Vector2((int)Parsing.ParseFloat(split[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE)); + if (split.Length > 5) + readCustomSampleBanks(split[5], bankInfo); + } + else if (type.HasFlag(ConvertHitObjectType.Slider)) + { + PathType pathType = PathType.Catmull; + double? length = null; - double startTime = Parsing.ParseDouble(split[2]) + Offset; + string[] pointSplit = split[5].Split('|'); - ConvertHitObjectType type = (ConvertHitObjectType)Parsing.ParseInt(split[3]); + int pointCount = 1; + foreach (var t in pointSplit) + if (t.Length > 1) + pointCount++; - int comboOffset = (int)(type & ConvertHitObjectType.ComboOffset) >> 4; - type &= ~ConvertHitObjectType.ComboOffset; + var points = new Vector2[pointCount]; - bool combo = type.HasFlag(ConvertHitObjectType.NewCombo); - type &= ~ConvertHitObjectType.NewCombo; + int pointIndex = 1; - var soundType = (LegacySoundType)Parsing.ParseInt(split[4]); - var bankInfo = new SampleBankInfo(); - - HitObject result = null; - - if (type.HasFlag(ConvertHitObjectType.Circle)) + foreach (string t in pointSplit) { - result = CreateHit(pos, combo, comboOffset); - - if (split.Length > 5) - readCustomSampleBanks(split[5], bankInfo); - } - else if (type.HasFlag(ConvertHitObjectType.Slider)) - { - PathType pathType = PathType.Catmull; - double? length = null; - - string[] pointSplit = split[5].Split('|'); - - int pointCount = 1; - foreach (var t in pointSplit) - if (t.Length > 1) - pointCount++; - - var points = new Vector2[pointCount]; - - int pointIndex = 1; - - foreach (string t in pointSplit) + if (t.Length == 1) { - if (t.Length == 1) + switch (t) { - switch (t) - { - case @"C": - pathType = PathType.Catmull; - break; - - case @"B": - pathType = PathType.Bezier; - break; - - case @"L": - pathType = PathType.Linear; - break; - - case @"P": - pathType = PathType.PerfectCurve; - break; - } - - continue; - } - - string[] temp = t.Split(':'); - points[pointIndex++] = new Vector2((int)Parsing.ParseDouble(temp[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(temp[1], Parsing.MAX_COORDINATE_VALUE)) - pos; - } - - // osu-stable special-cased colinear perfect curves to a CurveType.Linear - bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y)); - - if (points.Length == 3 && pathType == PathType.PerfectCurve && isLinear(points)) - pathType = PathType.Linear; - - int repeatCount = Parsing.ParseInt(split[6]); - - if (repeatCount > 9000) - throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high"); - - // osu-stable treated the first span of the slider as a repeat, but no repeats are happening - repeatCount = Math.Max(0, repeatCount - 1); - - if (split.Length > 7) - { - length = Math.Max(0, Parsing.ParseDouble(split[7])); - if (length == 0) - length = null; - } - - if (split.Length > 10) - readCustomSampleBanks(split[10], bankInfo); - - // One node for each repeat + the start and end nodes - int nodes = repeatCount + 2; - - // Populate node sample bank infos with the default hit object sample bank - var nodeBankInfos = new List(); - for (int i = 0; i < nodes; i++) - nodeBankInfos.Add(bankInfo.Clone()); - - // Read any per-node sample banks - if (split.Length > 9 && split[9].Length > 0) - { - string[] sets = split[9].Split('|'); - - for (int i = 0; i < nodes; i++) - { - if (i >= sets.Length) + case @"C": + pathType = PathType.Catmull; break; - SampleBankInfo info = nodeBankInfos[i]; - readCustomSampleBanks(sets[i], info); - } - } - - // Populate node sound types with the default hit object sound type - var nodeSoundTypes = new List(); - for (int i = 0; i < nodes; i++) - nodeSoundTypes.Add(soundType); - - // Read any per-node sound types - if (split.Length > 8 && split[8].Length > 0) - { - string[] adds = split[8].Split('|'); - - for (int i = 0; i < nodes; i++) - { - if (i >= adds.Length) + case @"B": + pathType = PathType.Bezier; break; - int sound; - int.TryParse(adds[i], out sound); - nodeSoundTypes[i] = (LegacySoundType)sound; + case @"L": + pathType = PathType.Linear; + break; + + case @"P": + pathType = PathType.PerfectCurve; + break; } + + continue; } - // Generate the final per-node samples - var nodeSamples = new List>(nodes); + string[] temp = t.Split(':'); + points[pointIndex++] = new Vector2((int)Parsing.ParseDouble(temp[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(temp[1], Parsing.MAX_COORDINATE_VALUE)) - pos; + } + + // osu-stable special-cased colinear perfect curves to a CurveType.Linear + bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y)); + + if (points.Length == 3 && pathType == PathType.PerfectCurve && isLinear(points)) + pathType = PathType.Linear; + + int repeatCount = Parsing.ParseInt(split[6]); + + if (repeatCount > 9000) + throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high"); + + // osu-stable treated the first span of the slider as a repeat, but no repeats are happening + repeatCount = Math.Max(0, repeatCount - 1); + + if (split.Length > 7) + { + length = Math.Max(0, Parsing.ParseDouble(split[7])); + if (length == 0) + length = null; + } + + if (split.Length > 10) + readCustomSampleBanks(split[10], bankInfo); + + // One node for each repeat + the start and end nodes + int nodes = repeatCount + 2; + + // Populate node sample bank infos with the default hit object sample bank + var nodeBankInfos = new List(); + for (int i = 0; i < nodes; i++) + nodeBankInfos.Add(bankInfo.Clone()); + + // Read any per-node sample banks + if (split.Length > 9 && split[9].Length > 0) + { + string[] sets = split[9].Split('|'); + for (int i = 0; i < nodes; i++) - nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); - - result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples); - - // The samples are played when the slider ends, which is the last node - result.Samples = nodeSamples[nodeSamples.Count - 1]; - } - else if (type.HasFlag(ConvertHitObjectType.Spinner)) - { - double endTime = Math.Max(startTime, Parsing.ParseDouble(split[5]) + Offset); - - result = CreateSpinner(new Vector2(512, 384) / 2, combo, comboOffset, endTime); - - if (split.Length > 6) - readCustomSampleBanks(split[6], bankInfo); - } - else if (type.HasFlag(ConvertHitObjectType.Hold)) - { - // Note: Hold is generated by BMS converts - - double endTime = Math.Max(startTime, Parsing.ParseDouble(split[2])); - - if (split.Length > 5 && !string.IsNullOrEmpty(split[5])) { - string[] ss = split[5].Split(':'); - endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0])); - readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo); + if (i >= sets.Length) + break; + + SampleBankInfo info = nodeBankInfos[i]; + readCustomSampleBanks(sets[i], info); } - - result = CreateHold(pos, combo, comboOffset, endTime + Offset); } - if (result == null) + // Populate node sound types with the default hit object sound type + var nodeSoundTypes = new List(); + for (int i = 0; i < nodes; i++) + nodeSoundTypes.Add(soundType); + + // Read any per-node sound types + if (split.Length > 8 && split[8].Length > 0) { - Logger.Log($"Unknown hit object type: {type}. Skipped.", level: LogLevel.Error); - return null; + string[] adds = split[8].Split('|'); + + for (int i = 0; i < nodes; i++) + { + if (i >= adds.Length) + break; + + int sound; + int.TryParse(adds[i], out sound); + nodeSoundTypes[i] = (LegacySoundType)sound; + } } - result.StartTime = startTime; + // Generate the final per-node samples + var nodeSamples = new List>(nodes); + for (int i = 0; i < nodes; i++) + nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); - if (result.Samples.Count == 0) - result.Samples = convertSoundType(soundType, bankInfo); + result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples); - FirstObject = false; - - return result; + // The samples are played when the slider ends, which is the last node + result.Samples = nodeSamples[nodeSamples.Count - 1]; } - catch (FormatException) + else if (type.HasFlag(ConvertHitObjectType.Spinner)) { - Logger.Log("A hitobject could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); + double endTime = Math.Max(startTime, Parsing.ParseDouble(split[5]) + Offset); + + result = CreateSpinner(new Vector2(512, 384) / 2, combo, comboOffset, endTime); + + if (split.Length > 6) + readCustomSampleBanks(split[6], bankInfo); } - catch (OverflowException) + else if (type.HasFlag(ConvertHitObjectType.Hold)) { - Logger.Log("A hitobject could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); + // Note: Hold is generated by BMS converts + + double endTime = Math.Max(startTime, Parsing.ParseDouble(split[2])); + + if (split.Length > 5 && !string.IsNullOrEmpty(split[5])) + { + string[] ss = split[5].Split(':'); + endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0])); + readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo); + } + + result = CreateHold(pos, combo, comboOffset, endTime + Offset); } - return null; + if (result == null) + throw new InvalidDataException($"Unknown hit object type: {type}"); + + result.StartTime = startTime; + + if (result.Samples.Count == 0) + result.Samples = convertSoundType(soundType, bankInfo); + + FirstObject = false; + + return result; } private void readCustomSampleBanks(string str, SampleBankInfo bankInfo) From de4ad1f62586fb3c55cd8067ac9672f284c8cfbf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 8 Aug 2019 14:44:49 +0900 Subject: [PATCH 169/645] Fix bad log message --- osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 442e37edf5..e990938291 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } if (result == null) - throw new InvalidDataException($"Unknown hit object type: {type}"); + throw new InvalidDataException($"Unknown hit object type: {split[3]}"); result.StartTime = startTime; From cbcdc2890088bb151ae6c444d4ae95e005a63f6b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 09:04:24 +0300 Subject: [PATCH 170/645] Fix hard crash when clicking on a preview button --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 16c6b412fa..13a21a4516 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; +using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.GameTypes; @@ -18,7 +19,7 @@ using PlaylistItem = osu.Game.Online.Multiplayer.PlaylistItem; namespace osu.Game.Screens.Multi.Match { - public class MatchSubScreen : MultiplayerSubScreen + public class MatchSubScreen : MultiplayerSubScreen, IPreviewTrackOwner { public override bool DisallowExternalBeatmapRulesetChanges => true; @@ -44,6 +45,9 @@ namespace osu.Game.Screens.Multi.Match [Resolved] private BeatmapManager beatmapManager { get; set; } + [Resolved] + private PreviewTrackManager trackManager { get; set; } + [Resolved(CanBeNull = true)] private OsuGame game { get; set; } @@ -184,6 +188,8 @@ namespace osu.Game.Screens.Multi.Match Mods.Value = Array.Empty(); + trackManager.StopAnyPlaying(this); + return base.OnExiting(next); } @@ -237,6 +243,13 @@ namespace osu.Game.Screens.Multi.Match } } + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + dependencies.CacheAs(this); + return dependencies; + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From 8668bce25d23d69d23c1bc3c0e15a741b9862b1a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 09:52:42 +0300 Subject: [PATCH 171/645] Fix preview can be played on start --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 13a21a4516..3136326cdd 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -231,6 +231,8 @@ namespace osu.Game.Screens.Multi.Match private void onStart() { + trackManager.StopAnyPlaying(this); + switch (type.Value) { default: From bcd443a3aa8178cc68481b96d3055d18a94014e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=BCbner?= Date: Thu, 8 Aug 2019 08:56:52 +0200 Subject: [PATCH 172/645] remove /j --- osu.Game/Online/Chat/ChannelManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index b5d8879e50..9acf6bd39f 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -213,7 +213,6 @@ namespace osu.Game.Online.Chat PostMessage(content, true); break; - case "j": case "join": if (string.IsNullOrWhiteSpace(content)) { From 0bed3bfece7397236bc891a34e5fe8ab7c343f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=BCbner?= Date: Thu, 8 Aug 2019 09:02:09 +0200 Subject: [PATCH 173/645] formatting inspection 2 --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9acf6bd39f..4f6066cab1 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -221,7 +221,7 @@ namespace osu.Game.Online.Chat } var channel = availableChannels.Where(c => c.Name == content || c.Name == $"#{content}").FirstOrDefault(); - + if (channel == null) { target.AddNewMessages(new ErrorMessage($"Channel '{content}' not found.")); From 6d5a7041fdf7873c36eff28d8e624e68fc0088ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 17:10:06 +0900 Subject: [PATCH 174/645] Move system user colour assignment to ensure consistency --- osu.Game/Online/Chat/ErrorMessage.cs | 2 +- osu.Game/Users/User.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ErrorMessage.cs b/osu.Game/Online/Chat/ErrorMessage.cs index a8ff0e9a98..87a65fb3f1 100644 --- a/osu.Game/Online/Chat/ErrorMessage.cs +++ b/osu.Game/Online/Chat/ErrorMessage.cs @@ -8,7 +8,7 @@ namespace osu.Game.Online.Chat public ErrorMessage(string message) : base(message) { - Sender.Colour = @"ff0000"; + // todo: this should likely be styled differently in the future. } } } diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index b738eff4a6..a5f3578711 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -187,6 +187,7 @@ namespace osu.Game.Users public static readonly User SYSTEM_USER = new User { Username = "system", + Colour = @"9c0101", Id = 0 }; From a3dbaef4cabb1fdd37c96cdd9dd5ad88ef1b62df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 17:29:50 +0900 Subject: [PATCH 175/645] Adjust background gradient --- osu.Game/Screens/Multi/Match/Components/Header.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 629a19e5e8..7f2b1278b7 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Multi.Match.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.4f), Color4.Black.Opacity(0.6f)), + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.7f), Color4.Black.Opacity(0.8f)), }, beatmapPanel = new MatchBeatmapPanel { From 1b559c15852901bd2c7819b166479cbb76f69475 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 12:01:33 +0300 Subject: [PATCH 176/645] Use async loading --- osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index 916115f11b..dc889eeb94 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -39,7 +39,8 @@ namespace osu.Game.Screens.Multi.Match.Components request.Success += beatmap => { ClearInternal(); - AddInternal(new DirectGridPanel(beatmap.ToBeatmapSet(rulesets))); + var panel = new DirectGridPanel(beatmap.ToBeatmapSet(rulesets)); + LoadComponentAsync(panel, p => { AddInternal(panel); }); }; api.Queue(request); } From 08a92c38d728e030b64bc0135607ce25ce01f5cd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 12:04:44 +0300 Subject: [PATCH 177/645] adjust naming --- .../Screens/Multi/Match/Components/MatchBeatmapPanel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index dc889eeb94..b927e38edb 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -30,12 +30,12 @@ namespace osu.Game.Screens.Multi.Match.Components { CurrentItem.BindValueChanged(item => { - var id = item.NewValue?.Beatmap.OnlineBeatmapID ?? 0; + var onlineId = item.NewValue?.Beatmap.OnlineBeatmapID ?? 0; - if (id != 0) + if (onlineId != 0) { request?.Cancel(); - request = new GetBeatmapSetRequest(id, BeatmapSetLookupType.BeatmapId); + request = new GetBeatmapSetRequest(onlineId, BeatmapSetLookupType.BeatmapId); request.Success += beatmap => { ClearInternal(); From e9b5c91690a424be0f26b8474fc27e03d326add8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 12:08:51 +0300 Subject: [PATCH 178/645] Fade out existing panel on beatmap change --- .../Multi/Match/Components/MatchBeatmapPanel.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index b927e38edb..f73059d069 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -19,6 +19,7 @@ namespace osu.Game.Screens.Multi.Match.Components private RulesetStore rulesets { get; set; } private GetBeatmapSetRequest request; + private DirectGridPanel panel; public MatchBeatmapPanel() { @@ -30,16 +31,23 @@ namespace osu.Game.Screens.Multi.Match.Components { CurrentItem.BindValueChanged(item => { + request?.Cancel(); + + if (panel != null) + { + panel.FadeOut(200); + panel.Expire(); + panel = null; + } + var onlineId = item.NewValue?.Beatmap.OnlineBeatmapID ?? 0; if (onlineId != 0) { - request?.Cancel(); request = new GetBeatmapSetRequest(onlineId, BeatmapSetLookupType.BeatmapId); request.Success += beatmap => { - ClearInternal(); - var panel = new DirectGridPanel(beatmap.ToBeatmapSet(rulesets)); + panel = new DirectGridPanel(beatmap.ToBeatmapSet(rulesets)); LoadComponentAsync(panel, p => { AddInternal(panel); }); }; api.Queue(request); From 460cf141de6ce895cfa69f3dd00cdc62a0d50205 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 12:18:26 +0300 Subject: [PATCH 179/645] Add testing --- .../Multiplayer/TestSceneMatchBeatmapPanel.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs new file mode 100644 index 0000000000..46fd43508b --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Multi.Match.Components; +using osu.Framework.Graphics; +using osu.Framework.MathUtils; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneMatchBeatmapPanel : MultiplayerTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(MatchBeatmapPanel) + }; + + public TestSceneMatchBeatmapPanel() + { + Add(new MatchBeatmapPanel + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + var playlist = Room.Playlist; + + playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1763072 } }); + playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2101557 } }); + playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1973466 } }); + playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2109801 } }); + playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1922035 } }); + + AddStep("Select random beatmap", () => Room.CurrentItem.Value = playlist[RNG.Next(playlist.Count)]); + } + } +} From 9ab132520cdb6af2063ca8de0d87a56785d44dd6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 8 Aug 2019 12:25:46 +0300 Subject: [PATCH 180/645] Testcase improvements --- .../Multiplayer/TestSceneMatchBeatmapPanel.cs | 35 ++++++++++++++----- .../Screens/Multi/Match/MatchSubScreen.cs | 2 ++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs index 46fd43508b..db2b61cdd9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs @@ -8,16 +8,21 @@ using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Match.Components; using osu.Framework.Graphics; using osu.Framework.MathUtils; +using osu.Game.Audio; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMatchBeatmapPanel : MultiplayerTestScene + public class TestSceneMatchBeatmapPanel : MultiplayerTestScene, IPreviewTrackOwner { public override IReadOnlyList RequiredTypes => new[] { typeof(MatchBeatmapPanel) }; + [Resolved] + private PreviewTrackManager trackManager { get; set; } + public TestSceneMatchBeatmapPanel() { Add(new MatchBeatmapPanel @@ -26,15 +31,29 @@ namespace osu.Game.Tests.Visual.Multiplayer Origin = Anchor.Centre, }); - var playlist = Room.Playlist; + Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1763072 } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2101557 } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1973466 } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2109801 } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1922035 } }); + } - playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1763072 } }); - playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2101557 } }); - playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1973466 } }); - playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2109801 } }); - playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1922035 } }); + protected override void LoadComplete() + { + base.LoadComplete(); - AddStep("Select random beatmap", () => Room.CurrentItem.Value = playlist[RNG.Next(playlist.Count)]); + AddStep("Select random beatmap", () => + { + Room.CurrentItem.Value = Room.Playlist[RNG.Next(Room.Playlist.Count)]; + trackManager.StopAnyPlaying(this); + }); + } + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + dependencies.CacheAs(this); + return dependencies; } } } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 3136326cdd..c89c32759d 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -206,6 +206,8 @@ namespace osu.Game.Screens.Multi.Match if (e.NewValue?.Ruleset != null) Ruleset.Value = e.NewValue.Ruleset; + + trackManager.StopAnyPlaying(this); } /// From 3ebfa0505c21bec9ef00fe643b05dbd52336444b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 8 Aug 2019 18:26:03 +0900 Subject: [PATCH 181/645] Don't share single scheduler across all model managers --- osu.Game/Database/ArchiveModelManager.cs | 29 +++++++++++------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index efb76deff8..52d3f013ce 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -31,10 +31,21 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveModelManager : ArchiveModelManager, ICanAcceptFiles, IModelManager + public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { + private const int import_queue_request_concurrency = 1; + + /// + /// A singleton scheduler shared by all . + /// + /// + /// This scheduler generally performs IO and CPU intensive work so concurrency is limited harshly. + /// It is mainly being used as a queue mechanism for large imports. + /// + private static readonly ThreadedTaskScheduler import_scheduler = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(ArchiveModelManager)); + /// /// Set an endpoint for notifications to be posted to. /// @@ -336,7 +347,7 @@ namespace osu.Game.Database flushEvents(true); return item; - }, cancellationToken, TaskCreationOptions.HideScheduler, IMPORT_SCHEDULER).Unwrap(); + }, cancellationToken, TaskCreationOptions.HideScheduler, import_scheduler).Unwrap(); /// /// Perform an update of the specified item. @@ -646,18 +657,4 @@ namespace osu.Game.Database #endregion } - - public abstract class ArchiveModelManager - { - private const int import_queue_request_concurrency = 1; - - /// - /// A singleton scheduler shared by all . - /// - /// - /// This scheduler generally performs IO and CPU intensive work so concurrency is limited harshly. - /// It is mainly being used as a queue mechanism for large imports. - /// - protected static readonly ThreadedTaskScheduler IMPORT_SCHEDULER = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(ArchiveModelManager)); - } } From 537973fc458f50a260e1e8d31f217a146b02cd88 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 15:59:29 +0300 Subject: [PATCH 182/645] Add test for disabling user dim on storyboard --- .../Background/TestSceneUserDimContainer.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index f114559114..bffee7f1f7 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -149,10 +149,10 @@ namespace osu.Game.Tests.Visual.Background } /// - /// Check if the is properly accepting user-defined visual changes at all. + /// Check if the is properly accepting user-defined visual changes in background at all. /// [Test] - public void DisableUserDimTest() + public void DisableUserDimBackgroundTest() { performFullSetup(); waitForDim(); @@ -165,6 +165,28 @@ namespace osu.Game.Tests.Visual.Background AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied()); } + /// + /// Check if the is properly accepting user-defined visual changes in storyboard at all. + /// + [Test] + public void DisableUserDimStoryboardTest() + { + performFullSetup(); + createFakeStoryboard(); + AddStep("Storyboard Enabled", () => + { + player.ReplacesBackground.Value = true; + player.StoryboardEnabled.Value = true; + }); + AddStep("EnableUserDim enabled", () => player.DimmableStoryboard.EnableUserDim.Value = true); + AddStep("Set dim level to 1", () => songSelect.DimLevel.Value = 1f); + waitForDim(); + AddAssert("Storyboard is invisible", () => !player.IsStoryboardVisible); + AddStep("EnableUserDim disabled", () => player.DimmableStoryboard.EnableUserDim.Value = false); + waitForDim(); + AddAssert("Storyboard is visible", () => player.IsStoryboardVisible); + } + /// /// Check if the visual settings container retains dim and blur when pausing /// From 88b9942b2ac601d33c40a41f8d3625b7788eabf5 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 17:07:06 +0300 Subject: [PATCH 183/645] Move EnableUserDim check to defualt value of ShowDimContent --- osu.Game/Graphics/Containers/UserDimContainer.cs | 2 +- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index dd5134168f..b7da5592a8 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -69,7 +69,7 @@ namespace osu.Game.Graphics.Containers /// /// Whether the content of this container should currently be visible. /// - protected virtual bool ShowDimContent => true; + protected virtual bool ShowDimContent => !EnableUserDim.Value; /// /// Should be invoked when any dependent dim level or user setting is changed and bring the visual state up-to-date. diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index 45dff039b6..10ddaeb354 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); } - protected override bool ShowDimContent => ShowStoryboard.Value && UserDimLevel.Value < 1; + protected override bool ShowDimContent => base.ShowDimContent || ShowStoryboard.Value && UserDimLevel.Value < 1; private void initializeStoryboard(bool async) { From bedb744a2e067a53d6aa5fdcbc1c6ede16245b9e Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 17:11:26 +0300 Subject: [PATCH 184/645] Add parentheses --- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index 10ddaeb354..8d1f703791 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); } - protected override bool ShowDimContent => base.ShowDimContent || ShowStoryboard.Value && UserDimLevel.Value < 1; + protected override bool ShowDimContent => base.ShowDimContent || (ShowStoryboard.Value && UserDimLevel.Value < 1); private void initializeStoryboard(bool async) { From a3d90da7d4663ee1e0653bdcb9d70143bc89ae9b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 17:29:52 +0300 Subject: [PATCH 185/645] Remove unnecessary check --- osu.Game/Graphics/Containers/UserDimContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index b7da5592a8..6696a5bfe0 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Graphics.Containers /// protected virtual void UpdateVisuals() { - ContentDisplayed = !EnableUserDim.Value || ShowDimContent; + ContentDisplayed = ShowDimContent; dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); dimContent.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); From 0fcc6c1676089fd2dd963f937bf317b68252336e Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 22:13:48 +0300 Subject: [PATCH 186/645] Add DimLevel property --- osu.Game/Graphics/Containers/UserDimContainer.cs | 6 ++++-- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 6696a5bfe0..023964d701 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -36,6 +36,8 @@ namespace osu.Game.Graphics.Containers protected Bindable ShowStoryboard { get; private set; } + protected double DimLevel => EnableUserDim.Value ? UserDimLevel.Value : 0; + protected override Container Content => dimContent; private Container dimContent { get; } @@ -69,7 +71,7 @@ namespace osu.Game.Graphics.Containers /// /// Whether the content of this container should currently be visible. /// - protected virtual bool ShowDimContent => !EnableUserDim.Value; + protected virtual bool ShowDimContent => true; /// /// Should be invoked when any dependent dim level or user setting is changed and bring the visual state up-to-date. @@ -79,7 +81,7 @@ namespace osu.Game.Graphics.Containers ContentDisplayed = ShowDimContent; dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); - dimContent.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); + dimContent.FadeColour(OsuColour.Gray(1 - (float)DimLevel), BACKGROUND_FADE_DURATION, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index 8d1f703791..2154526e54 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); } - protected override bool ShowDimContent => base.ShowDimContent || (ShowStoryboard.Value && UserDimLevel.Value < 1); + protected override bool ShowDimContent => ShowStoryboard.Value && DimLevel < 1; private void initializeStoryboard(bool async) { From 565034e658ace24fd3d2ab493bc0df5496a9cdfb Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 22:14:51 +0300 Subject: [PATCH 187/645] Remove unnecessary using directive --- osu.Game/Graphics/Containers/UserDimContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 023964d701..2b7635cc88 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; -using osuTK.Graphics; namespace osu.Game.Graphics.Containers { From 7e9c100c9b25dd450e290da9d74ac068010f0044 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 12:29:33 +0900 Subject: [PATCH 188/645] Apply new resharper refactors --- osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs | 2 +- osu.Game/Beatmaps/Legacy/LegacyMods.cs | 2 +- osu.Game/Graphics/UserInterface/Bar.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs index a3cd455886..e4a28167ec 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// Keep the same as last row. /// - ForceStack = 1 << 0, + ForceStack = 1, /// /// Keep different from last row. diff --git a/osu.Game/Beatmaps/Legacy/LegacyMods.cs b/osu.Game/Beatmaps/Legacy/LegacyMods.cs index 8e53c24e7b..583e950e49 100644 --- a/osu.Game/Beatmaps/Legacy/LegacyMods.cs +++ b/osu.Game/Beatmaps/Legacy/LegacyMods.cs @@ -9,7 +9,7 @@ namespace osu.Game.Beatmaps.Legacy public enum LegacyMods { None = 0, - NoFail = 1 << 0, + NoFail = 1, Easy = 1 << 1, TouchDevice = 1 << 2, Hidden = 1 << 3, diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs index 2a858ccbcf..f8d5955503 100644 --- a/osu.Game/Graphics/UserInterface/Bar.cs +++ b/osu.Game/Graphics/UserInterface/Bar.cs @@ -110,7 +110,7 @@ namespace osu.Game.Graphics.UserInterface [Flags] public enum BarDirection { - LeftToRight = 1 << 0, + LeftToRight = 1, RightToLeft = 1 << 1, TopToBottom = 1 << 2, BottomToTop = 1 << 3, diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs index c9f7224643..eab37b682c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs @@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy [Flags] internal enum ConvertHitObjectType { - Circle = 1 << 0, + Circle = 1, Slider = 1 << 1, NewCombo = 1 << 2, Spinner = 1 << 3, From ca33efead43eafe29d0fbc0861e4918cae261f68 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2019 03:58:06 +0000 Subject: [PATCH 189/645] Bump ppy.osu.Game.Resources from 2019.702.0 to 2019.731.1 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.702.0 to 2019.731.1. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.702.0...2019.731.1) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index c4cdffa8a5..40c15a1162 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -62,7 +62,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 02bf053468..8ee325c2ac 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 5b43a6f46f..b46438f766 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - + From 58e98e53d276c96eb362f75b84cb9579bb3d4cb0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2019 03:58:06 +0000 Subject: [PATCH 190/645] Bump NUnit3TestAdapter from 3.13.0 to 3.14.0 Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 3.13.0 to 3.14.0. - [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases) - [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V3.13...V3.14) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 9acf47a67c..4100404da6 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index df5131dd8b..013d2a71d4 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index bb3e5a66f3..92c5c77aac 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 5510c3a9d9..82055ecaee 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 659f5415c3..50530088c2 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index dad2fe0877..257db89a20 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -7,7 +7,7 @@ - + WinExe From 5486c7736277d3d16b9ab1a45dc4051f24a5e7ce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 9 Aug 2019 15:25:42 +0900 Subject: [PATCH 191/645] Remove explicit autosize --- osu.Game/Skinning/LegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 3426ddaf16..5357a75e00 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -140,7 +140,7 @@ namespace osu.Game.Skinning if (texture != null && animatable) { - var animation = new TextureAnimation { DefaultFrameLength = frametime, AutoSizeAxes = Axes.None }; + var animation = new TextureAnimation { DefaultFrameLength = frametime }; for (int i = 1; texture != null; i++) { From 5073bce2dcbf8a5bce4f33b06036822524494082 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 9 Aug 2019 10:47:52 +0300 Subject: [PATCH 192/645] Basic request implementation --- .../Requests/GetUserKudosuHistoryRequest.cs | 21 +++++++++++++++++++ .../Requests/Responses/APIKudosuHistory.cs | 20 ++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs diff --git a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs new file mode 100644 index 0000000000..e90e297672 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.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 System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetUserKudosuHistoryRequest : PaginatedAPIRequest> + { + private readonly long userId; + + public GetUserKudosuHistoryRequest(long userId, int page = 0, int itemsPerPage = 5) + : base(page, itemsPerPage) + { + this.userId = userId; + } + + protected override string Target => $"users/{userId}/kudosu"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs new file mode 100644 index 0000000000..949ce200d2 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -0,0 +1,20 @@ +// 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 Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIKudosuHistory + { + [JsonProperty("id")] + public int ID; + + [JsonProperty("createdAt")] + public DateTimeOffset CreatedAt; + + [JsonProperty("amount")] + public int Amount; + } +} From cf2a9db8e048abc2e788c8ee210a2d7b958c9010 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 9 Aug 2019 11:14:38 +0300 Subject: [PATCH 193/645] Implement basic layout for kudosu history --- .../Kudosu/DrawableKudosuHistoryItem.cs | 56 +++++++++++++++++++ .../Kudosu/PaginatedKudosuHistoryContainer.cs | 51 +++++++++++++++++ .../Profile/Sections/KudosuSection.cs | 4 +- 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs new file mode 100644 index 0000000000..1671073242 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -0,0 +1,56 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; + +namespace osu.Game.Overlays.Profile.Sections.Kudosu +{ + public class DrawableKudosuHistoryItem : DrawableProfileRow + { + private readonly APIKudosuHistory historyItem; + private LinkFlowContainer content; + + public DrawableKudosuHistoryItem(APIKudosuHistory historyItem) + { + this.historyItem = historyItem; + } + + [BackgroundDependencyLoader] + private void load() + { + LeftFlowContainer.Padding = new MarginPadding { Left = 10 }; + + LeftFlowContainer.Add(content = new LinkFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + }); + + RightFlowContainer.Add(new DrawableDate(historyItem.CreatedAt) + { + Font = OsuFont.GetFont(size: 13), + Colour = OsuColour.Gray(0xAA), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }); + + var formatted = createMessage(); + + content.AddLinks(formatted.Text, formatted.Links); + } + + protected override Drawable CreateLeftVisual() => new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + }; + + private MessageFormatter.MessageFormatterResult createMessage() => MessageFormatter.FormatText($@"{historyItem.Amount}"); + } +} diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs new file mode 100644 index 0000000000..29b1d3c5aa --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -0,0 +1,51 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Online.API.Requests; +using osu.Game.Users; +using System.Linq; +using osu.Framework.Bindables; + +namespace osu.Game.Overlays.Profile.Sections.Kudosu +{ + public class PaginatedKudosuHistoryContainer : PaginatedContainer + { + private GetUserKudosuHistoryRequest request; + + public PaginatedKudosuHistoryContainer(Bindable user, string header, string missing) + : base(user, header, missing) + { + ItemsPerPage = 5; + } + + protected override void ShowMore() + { + request = new GetUserKudosuHistoryRequest(User.Value.Id, VisiblePages++, ItemsPerPage); + request.Success += items => Schedule(() => + { + MoreButton.FadeTo(items.Count == ItemsPerPage ? 1 : 0); + MoreButton.IsLoading = false; + + if (!items.Any() && VisiblePages == 1) + { + MissingText.Show(); + return; + } + + MissingText.Hide(); + + foreach (var item in items) + ItemsContainer.Add(new DrawableKudosuHistoryItem(item)); + }); + + Api.Queue(request); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + request?.Cancel(); + } + } +} diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index a17b68933c..9ccce7d837 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.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 osu.Framework.Graphics; using osu.Game.Overlays.Profile.Sections.Kudosu; namespace osu.Game.Overlays.Profile.Sections @@ -13,9 +14,10 @@ namespace osu.Game.Overlays.Profile.Sections public KudosuSection() { - Children = new[] + Children = new Drawable[] { new KudosuInfo(User), + new PaginatedKudosuHistoryContainer(User, null, @"This user hasn't received any kudosu!"), }; } } From 093359c13bc05d590e227a9db7615f4dc287be57 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 9 Aug 2019 11:19:14 +0300 Subject: [PATCH 194/645] fix incorrect json property --- osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index 949ce200d2..271dcc320e 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -11,7 +11,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("id")] public int ID; - [JsonProperty("createdAt")] + [JsonProperty("created_at")] public DateTimeOffset CreatedAt; [JsonProperty("amount")] From b0eb2c6e28cec2831e02f3f63125532041232365 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 9 Aug 2019 19:21:08 +0930 Subject: [PATCH 195/645] Remove iOS BASS libraries and properly reference --- .../osu.Game.Rulesets.Catch.Tests.iOS.csproj | 8 -------- .../osu.Game.Rulesets.Mania.Tests.iOS.csproj | 8 -------- .../osu.Game.Rulesets.Osu.Tests.iOS.csproj | 8 -------- .../osu.Game.Rulesets.Taiko.Tests.iOS.csproj | 8 -------- osu.iOS.props | 18 +++++++++++++----- osu.iOS/libbass.a | Bin 1717480 -> 0 bytes osu.iOS/libbass_fx.a | Bin 621624 -> 0 bytes osu.iOS/osu.iOS.csproj | 6 ------ 8 files changed, 13 insertions(+), 43 deletions(-) delete mode 100644 osu.iOS/libbass.a delete mode 100644 osu.iOS/libbass_fx.a diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj index 37e7c45a4e..7990c35e09 100644 --- a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj @@ -13,14 +13,6 @@ - - libbass.a - PreserveNewest - - - libbass_fx.a - PreserveNewest - Linker.xml diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj index 24abccb19d..58c2e2aa5a 100644 --- a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj @@ -13,14 +13,6 @@ - - libbass.a - PreserveNewest - - - libbass_fx.a - PreserveNewest - Linker.xml diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj index 9930a166e3..c7787bd162 100644 --- a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj @@ -13,14 +13,6 @@ - - libbass.a - PreserveNewest - - - libbass_fx.a - PreserveNewest - Linker.xml diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj b/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj index d2817b743c..3e46bb89af 100644 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj @@ -13,14 +13,6 @@ - - libbass.a - PreserveNewest - - - libbass_fx.a - PreserveNewest - Linker.xml diff --git a/osu.iOS.props b/osu.iOS.props index b46438f766..82c60d0aed 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -3,7 +3,8 @@ {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Resources PackageReference - --nolinkaway -gcc_flags "-lstdc++ -framework AudioToolbox -framework SystemConfiguration -framework CFNetwork -framework Accelerate + --nolinkaway + -lstdc++ -lbz2 -framework AudioToolbox -framework AVFoundation -framework CoreMedia -framework VideoToolbox -framework SystemConfiguration -framework CFNetwork -framework Accelerate true @@ -24,7 +25,7 @@ false Default - $(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a" + $(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)" false cjk,mideast,other,rare,west @@ -44,7 +45,7 @@ NSUrlSessionHandler Default - $(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a" + $(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)" false cjk,mideast,other,rare,west @@ -62,7 +63,7 @@ NSUrlSessionHandler Default - $(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a" + $(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)" false cjk,mideast,other,rare,west @@ -86,10 +87,17 @@ NSUrlSessionHandler Default - $(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a" + $(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)" false cjk,mideast,other,rare,west + + + Static + False + True + + diff --git a/osu.iOS/libbass.a b/osu.iOS/libbass.a deleted file mode 100644 index c34e6a0a0cfb30a240d70443fa0276f6e2774f90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1717480 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 z�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

n1vJMuGM~kIoXjExl$^E zH)vlmv3c}Gc$LmB+UD*E-jA%o9@*i^9}o|p7_;svkeSzwjxk@Y5${y!oovzn`;SGH zLB>Y#JZfdb9Al}_Svy8IH+D7+gDUnRIm$r0za$` zn(>>NDzaB8Z`-Fi-zl<;Iq-K@y|?X*)&JIcZ8z+L=J{29=O)3!UCtTHU5 zR_v(>J-Kf3w70)zq%I+D?+IWCUK&YFAkIVbcVh7`h^@N3U>A9BgGIK@;m1CD^V>%1 zJ#q#A;d7kt$@u_h<{5)AVzf7b^RDk#bhceox#a`T*sdQRn$q2WGkd38zV^xwZ+Nb6 z^df&1bR%0y->Zz`VT#w~OjAAfd1v;yQtF%ft#(5fMpDR8E8g!7;?tXj-|4np@iuf| zdVdu-MXn8W|DF(I)rnpu7hmaC=(F?C=enCH|1vlYO?)(fK9A4*fZRsu_h;rs2LC`# zr8mDFNgbe^xi0!(Cwnbv@2GMI5})+=kEvsb96D1DJ{lOpKXvk}#^P*rPuC;B_F3S_ zX1(W@NaYghuDiupJRdy#zJYwOz@mNWyF51xv=Y;H1R9#z8X-p~aOSf73Ir>rL?cDtLO8{M5{a7rzF+`jIUm>X=I%ebk{f#T$s33PFE; zGmJser}JCo)#jNoEl@BZBw&sTpp zrS%H&VG!A1^J8Sc4}ai$zDZ0$;Y0BLCS&*d*4j=lXLB89+<&-na(AdUlKLTI7RoWo zJ<9!uzrc9SAT1T=8P`VkE4FJcGGRUaRK3O2FTBl_Jj!?`o>6`3Z=tJTrD#cKfSb2Z z&ke$hb;K1*9`-{+^{#5gnjjN>akbrqzV79@i*wz?kK(<|*k8$pY-EQczo55voneGc zdH);O?L)wF0$6;m1FM%X*7etIx=FccXCw0@SBG>C8Smw*EIv?Fu!DP1QAq*1XR-Lp zNB)!s;*gHu3lP0EZ{HM9J(5kPYeKu^cON+?)Hh3Zv;L*A)m*1|0s15uE|^zUTo5)c zE^rZ}>?Y>f<1Q&UwKbBO>54o+oo|ntUQ%$;^r8aQd(X2M6>J6OQPVFhxSw%&ZB1z3 zlC`03(cSB7V*BnPR{9>|sjplc+Sg8uBp!c- z9N^d~3r~6OekxHHZ0|M9Exn5j@|SC_=kD6U_Zpv#7Z`iClPl{aHuQIq0g~s2Ii|hq z&<)*V>1((;+ju|BEhhA?IDI zX6@UIKH7?0c@^1rF?zh~nTy&_tZCl&%8OsxR~#%UIPu~|``o|%(mv@0TkCQA zn_KcHhLJbBfVcj#oN2<*+9gKrEM#vz@hS7br=D4{EQ3Sk|3m*?LpN}~=Zf{5@iBvP zuaCh;G$S&IJ{kPZbFN>V0Cy+uG*Yia>%U9q2Y=gtP3U*{AYUc#%L#J1y@o9Q;l}H` z|1>8uD7^h{%7H6JGj1or?GxZu?}SU?(J%_yXJ88om&?KBW^lQ@XI8uT$Auq3`1}L- ztiJu_u^U#uyrB3y*%OL?TYQc1NZi%JtHI+;>Z)HCd9I1PJBAt5*^1Wp)$rN^_-{S& zzx7!MR@3K(8s#+^nW5nbHT31k*gy$JoEg^~N;&J3sI(h=kkkU43%ZHt<@#HV&-uG^{g$ zHJ*lb=00ewLwfPsz$*IPY0)p`KZ1S@V>~hBIsTc@pyHTL&S|&yV@mGTA@@YL+QT4P zdIdVXl|CFSvU&B*DK>oK(b>?ILl@guFW>ib_gMdq8*kk=Z|(AZufcN~&zpl67Q712 zje_S~(8jWCSD`zD=jNqh-UZCZ`9?4s@Z9k<&lQ=*FwZTA=Vobs8akKX6c2VY{H8G$ z?1nLcSTAGYNqkot2fH6;7kOYUx)k4>5C3m~fBD`V+_$cd@B822{m}m!?*$);_gEV5 z7ecpA`}fA;m+wYTebo3DgB#bXv*W+jC|WrDKKL7^ zgYjLbfUOt#r2V{-+oEe=SS)$t$Zo+tQg#d9*JSz6mEYAbjXPM!wUFz^m&QqcXUZSR z@i)^vee19sk7vknn+MLy@w0gN_Wy$%-zhmh`z&1vC-`HAupU=Ek-`K!5GdMi_wW%m1T)n7N$@2lW{+0+b`h36TtdQx8MK6>Py=%js3&r6WkLTUa{bhBj=FAl55Dh zSJuqj=RqzPqhD&qO3t07$wSz28XNUvr_~3^=a23~99bt{Npps*J0G7KMi%j`oLQ40 z>#Xr%Ouoz9AqiavFC_Q0k?l`n=b0{dJjq^18=f=2VB`iV8^jh27Bd%tH+i2ieQVk)i+FTsD7c4S3k! z!uqz>x%098^NI18IM3H%-kjahi|wR&gGv4g-M!fOCTB)#4ZUy<7ja6xoL|{HMSf%3 z56bzp*14k7;t{@W&Be!_dVi9!=M4EUf6CfRXD+e1{O)5N*TA2mv)l8G)!$0GYeI#Z zCt#=Ox%R01i1pGRkLMgkY&AW@=XMl-+1pG~SZlG{+cvr;w4;RhuKTdgiA`~yvqqcu zuBRwG1-uS1*K}bgb+Vo^mp1y*WA8CHlGEn87>UA9H&fI>Xe%SVjCA(-*?s#4bLS*&nXakvS?s_5iC24(HU2g}R2D_N z_i5G+oo}>X&BT@kmv1YFUdR>jF)t-=hWrxgb&W}^b+Lw-`Q3J_-h3;Mf#6_&U76F4 zQ}+NqjwE9k#ZS}8I*~Wa7}Omc?KR`}+7kYLV6pRoXw28XHMI8g`3pT3wirLd8s`87uKiaMQBa9JC%_!6WLLgVTRmSU_af^JW^lu?|8kq{&Uxdl z#0R|x?ZI2eeoL9D^v@)R1iWzBQfRQ}k@R_tA{tM!L zsYCb2h@CjjZ=2qxc0ERJJg2Pz{9ES7i92TOfTfIePtBe7Om;;EwRYdL37tgzhrSi> zn(!`tu>50QzLQT@`B7aKJ=t`sGny1**YgxIW1MkW5ipy`hhAVkT#B5Vq%rlzw}B62 zjdkYs0iLT3#dJILG!m~7$|uf{ate7g30xDqb=fxRP7q(1315QoD@1n+-x>qqpm6(y z6<)q6U!MpZAES65n`R}`!Y>RB%NGMUfoo5m5gAmS^6~G1whEzlhb9>JWB)JmSUIGk z_gS%}do|{_S!14#8~-Ou_m@Xs!FSDm6vg#M*>4qXg#WH*PK*3f>~zxuzz59;-zD@* z@CnW+bfxtotA5~b0-uf_pZ9t8_}DZZ{oZFgo1eJ0Gv@Mku~ynetb11sn!+d4C3A-8pbhb_{-^*j9-xfY{%NoT#V)s1e%&(lsl>wS^^L4NmJb)vTz zXVuxp*=F=FB|B)t=*a$B$}~`BncLX^|1tOO@ljUS;`j5+s zfWO+?@2ys>aUmmCzJsu%lx1EL38}N`&au-irABMpF!>XcNwX7 zV%sosq6utvm{!=;LNe7n{6&3Uk~vA{z*gF!_n$T84s>8rrq!y%LZ-nhTJP_^T*^Wp zQGwe;f9;8IQLqCk)0LPK8oInx3F&j1QRc(-Lw)Cd`%!)8zkBC~J^ebK;E$KDs$oC# z&M^3;O$|l2ksBeQ!xnhbZuaBrbJ9oSni}VACgu2Hd|Ezf{Pg;%7k=@)#UlG`@pS?B z_JeczMc%XY-BVjSB0NJY3hBNAetcmAvj;Anr_jaSeZU*VFJOMx0VN9U z>NYw(hSHfc-!kxP7#o3~_s&vvS>Wf`V6lhQVBdLXZ!dn$g*&~>m2K_b7yr9ya&&bz@~$rbtrJkrKDVi%D*MFNd|6XZbskT#+W5Ci&8X)ZLM4G!%{|K)Z!=baB45Hr9RZ` z*^pflY{utJV#xuEM(0SeCiLcAO7gwQ-pKM}TI9X2 zE6Ii#N+hw3^A^rO;9SSKNzTCINn(~{dL!;5m6606B{?Ve!ic+LRwS`d>rdEt?yQNt z@f7u=&wb;Evk^=y`{b;iLZ5GEb9};*HJCBX2z2Y%70obvt%>ea|-dCNjJe z7{w>!`zCp4zzGXD;qE5SG;*)VSQc#itv8ZqTlCv%TCRF>!>fWzt;|jGec~zP!_T_( zoFy_(5i?(x4W5{!iteZRQR>&*aN@z{krU4}m+$|m4c)W>-+lJ3V;2&u8^fw=9>{%^vQIWp`&}ks2aG|`% zju-Y6A-i3`;k0@JdzI)0>be_Q^Z@(ro&iSM93}5Kvd1=)Eg0SvF7Be9PZQfg+UxbX z!v4MPuzE5r@&vRb|HlUx+qOn5DTTO~tZBFw-<(HHQ-eO%wgJ{To{kIh+RMN@)-s++ z?4y7-M%f<{*lBi;n%C`O9@G7GrHx|KDPnK$jV7(qMStV)kE!%|9WZ52iB9`{R&TCG z+}Va1%*VN2=v6ybF(-B+8)40Ar3;xw2GFOq_hUzV97n3dgq7e!(r;mM6KW#4imT z$d$2o(#|Gm;W+edjC*_|uu?Re(7o_^d1st!%q2lnQdxFpk}@~@@zmOM@G)inK5`@n z_QKb`dS%CP`ZdBoN5P{;`ri%?y77G#oRIdpuhN#((4NF|>;>YPw4?jIGs~W$4$*0q z|8d=`Y=(}oA9SSg!@5^Tq5Yb4tz#o~vKM)YmhN5RpJ{fVUg(Ri2M)`G)J^I?O!}e&(FHz(X6`v?$ZoIP{`d>$WQ`W>HM~GZ3xwFNVE3lG& z_p&cfcslj5AB9+p@K-ndbyHr-&)DCH>XUd@eK=o6BsW-w=XFFuQ-KZb7*&+As^b3cB& z%ZNcSiT|E?y(oF+cSXqnb43k(mpLfl1oxq%i|Om1pMyWM|Gnlx^FTW?xF?+$=-Awk zptH7YP?tKso8A$>URn0W8urQkFulKh`VS6yeimVF!AJ7LFTNUoZXW*8-d9uiD_`9t zzJ&PSo*PGG#jA-Q&x?)<%!wru|H-`QJLD4lNC;Zz&Y_2dl`ko?3pLK(6Ya{dCC~foT*DGFaw6OPBwKhpR zEZL@|3EBYN=Ee8Si>{_lqb}n=_$D{IoJu7A6D8S`p+sH>fAZBwACCj)I5;V}m>3KE zW-h33U-TO5Ym2o<=MSPkB35nZ-2?BlmizYph2c}ox!opj_2tTR{G(H{nsSXYaGLjL zOhtMuSfRUx`?eO#xSs%TbomR|NL>Zg^_sLHPdT}RxE|Up;@e`=kz6wp!_D!Vg#$t> z(2w4ab`#d2-+z5@)U{&RE82ql-1hJJ7T- zb|TXlG(4Jl@2=jN)~)W`N#QEs=)k7s0k@?M31k@e(4@#Bo)-z-LlX|>`+}eK6vvsz z;%id-AT;Oiii=s#r}|x@w|)D%>H*pF^`!6=r8p>ZNx!uy?E0?Gdm}aGLVX{0e2p)9 z?;5S-y{~(r_o+Mo{2Z~S=%efpkTH!TXUez=f0Q=G=Ydz?ejjt!#BpB6IENllBHiMP znVsT6A(J`MO5{XB~+ap=9h(VINZe}wK`ulNRp=0wIx z6p$}{7V?bzUvM1zu(ZVyL6-HS(~HCEzlCe<;DfT*MlR!*~4bH#Np{ zelC1s2XI@+|DNSsj%-LhQeI$v3i^?JKy8eR_z}qZPGBL=g#Sxk6QSFQ^?e(i9`e!) z0y{6?Z^OUF#vZx%!0Q6@VCTC$pK4Pg2JH^-T{xm;YGH@seQUtf^Z0j=x8yrnzl?yx z@kvVFyT}`U`Y3g>z}9n-$@LN101dIGOwo`&mt3yoe#czYB=s2WTJRe`_R!#lCnAMMTchoE2{H=OBX;Z51>H)#g_4IR? zdIVk@$@{R4xB^1IU1zk8p5OV_1=-{DE<91kQy=4sjBK>o#n=?5!yjj`hTXp?{25?! z3OKw-em|ox+P;M&eHkg({c;?3KQ>K(-IYq-7=3&fy^hd80d@mv|Jm}2x|BR66~iVa zDl*aO`_w6~!FLLgcYcg*Z~YX7JZGskKU#|on|6QYciwdZ`_1r9frs?-UHG@)3V1%g zuOO96W;*b^7rg`fXo0cQ5fKzr(-eoAaL!ljEp{cFVd@@(#TZ ztp>`kapOObd%VD#41&L1(Ci1$$Pwgp=K1Ey9Jw69jl{E@p+??V@2Gf2Eozc_a_U2Q z&pi7ualS%%=sg~ONl_w6+H^+E#jjIY)^ zOT#(Lb53Oax$JA6Yf_t(U*9oMswhn=a+g!dX>ux)Y$pD%_;?Qqy z-~A@Og%jH@J{AuVPyKcD_&Gxl6`wR;OkZ+?|2Fi{a=AWCn;c4RaME_Uzr=G8+xlUA zgw^rBsAv02W0Boo*xX0q2I^__XixpH3Ht5RlS{ydqZp9h9T zlz9)D{?ior_WjH$=pcqJQI_3{%=w*5knx#|tId-mN7$ocsuz7vYOQoHYm4>t1ARxn zpLt8N%Od;gv1|{@JmY=jEI)E;;e6E{nJ7!;t8*jgm$UqmTyg>{ zXle);Sdeo@;SY^-O_3&Isjp(blNfrYz-c(%mD7FR#z+;f%O1ZB0~U z2zym@y>~pw+5vevzLN7I`pf$Sah_XPV;z@yo3^_7pXd8c5;LsHkdclDz0r2JrQ|s6 zX_tK=(7CJyY5$VOT>3!yRniCgBkRXF?R}bcx5y{>@G0-__eAxWOF03Aoqq z#}ALW*9B~39hO*0`&CVkkD6fKuOA`4=`V?Mi7iLk7cal6--V9BP5d*@7npy?+liu~ zseI0~5`nD;UUULlyVjN!F5g!ku1Cg@c3I(D8vc}0e_yRD+PdJEk_@aMZMxX)c8|mNVCgBAM`f6 zKc>w>kFPIBX28ed4aPLWe`V~&5C17*35Xmk^3ORq0j`M5dk#(@-=OzO^@H!Fj(-Lx zY#)OYz~rFFh3vT&{6J4KE%@4tJ;mU?o{!lLekOpg$bzidn?`|SgRGw?;sDBi~HT+0eBw~xzsU^ z51)h!A~VW3IKcLa2f1qFVfRaz}H{cdHdM$KR{7WTQXk5n|!9S6c zzdklS@eDlGviz7)Ja?>_L zZZ3xIrxOpegqZiKc|vl5E}wB>c_Sqbg2}j^j#r2gQqHVD)XYqok!3~81nMr zMHNw*^HpfrcqTeY=Xj29`LFSfJ_j(*^aFF1Jr2hAqF*_+P4t%%4=J@K+5UiSKo(a+G2 z^mSr?4x26*K<+);9_)bl4Tlcxpr1w?2ixZlJPK`Xs~~?3eVf>KWu6i}0-TI*+3gT@ zoH4s+1J@(Szs7UDUq4p|l)sP$YQq1N8A>z+|2V~dkat*PiY>B-HJ5QO$kfN#LTyRgN-&zcHdBV~(rz6b71Y>Rfs1xxFjT;ZMvlri~!D&M1@tk7t4pZJ2% z*7u;BQ}89hmp;}%=d^7ReVf?Un)B}K6j@K|a^!1AO**Y@W36a83H||d4g1v|&`|lC#HItE#cpthoMl2Ao!h+{WOFt3Xp;j}rw;(sR56;p?XZaNM<1i(|l1HpSk_Vls7 z_al31=!!KbwDl0Q#dkux3F37#KKT;sLduQ;4?XwHx{%lmAKnZ<3{SO%+jFhqdSW43 zd4_x%X>9OUN&NKyvUWQ%ZVPhX*cxxL8-5$$UvB>8=3hcj0scq4h@}SpR({Tpc~Z$A z&IonBMqG^{*2D%L$-J|_u@rp+I)3uu5OXB=gJTy&dTyFOChZG=OYfjZlKs(vhXk&c zAo=!|{jEA4wJNziH!U2)Z$j+L!8+y-X_v^evPRx?)16~h?8M(7p3y{{R)Pzvq)dXj z#-RNt;j<#ExZyF<_k8rhkKN=Sdkp^>>4RbSc=uRtWN_X50WElEmEd?ObD^vQw#)hi z8D!$OzqICux0|q8OenwIWYYKBPkc7acZzDl_eYJQr{(`b_mWIf@V0q{)jJ(r^U z0oPpQbCfX_ygNO1ra;DA#@kISEEyBImiOW}Q^~W5bl*q)?;M*GA?HYyzQ^XFa}rBXRc!JP`4=)$Zi2p*cHXmF z)&1U_cCT593B9&6R$^=1Cu4<7(1TCFVcLF#F%USV=Ix6j$Hw{5QJL$Rw}mH&9RGR+ zI^(gFPDgY>VxzmAehD7OfrI#&A7(Ck?^t>Y9+~IDLvXhDKGT#+WK`swe4(XA;34zI zh%NNUiOlu8*f02alg$M1eOxB$s1g-`vsFJvd5Hha)|MtNxR~*uY>Y# z%6rg>dhk;dp5VoI(+ONl$%)aR+afa#`jESH84S4#zg+r~aZ=W)qJup5pWtejI%Sl4 z8>zREcG-??1{>R!EUPgSFWLLDSf#6yIp9U*_Gw5A(KOjHjV53dMU?|Z3g}jUCNG(&btKKRxrdij+AFSxeT>)i@ zn`aF}?(pcUoz0_(&8y2xgCL{5R{fb=+qKWxUGUyklMI%Cl`;!&8?qwz|${ z6|^Y40J%hP^^oACWtCZcmqo=l1JIc=Lc8Cx9cDAHx?kDqx@ZqEkYpbAH`hf2#QT!?UZT4iuns?d*MInu z??UUt4|&HNX6^V2a8BeV3vDYjYa<0}L0IBGzJQHQe-Gb$-qbSoVwn;N5MOF1vZl;e ztZA1`?6=W=<2(%g_HzVwsmXpT>q#|#q*N{Yo@y@pp72xV!S9K$VJ`n&kd3eEze-+C zq?0d-ONqiE|em}84Qr75Gky7VHCYLn8~s-@lLk%NQAB_^3&(F#09yqx1b!9n)Epdet$7ul0hA6(G=jp7~ncp2?uJ-JiH-iTW+@l7VaKSf#jc48Z@V?83{CA|Lc z$1zX&bsGPZJ{)E*$S3g*>9h1zL9sbW{D!d3Lkj3~iVnA9yYz#PvK~5$FM<41 za!^Ve2FX(^{;dB990c#BOe_D_&$LNDo5s&&TEyrJ&p#F?#D`a4)YWc|-UV(5-Ko%c z+j4XCZt6Gi^-k(C*5+LvHQ6633_pcy5`8hnrh}E?1zD&1Q=gNzZb0|J2n}mf;rtWDoku5WL2Sb%YOG(ir=Re(BXeO?i2Z@vFw}$W=*23;9e9`$LOXaer zwX&wAZNgXZd#QlGJ+I-DF8K%J@R+H&-zb(fMPCLvl4u8g#6Fc(f!?8F0dejw;oo^Pd!=5TXP{fq)B>BxuYxPuv%Tbv#)f1{$kLZskA7k5)Hp2upf#UX5z*ko+l|GK%wBxE|$NmpeqSf1kG0 zZQ0%&c%Wys{C5a>a-wd*OHNVN`FdQBcG}p4-dH0B6M2|ytJuH0`Q+m2o+4!)@?)eX zSJBso4Mi#4ndJPV?@fNjRx@-I9nw~9;WFAQaAury<-Nr9A7$+=I?vwwrY@~XIy$Ix zS#R@{r5@GM+}^H4NkX)A6uq0opgRFxZuZ@2ZQqsc4oynCUi4_)>fja5f$g^`i+9{+ z+$+S(B{9D5>H7;v(<5#YH!)lePIo-MxRN&m9oiU-|?-8e=&EkC>WMxC&E5$uE?UB*#2ov2Mq}{q?r+j(E%*w3A}?9=p10B> zM`)i38?>>v?a1D$u;jYc$n7gO|Gm4|`!&v&{ot*Fo~D(uqWg$rGXT$-_mqlB+_zDm zd@K7V1n1?u5dSy6Gv?+l;O0>BgNJ{-t@z_`{d_q|mp3xdIpSm520W(z&#&rhJb0Ua z4^Kc3q*Q)d+1@<$QxB{b{=7i0T^m;$G%Wce19`+j9oM@CO`+(C%=>n=yR)`7NbYm? zK#1NCT(*gQQvOwnPV0ObNz20Ck|yZ>nL6d5^iSl(t`(W&QobMpKTb{~#+<;rnEIEq-&p(wHqV^4RrX@EKbSez zF8fI-*Q?KDcRlh9dD$D)?C>U^!dgyA%3K)u^4Fs6mEL3n{{OBe z#4q-+p8SoU{A0dkH}$rc2~V;HWp8miwy(xc{}{IF=du4+j|gAC`I_h|$uW|9ExE@e zW+8qAjD_SoMvqa^=qndrf$HPTqcYAWE||5EHX%W9abbKgaCV^&L58C7OHN^t_r{ zbB7n+a)v(CiEfg1-P@fO>5QaB?%I(SX;(8MqnS!_DdjbM{Q{M;E-YLvJX?n)^N{2S z7Fw?nzJyIk@+{WVp3Q~8pElMPmR25}U@Q6$>hj=2(8N62LK#1PU#@icFt#ZfFR9B# zdBL5wD>I|wqu?l_&*UEPjepZa`(5-Up06y}!#wnTzHyQFOwZYSeP*<4IXL;{R9yk; zl-ygEE0lTteEYb3OIZti^(o-)rmnc23(m4r{^{ht&&2yH$OBFt;)^D8lISY54LM7t zKADf==E=;_IThktFXJV3v@s|3Qn!b)^~e!^+TtgtOyB#Cg@Ma5qrZcHVzZ6}fwPtI zZ%0Sp1?*+~EsTFaaAkb_MV@NuPVI@TuO|LiF0jJ4rha|j0J+7`r8{1ey6f3X(M8=Z zC8uIJ?P&Qb_=3-P%QNVVX|s=US80=r93Jj_)27t0NBmlz*I<_rpE}_+%TUg-y~ z#E-8Ayb`%0utLwZLM-9TXrBDb;rUJ-msY*d(I$St`%Q`b8=>5~H( z4UV$baZ(p&gLnIZQG$6+_`}M-oLPpxCnCI2Y*01-~^XHIwfp?dsug=}5s!ba4FSQS^epO(hvHq^dXH+X4&+P*LwA4Gp z3b7#7wf@~@oqj!ric|DKYtgTR|HPdS&R{L{cjuXn7an|PJYML;9H%|fC$SyVr{Cf$ zH-`LKG}$)*bDMt{zff6^80)eG_G6*z;Z4YNS7D=>LfqCDv<}fLP2A&Q{ZR6`tk@#{ z+v1CgAAGLpnMKAtK-qemC7k^Q_!hqUL45Vml}E&9@@eMXkec1}!vm!f`z~@V-#y58 z@_aMTbF!4&lfwJ!GVRyxae*Jcqr zOUVk#TJg;WXPB5ay3eLUj&boXor~V^b;h%sHJ$ihoq%umPUy==@sn3m|sXR3z@~YT@$**`w z`uAt%y*Kg6JB-a_h~r^3J8Zhm7c)P^fxk@I<}%0LpE`CM&z#~*LyVWhS1G%np)Y&7 zk;T!GH9FNukV9m29_J*rKAnb4R{(4a@tsMniMG?HA&#RQU&QCZ zTxZhPPp{RQBBwdll;O9-TqXQm{BbPQ=ceyHlRlEc1n)kNZKcax6l{lYx$*aLt0hg1 zCgd8ob*s#mqvSvsoy-|OfClUY;$vg6;1fxGv^{dyXDnMS7oul#TeeCb-uKW2B#}Si z8IKTC`;d8w1--Sbv5WLR{DD4%%r&p!`x7a|ZdZ-p^J)6<0!It`X?(!5Wg~na{ebXA zv8#*kMBMD_U&FQZM`UHKh^*%d@Ppy5;^Jb@hORoY#~>s@EpN44?Mq-Ir2FF*2qy^qk7+}=U!3m6+-`( zERiYH;3nEmJ48m-VPw;&2fiDG4v7sLwd9M z47({S>tcbQwC&?<2@;doQK7@}Uhk`cjKNNkg@Phm5U*a!2JmqZn~>4B2B#%lif`RS z9fc9I=Z$%LZdJZ=%^cHWiIrJqS6xoK>Q!Rqhp(O!a+TV@NUWr^D)#e#`>HwnTr=$d z>Y8cKxKxQ{4lbUP?zzbR7uTis9G4Qy9j=>mjb|3Y(<|(GrAlndf7Q;3c;?#g^vt)j zku)~-*SR}=ffI! zUwrE|b3X5J+P|}?(tfY)a{HHUGwoL_nrV-5{Kulp?cXiG!u}nOndLL>MV<@o)r+d^ zpR-ll|F1>W_TQ9O+i#|=4rl$G-`i^J&6hdt%~qG)>7xA?HOz5pmG%QwSK1qiE&6-c zmGws<00MzYO~H5^-p9F1yg4H>Yt|zXYu317By=OnVw-uXbN(UtE2meWh&%a4zHfdG9qT^069`oET=;d^sz7V)d^;CPAq2SVww2Rw`Hx2)y8Hp_kuv~$bndB^qD z;OqmJEwazb=X(yle8?1=bt(58dU+)y_CWaz`z`m5mxm5+`RsUk=xF1j8TOeu-q!1}UI8&CzJx7^lcHAFQ zV`Wv`b2z#0Rx)GV(A|o!$on#TE%dnJQ}PZ!2I#h%c(`Sn)HhyUq5S3CbLizmnK5U1 zseMJyczJlsifhNqL+hoBO6|@xZ)^pJ#AfRbDKV#)dk&e$Ly8s~1XtTOr~EH`@P)Q| z-f8%|C`xQ_(LB3T;d>6fJkOkqx#!T!hqTxm^M+O(FCSVZc5ImgO8GX#ccuI@#Q#cZ zdx&ii0Dl6aT~ z|EcA9Mzz3ZrhPB)`d9pZzXpxvd`WQsQu}{FGcQ4dv%KC|hsztwwC939T5J|$*D-zk zp7EQ-^&PY|g&*J--`+tRQ}~e{%eaCz|3D9CgrOTAMGnQRE@U*c9-^ zyc+S9Y4ekOb0P0bX^X(>OS6f$o|XpewV0EBeu=(yr=>IY8Q_OE_Qg_S^2>X0!3iwB z2n_Ul8C$;n2=?Zfle$&_w-oHtiRJ8#wE^E&7LXxmvy`%Jz)Zh~HWm7=(qA36^h<{= z{ncShA9dK$cLTQnC`@mmE}cf9ky`|oR%j1=yM?+Q4qYAlnK#q%HDD`r^RQAMdx`r8 zfc^gtEZgY2Q@haagRa|vi+&BBwF&&dSD}|Sft_4Kdu@t0cE55penqMd>o(waf2bbZ z23CwkD{$*pu8Fm#DZnl>)(YIZL*w_rzU2dRKe?!r%3@&1IO#ByHVA(5PaTHTsl$-E z{@XBwXP$*2JX2u!DGq_54pU(GDGq_*)xi7z2n^w~XJH7RJqyFq2{2?X5E#~S2n^9Z z!~}-590Efx;~+5faR>~(z+YhK{n0bxv}*Elyhbht%JK?70FRfJd=5xt#|d zw^6??b5ehh`fXXZa29qca-N5SDti)%NnoS?6WEvS+^bTc-s;;n`9{#djNvkF1;97f1 z@0PXNx`ck?3+zC?j6c^?Y(=IVdHLx>$6wz3RwMiWucfbzAFkYTt(s+P+|X!S_1nzo zs%b6N+tM#seXS$ZoL#|sRoz_tAaZ&Aj_eYFW6!wXh(`I;8hE9?2JS&m5>U5S8hfBE z{OiDr&pgup$XE27GH!C8iY|ry_ETJv-!%Jw6#JjZJjahk`!zZf*4uo?dXqE$RpS3A zc@@Q%4_>$1Ni0BB=#M>qD~WwhUW*0#cuCpJ3-q$?#oht8d$_o!+a2_5a7<||Qkvbs z!L1fGH{>f-QtlXQle6W_)6XrpW4v5-s$9c`%33L79{*QjhS%*;Gd&*GknQ(Qo?`v= z=-Q_^&sJFP&$X45e?=J>;r?3g8@X@fex;IT`@WKCdr4u;z)^BNE|7IaKi?hT2y)nd zeSEFdv1+cRWHx1_d~mL{q-ngolq2t>-fp7}R`%rTZTL^w#}?{rOy^K-Bde;sk2G$` zB0j(kuX1nuXWQq;wl48q&S~F&mWNmIk0Ad5zejH6AHfaTTZ8i zf8>ki3~;`0a>;F1Oe%T0I;({5rq~A5Xx8&;)b=mFC~K+tVRR`r?gg&b0mlay*h(aB z`>j{WSftzh=m3wRn-KeUSiVW~M#Fs5ltv!!QYG>gCBtUR!T$jolXiCby!smLc#Tpa zblas`gJQQjUXxQH|M?U6@iSu2|9{;-z3uc*Z##G*<9zG*eUN+Uhv3~m(-*-rKei2{ zFJA`F8>n{^2XSh)SpL%;E@!OVj1~I)k!!&NH@FtKq9I()zuj|)E3sG^sAZ3_{9o$R zz}sBl)=M3-wr%8WJr8H49>Ll6D;o8B8s}KHddBO~+cb{*fKEEAAFto2cX$E~Jb;c(>epcb50N%D%(0Z554$-1Mi-#BW#YHM zr(`00$P0UR%mh9SYr9^?j2#R_0492lzHxL2e^6KI!BCH`WPSzc1Ne ziO!FGTkcPT`);r9!)EyGc+Ev&@mV^GUQRE|zx6$sYLUKISZ^18wnp3EL$`JszYo#D ziQkN2Yc}lH(xx6e`Ip$kD`ieHMv{x~P0m}i9{M?5*Dpz&RLK!mgf5EMs1;)?i&A=46^@haj8<0oyJYe6<}e5iKBi4SP`LgCWJ%qii9Y^BqJ{b&DyM3v0j6TeIHovWpA zX??EJxrP`PeZaa4JB8?F|D85yQ~Z@X7z=6dQQCh@bd^(-N@?p$yg$Fc3k$J30NeOp zWjv-~%D*eVmuCkQy`G71z?UTW2E4a^Uul@!pppG1rO63ih`vq!VZiAr{`L0chbwEu zuZ;ZQ{?+VhQZLAxa*>j2L8-3E{^|5Bjqx9t@C(9L1Aa-I>a*k8maWIW?t4-_$a8!U z^4W7WuDesnWsL4rVzxk=x(>4ObNEf7D;NB!!X_a8Y_eb3h_Nd=Vu{tXePhv>Hdqzz zGZ&BT>000xJe57s8n&ziK0YG%)UbE#GR8&py*PXmBd;)6xS*$auE5VBzDp@wa+DC~ z4_FY>1^bm26dRt{u^i?p!M!|B%vkJ3Z;2~F!#cT_eAMiVBj+V@v7%Z1*t+EZ$cU>g zpD$eMRzrGjDUb74#f?`eQySgBDt14+sd)X9Zg3!bwckA5_8l{^)HsG`Dr+UC9`=AG z>)5|4{8H+YeyGT++ku;mhlVYJoO=awE+k%{#`hxM$=)LJEJfob#7M>$1Dg@HLE^8? zVhq$Nw)hMs`culu_`O%ao`84GEGv_LWZdyr_*IW>TmB{XKRM6l{5COCQnspTI$liS znbafo*^uE~@Eldgo78&}ekN@8AeVNdVBTx3(if&qB#QB@?>-$$ViOuJ4EcVV9tKTgA! z(DBjE}oP#|@8`qx&ZR6^x9! z#3$CcRzpKY7*-Z+cgZ(Iw1kZaLNev}p zD*GRDF0^Z`X$@SJeGUqH-n!Z6pzmo=s@eCTCWZclmz>`x*|#F^|0lfilW6{I>|uPd z&idcAgKx;tcQSr5zI}|P_?r6F(n=Z2slZzJr_gerNwGOB-i}R-z40uR{}HWAJ_7M0 zChr)2E-LHkp5ljSuRPcNhnxA=21|+f1K$n(-vjQC&A@(2JSL$V7q;OP{dhn8eAciY ze=;Tiq+5HUj!5&r9=M6X4kD6qEWl?Yh{&Jz< z^?Cmb;tLnV4`||lSE>2okNe-me@SjJ$w#5M0`^JDm%sN5=J_+~q~I^mmAr}06e*{kqe4~3iGN#Bdu?Ve}0O_yy9O6?+U=P z-0)7}NeX-8bsE8+UhrldzncZW-5ZKaWFHFt2_@*oJpaf(HfW<+@a-?>(Sgiug2P5z zgtr>^hE0|GPxSd0+BvgNVXcz#mr?4!+brd!-aE;mAUs3v{m84bH|y+wYVmOqzHaqK zrxDM>pc`$lG9189Q+QMWy7S};zp{p1x%e{PMjegt_WM(QIFh>~a5X--?6Gfe$HxI$ z31S-+zfSSR6u-{E_1L?4&KfBas8Eu7WFBYzBDgI6@4sX|*O1A2@c-5KXsR-YE75N# z^_8i6d|bIdrFfB5Qnpt=^`zdx!+2-3-OJuy@jv&c7cLB4=1rES6H7c}d$Y5*XSKk< zv0Lrfh(A>i?<~I3FtI)&)7(nrvVeMU5xxkQL-PgvWZz>YOAYb$(`kt@kV;eSbq z-lg*1$7v z1$NyN_7<_9t9d`~T(qFL>{r1&)KN~k{X2b0=a5VGT(O2q(W}%i zxlx917I|{&U+tsPX4ksA(1qVmd5b1%Ao!!ozF~M_6VG&>DrfG+m#hJKO#VHJYuPKI#;Z;k}M>c5}y=M=<-c%fZ8!!}}WLwOh zWaJHz5&eu=7HftRQ+`1}-YShr=$hORArz-L6xNMB?ql|AN)7*b_hLY5@g7DNK zCGr9Ndk_63@ezq-s_uLre4D6Kkh#Ii@sueP_2a92EB?{P&G+uYmt`bG-mK$%-=4PVUR~&M8&Q4xj#?G{+8$k7vH~p4IZK_Pl3xJgYnB zS!xdR+b1)J{e?NqVVWHL3v*b`WlHm##9F)|=vlkH4Zky|*pr<0Ms-S<9DfnFDt=@+ z9X|GH^jfpRs**6WRV6>^m3a2*-HF68>L@#|8qcZ^@VxF+wb{{5v~KRbS1#dS1w zZM4lo+wkw5(!zYF+akto3RZl|kI%waeSP`b2Jp#6{Q4ezue6i)NMiE3U8BTouqhV& zcD=DS;3n-?4OoWC94atgk?osfz+Lqja5m#EDer1OdUtm0c*mHo$gcb7ozECoDJSn1 zfAntX3*+M|R!T@ct#p8{xym&w24rXBHd@*Y(FI zv!`0q!V)K>R)dC0kTsBx;!}v}iGC{hN8}CSSS7d@cqfqE@Lvo6BeKOrUVpwGQ`Xb} zukj8I-f^T8-XVJ~4BpWR@3?Ow?}#tix%{HrQpdCN_yuyWH|X9Sf+y@4=LwtP2iRcY2~&vilGEW#l9L_&NbJ55 z;S0T1OZfjZZ?Hi7B7=`Y|K9bU-C_?xm-PP&`j>GL9-!0sKSBR1vag=NH$I|qwfk?- zzl=vJ9?Mx850Lxv<7oWu(T}0=oN*dQ9x!OUJpM5>&OW7ogvK@OFB&-}V1z-DMP*Kv zHHEbhd4s)zO~`2e33~+FSTibaC3m9Srmq#uX$NI4Zc2Tzpnd>8Zl(_+n}96 z_4B)Tz}v;=LkW0xZ|7e8qZNFNF6RA^2GvW(<{sL#nRrP9-M)xnFP}ACv7qxxab${XcEtTh@cjG27de znEbCr{H|H&jiT?9yrb+_I`km%>26cA!h_x3*zIa|_{jKw2l?k==71sQP5I}ge51Cf z{yCV7kH!vf?1=P@HV)E;LFUUNs{E5VZTvgwpR9?u`IM7`bCsCHZEV!#I5pxSUvH|< z)^IEJv}Kc{k-AoNE3p+1dgm<0C+dq|RrEaUGdi!rS8;}YMX#c_#knEXj@Ad2SZgk2 zFBmTyk+QX^vftpE{+})T7(QjpM}kW154Yei$MeJM@zuS@8~Ydh-~Mn5&u{m}zKU<$AMfFL*ZA|> z`3HLxti-vl&)ztYb%l~kEZ@A@=-jh%x)0%3y*11A$e~hjL1S*RsKj}yFBe%iU*6B= zeQ!f~IGbn~;{pcUe-q?j|TI>&*a#mt#9DlIMwJG+8DRMT){!k)k zHTH)Y-q;`KrTn8V?B;p7H}-wneo?n6_QyrWbH1BpJf|OZay`R-(U3Xz$ED(9b&-9B z&y24!crav&9cxPYUzPbxu@%6rY)FkAy(#6J<@BjBA8>LG0n2MrFfa81%gJ2RzQYA_ zR%3@9ayG{f*Knp?M;Cfy8^yP)TZtXJBvrquTaC3+mqJ?)1AiyiDs>(C3}yJQ!avBN zGX7kR9l61HPW_Ba>U&e{NQ?2DdKjbBb8}3ge`m~T5sCjJd`k3(jx20@*to4}vaj5# z=P&iJ_JY3zpOLkfF0U#bqtA60dvqC0nST@=t!GEe+VUeUYsoWV^Bi%km9+O8m>P(&OpsaORFFyPN z>!LlZN8d4LL{v{|AGy>Qx|;kCrj-2@ev7ULog?~!_}02kKkK>pHqP@nhdEDCqHlk_ zuCt5vu`e?5P;PE2<`V1mB`qJCJN$Fet*B~; zi}UE$q^u=a3*6e#$tSkdbq26sCCaa<4zOQW>Iq=ua(q?k*vL12>~#9RL!O0dRcslB z71D=R$=iVaOV*4d<8x0t`g?(K>q2yl{y-IB$p~YwESutYSGCh_`JQzrbgl*2le+Ak zeQC@$#9w`zHt+F83r{M!eY%aJF!%)J`c`DKj-0x)5Syi$dIx}|+@HRuuJcS@TE{-V zIRb1&rq`D+-D zo}0v0Qy8qH%(q)ar;+MoYZ>~v@%~BP*PtWSN3qk2E>Ut6i;qBwb8-K-h`V}vhPnUU zm1<=8e&%-k4~E$X6h{}(xk!ne!Z#=dmz2(Y2){YQ7TpRy_U!Vltw*O7w{`8hD~SD1 zXeOF@atHi9KF=35;D*sO|Lq%;=+R=aF-#Mkln$%6`NsbM@vXjKKA9*EH81Rzed`ia zB&9Fo-4aDDXwu;dohR52)NMBBKE+lY|2pRa&RaN_aQ+r&2j?eK-**ES zzfEuo9j6VN`N{du(UbB#i5@2Y1Imt=qNC7COLkhve#&al#{(TwB2*uM@pDiOgI8Mo4n7mUU6MRA!O1Bndi zyUsB%ivE~5t2WO@$H4IlZ*}=b`@r!^Z*?&Dg1jI;jpb(UYX_^#>o{M@`+b}*^Hxh9 ztr5jlIeTBrz-Dz?#q52Kfh_Wo&8F^hY&>&#{tSJe!}HBNmt1ADXI<%TkZb-GAP-am zzVGHck2<}=!*@Y+$?o*&6>hFCXYX_3YWDa-uSWzP(6GdA)u3T1<5nl@c`Q@c#2cmz zxp!&l~hSTp=1bEB~b?99egd<6q84q%|vWk>FMgnf7$3&xDS zt>O=a?@Y(=jo)1E&r_oQ%kh8N@J*|7GACF5E4V1{SNaVATey7VLv`LIDMXb5I?7uck zEI3W}CE9}C9re1O4QrR&cDph@Kbtzlh9Mrd&;u%V{#x;KJdGAb8s;6dot4~o*|BkWIvJ3Mp$fw|d#}7ZHzUnNY zF^QF1guE>FOX`)J#ga2#zn|Tx`@ahxit{~jIjd!S+8L)FyOOt!*s3RxPlUFQK-+!9 zsHnFp^ZO=E&+Eev>IUkU@AlN1Iuf(C74Lb(q{kQ%|3gD2bWiPFzQ<(h@R%PfZZP*2 zi`}{2=3Q6)+@|8?Y_a80!X+K@SmefoO6(0hK*BxQ+)PnEO-I4!GY zuj>W!oPKD;B-le7kQvk=VH?{ghL+EV3E=LeXEn%@=nUe86)9!lK-Slo)xE_oi?RMh<~1|$1K2i?KpAT*R%h)%dDPMx%Lxp<@vhL z45+WnCofWQh2ZNG;FFA@zP|xmQ@{B$I#2aOUxHV=H-2X9_;L0sGcSbsm&A(zA1eIN zjr2#x_SCPo6&Hw%I@6mhZc`#J0;|F1kLFYFM*GVB+v_-3PQ&QgitT%V~#_pk7FN*OnGx~bDm zoejtdHPpLOco_Zx%46PjW$I1qj?r%MX{+ab{bXtX^osh)saRMoJoCRmOb+H+|Fhoe zckxHpZk-P96N83%z258?_zdfnpWw$Uv?e<2TJTnT3VWe%VfYDXQypJh2^?ERww$Kq z)>FpMSZM6Ch-dWJ3O>y<{oj-Ie~Yc{9%6riw|YLaM%q{pEPBk|=xginJ7Dfy&iuTM z|2;*10avCyPkiRmiWaZi0iNo7tg8zf1udTP;=cFQ>q9 z8hFP!m${`B+}lq7=H8dKltodsjepE7b`X<>91nbx^_HVb`c*?t62Vm)_acv3IZIxv z9Q;%-!T0*N{9AbGt!2VXvx80K7nFHgzLoiV&p!2_vDff##mt3ICE=O6zObLTWBt9G zbiZL)*G^pjPK+UU*6(>=x*iY7u!Emr9p=?i@}I=xU?m$d=3RkxD|0S+S$Fj_=LVQ_ zdmkWAHuHCHg|}1Yt3Vmow_z`pYv$YD_VH`xpWaQZ^RaE06OTWbYqNE+er-YqU&Xva zFnxVqVe^`vo3dvebNCZ!_`ET7b$3iyKepm0C-Seco)j7QGGxU{a58?( zHz4akp;_6(q|3!KY6o<=cxCN?$i&DE3!0D>y5PG{GxqeixrXP0n<9^0PF<`mr{DzJ zeBy`R>eRV&RhL5Yxi=>A8TmU;bT{tYM$b-DakwE}ku`KR@dK8Yo82~< zt0Z;;Yt3p+=1^#_KAUUi+xlFkdU*kQM{|0I=yyN1J)Ko!^fRKjN&3ioTE_A&;%Rk) z3r_rIjXn)#6zS{D&b(0cg$!(S0w4Id4jbf@Z(io@e34j(#yVY(H$(mnOW^LRny)Gy zA_rp2JNQlfHs%>Lh#mfK(cZAc{9qqjf_-fGlx?->u~@#ig}DL$z-fA}C1am}__*F> zRg;CRx1#VVa(q<$?g^#iwO!vX-mCjNd=#5fXw5=Dcd}M)p=~R{CFH+cnGfNS3;w;` zRi&>}$YUV-mPemJz9!B!iKwdHMNiO09MjprbPxQ=?@7@@kp4-XLFixIldd_e`F8dbFHqtcS_yrU;=5wI_CU*xmg#v1n7j4%Y*0FG6CpTkXG?dn;$;^>GLE7JxNq&}eYdCCDBbzV4=AIGC`!oFOcK+*7CkGDzx0;h?UADUc zJo};QTDT2(h=l;!X^U^ci|1kH#<##ZLOx|mP_bB8<*ZTeEq z^W^zoCd@Np*D-ix>(r0dEehAdS49?PjkI%wm}Ig};aT!mdx-_IM2UR5eP{Ds(1Xk& zF7(yn6QjdAR|}dYuYt%;z(cjlT$0iY9w{O{i#OOQ%pB+Yrvfu9Q zbon%og|ZFkdR>fVpSgLUzRoewXI?U3%sV3Y_0=sI5IL@IBWGl|;nna{<_M7^TadZ- z-{-A%iLdzGQYjM5uYGpXm`nSLHJjv&{*1|0`CDkrsPlK!sZD1samq|At+b`Y+{x1}nqH!XWG_kT zAFY{6_4#!2EA`UK85{o+n=xXAN7I)SwIhBc7+|R^!)QN17ZJsAFhON%-W-HeX zYA?2*X%#lLWOXCg?x{BR;7w~TS8eEJ@_806c3q@-M28W$4E_Ce`FSl0>9=%`x1dkW}%irShfzK)P zUGQA#XFKz;>;-L?`GT`%vDn=3Y4Jmz{aI`l(1HB_eehgpA}+A;gxC|Hh3~d$;WJ(K z{xe+{a7^bY={NZQ>3tb`Ug#d;01u;Y68>8hgg_*)z7yl+)3-OrA3r zphJ=O&%<*B@AYStmuJ$J5U^n_w&Z!{2gymReZc-H$+xWY>cZ3Z(ah6(cv*YP#=)x*U(m21nq$&@akK$k6ydFMDe14SQ3{R#ZZVCTtSWR3>Fw*$bT33z0Y z6Fpp{us7dV-Gn?M_QFm3!o`~|P|!=D_Z~8z+<`nf%(_jhW6u@qIxSGLRKo@{%(_my zfoJI1dl*a0bJtY6(b-$Dx5!wg?(O6E>^0*(`?V@G-dku7ZE8Ny?5(z9mpO1F=RKSo zIb)wWa6M=2GY3qTaMO`%s%33h$~b0aTEgK!nmZf+cun;tl4Xe;B6AV;-HxYdr-uFJ zZs4;06W|~)82+-@mer17kz*KR2X&*zuW(_r(rV1?Jwz^9f$a}i?H}a~jFAPaEi3<< zume6i>^u`-w|uZ#yM}si9;~)Bai-rEV7Z@uTb6PL-j>gB2F7mMXt{}h|JGZbz=vTX zPwS=+3|TYu zYptb$eKpAIjK}^a^vJ=$TKr0KtwHx%EAQOc0tL<@>z6aP7R<9nhMFZOKuUHQZvGkY zO!;uf(T9j!9A}-OEo_pU&w9PR%g5^lcN*24RNcIvShtP3hu`v6GcNNj=znxvLZ;#0 zOEm0TVs9Rg?XxGeEc-V z&mrSS|30AHa0TTr<_s>y*;6rmr8gS4at3dxr*eOVH=4j^u^&BTf_Zm8^(D}~?62kA z%=v20H*yBQ67b~x|G{~h$aYl=p~XDmcYx>3?*00A z)5fn$7mgw`ikvPsz0v=Ny?24jy1f7YuNyFLzym5ODhZkusFWENns?l&ZK%`?tyyV7 zYJrePEKn=7)=;dpTv5SVVm{zQ{Ry^d5TKLv<@XhV-kU+fQTc?0|{F zMAoPsWurF|hL4+%cRP99Ok~^)A1_PJ3AU_TJgQW4rNifNpLk3KYp}hMJ-t4o zHYJ%@_j-zs6GKcL@1~Dn?@irJ zSr=9M;p2(EK8&Xs7dD~S>0P+Q8NU=pvaz+hD5L4@OHxbD_V=s!^tRXhS?QJg83Qh) z?KtU^cG8K+`Axi)<>#EWAGx=Xb(QMbsTrT4XJ>7t)n5hgH%itu=ytUBQtke}kn_Y| zT&;ePe_Q?V`{%v{$B*1UNB8tPVXItuz6yE1dU&w(6XsY-y9VB$a-J#uxkbJz3=;@qJy(A68+{3LhIY_z&V$7hCnon6}f=LJh!-AGS)XgnSo z(F}cusSn8~s>>$UUL`xN=M6m7vt;(qznxX{cl6hi<;}|%RW4t=xYU#3y}6ELqJF-9 zvEp0sur-bh5AQm1l(xAfd*lx4;P8+!b%T-3q!YLuK06RzE}5w5TjR2 z>YLw+gY)xc@6)!6XzRL1CmUTp_uivtifonh#?n8+?rQ*&>Iha?yj))rt@95v);68 z0B4#A+eAKYkLXzxRNW6S7f6S%bjlfz9Hbr9r`xejI!MJ|^S5B_3g$W0j1Lve%QiBO zuVkEfvU{+!l5rq5$)vyE-=tR!51wd@Ef1ItapyL6EDw|~UpD%=XM&{4ziW)G5A+<} zrOOrc?FZoL-u$w$uj8sJa=8<>E1w;;Bha5(Eb!$4qme+dr%2dFIq$8Wi`De{jOCvaU8zVX2S;PNA7|r_q1Mmrz zQ$qyhvc2y~WtWT&R&Mmox;Jod7}KwI#jDH(*ponijwz&F@cwgm+56+_M>Z@6pOP9HA2 zD%Oub$&{={UeWJ1U4$IGlDm#v9hK%XUcZ+fa79W@ZcVDyU*(6nd22q&tfL}Z4VQi` z{9Kf$LlLi3y5iH`cwpP7Sra{-y(8R#_dYsz-E|&4UHSj&cjOdT;bUV{wfCif`pJg( z6bv+VOyi!nmh7DYZod|zJQX}KE|u{#SLfSf zZlXW(&V`eYfu<$M``}t@h-Tgt)#cD?nP4>_CvK69p5kOf}hoqN_l)~s6Jd5v_Mn!o?6GT#`eAC=zT zv*Y2{)tR@4TW6Nl9v{7p`xTfYhqsRcWd7*N>ee=x5!{Kdc&Y!~zQ`zs7++l30 z-jvZB%YNc+xYGZK>EmnZeLC-uQkH`ws>JsO*Dy90#z<}gy9DcMkY9zVec%PihtX*f zb@1F*7Y>YAlec)$R+WLbj;nc59`EIy>aC~nwhukAIs+~p(Dl%+GEw`m{ot$D?QEa2 zd|UOQaaL=x-&-EF<`%|xuW$ONC9q#-siU9p(`K7yUy#8(Y`DhVXVF!?J;pe?rnSpE ztw9JM!M#?j^+%3$@-;kaO|SmX=X$)rKROOsv{%t~m9arC<&H4=Aitx!70ez{x|aB) zH{TW!^-;dY^6R!&w|@sDoIiN&!h1)ttz2|2{*Jl{1GG*TbA-8>%BA~A>M@qH@dfM= zxtX&z(#>!#??T46x)`mEu3WhQ|3&&8Q@L`%pl%Zu=c9AgJK2MK25V!nFT#)36|0Cd z)7R^W&WT6Uf7M2MqjTXs`6J6&r+YA_CO4yc<$^N8{QlP!3y#MG%bI9s+B2@T*K)>T z^-s0ugMB4iSvhIZX{LpI#3yl2hsvp`FR~bVI!AUd>)O45HpS}&-9BTDL}`shuNmI| zzUuCn_T{Gip$E@Uy7q3jqqT+mgsShdbvm zJvT~^9FMHOjlH5@S4Wwg&6q&E2P1j6g*^og@D%ok%&%6RL>cz|o6EC^M|;xYv#+Ks z4ZaprKfqagJ)*K@j#NXKoWi0E<|}(2{SGo4<=w*njo$)B^+1aEQTQE37^(+2Gnyd>O=AiU*_BDj_))e+QNH>|H_cfq-1?A6u z1S84E@EF!}SD+iQ-~HY1IQKir{Z8N>FSV_H(zT3CjYBW!2a$PLry7~czKQ5KkUfgg z@#x&5%t&O8bjF(8)I|2zaF%8W>uVD^6Eozaw=*XCOj)e@A%>hLh*W=d8{rMF(+Lf`&ex;4%?HgT^& zB0O(hq*?PZ{LbSE+y^p0_DnMceMifZShMCha~m3SeC8z9;<_+@*=M@>*h47!A`5%} zoV}yEtRmDtY>PS$NxoSw`lwhCVULx&&O~0 zcM9JH@3P;Jb-+gaOD|kc|4V9#blxcoPp412bPxAqZ5_Mr?PzT8udmX?Pk6c`Wfw-5 z=*W*`?>hRJM%qoL@y(~-PHANBsD3_}@F|I|{tG%YP2_ySOi3x}KiTi|UoN_7|K0WW zk1e~?hyM+ED6`5pzlnHKPDGqk4)1qN9IkhTG8C3eW#w_Fp}q^r9l?zY9;w zOo^Od@uAjuG>@RoW(}zHeKa{k`;WGguYBUjW8a3#hCP1q`mS=n>2L8$BRu}u#DCi< z>{nvXxZ{NP_BNGy-|oC|(J8`hB;4#%*z? zAe~8WI$FQT<{q8!e8tcovQI(BVC=_WuX0It%Z0h>Ka|S^{AHZNekbYD@NBt2zsmXi zQ}~-r_!QS)rrtMuhw-GV^?&v${J&4U@PvP$V<&szdY!_4Bk`-9Dj$vR{6V~;eL3yK zpLEFW?cc|K@G07<@}n_m3470`{3$d7eIDlsf-OrT{gubHK976-U8dQ2gE%6-Xvkaa zqxvW7?I~Y`LdBS+m~p&swhG*U*^1eXIe4aM{W*TNGW-UhVqHV?KZL~uey^qHD z7#fNhhna>c#@vZ%KNg4I8>4YqvRNbJuQ%T+=gy~ud!NoNeR|b`L~tE=9QU{UPv$Q6 zuUPO0e`RhT`kB`HJ(*ZMo_z?;9IcWz=jgkAJzLkPo1&2|&{gS8y~3!33niCyf**y? z)wVM~@a9_q>W20FA|Je@${ly5+ic{`dIoRSs(Yfxh5x1Uek}ZoaV%P9uouksfdUIas!}YDZ;J3y2iyj-kqOYf~ zy@mNO6Sny1fc9|obI#e<_ceRR&}Wb-UR66dsPc4W7e|irSskeOV`??DG}yVRen;%wb>;6Izblfril--G$q zSo>8nLl43)j6m0Y<&+w~ujj7Aw+Ekzm#n-o=-kWrCiUCI-NydTN!=es-$qGgI-FUtW@n503q7IV2<8#iWB`re^puQweg~y+9iu7nl@eQOSnQaH@B;Y6fTk=rF zY3x-~yK5KU=u^bEGKO`?EaW-83z}uu@Uyo^S{c!mk1it3Z1!<+|MKOUcQ?Tc#z!pIdVq|a$ySlVpJAd`_y+eYZ#|0n@Ywb_CfZRp9=QFgop9F-|fruNy2P$!>H^O zCcJEq@Rq~|-2cIzdBzX1Z>?{}xm|8NG(sny``mB6S*q~mU4kQ*bw{SB|L$OYFgnP& zuuGY9P)DgtYB=lIr!pB?E4k zesd<@IqN{3r-#SEzJEt<3AdBnBL1#^t9l4`J4~AAwYOt0`OtQDskBAO3*lkMV>hs! z-C_1m>Re2?ze3Vr{&BJ$@+thtzR{|^jep_XNW1>>e%GYo>6B}DTsx2#)HcHH4r2$O zIH?Vb4=TT$>%4qzFSF+Uzl277)gE#2kvkdp*J5fh+_@h*ijf>J2$PPHypVn(6q*FS zgqi7@{ov8CZ`rd(=D15f&^Pz&xB4H=?@5>vOa(@I@uZL9=0`HG@*Dc($Z?#b=s$d8 z;l|vJg;rm2ls2;xp0p93r1|Y`eee8H?#>Bf=A97eiZ|Jh;TXm45%8-#tzQ&HV#M{mg87=5R+=2nopA-8(RoeKu} zvKMPyNVzGh`-Ipha#yaj`_0u>Q*KI_Oe2dI{Z8G|-&d}y%AI}JYA23-`JvBiJTGWm z#-3b%%xpipnA7fZ+_x)U+y|%mCr@Oo^ry!5qraqw=T+~$a9`eV?Kh-v)t#X{sNAk% zpA+*L=9WDeFXmSw$4IY>z92XDS?5gW$Vaum2$`q&qw6wOan`MP?{%fTu`{^!9A^L> z1A3{Aq$yp6KfmLe81C@7?hBodpx?qTGtp^j?|c(9q>z5oE&W^XA^p00v_IAyov}xE zg1YnbR|{^t?f!)A=W{2S&gARfeye|}T6|%11M<+?hy>?uvXJ)E{hRtSM>pWen!b(5 zn=R4-sy{U9e$jh^Wzs2COYS6}(iO1g;Jm5s$(PbwRiV#P80lYRp8_BIOzUq8f~7UN z!P40`YhQBI{209faC$=b2?NFt=H9^JMZVP79?Mqt9l^PwZR}qZzskODEbHw(Vk=nx z>sgjjsx^-q-U!wHma4P-j!dL-IUj!C6QgxK`58|*ji<@$uUY&)bqcMoHr>{<-$P?l zDz*3cHSKeNM&rx4Fb`QmcJ4k11F78M0 zqUfh1bQheLuF5_6r`Ig5WDh!L71ul(*|TUpd*rn~`5CgVk3GVY8};78yRIy$u-YT+ zt+8aY-kyZqs&&X~SgX@HnU5opk*EWmd8uSgC|tkyb@Jp_$#t#g#O{c4<`$k@y#8_D z-gg*(JvpcPj;m^S-1S86_?_yr(M4}HROenjSn}}Iiw*r^JhJ+ZCMzqiKg&$1iM+aY zXF+xD;1tVucH&>Zr8ixVeyIAzt7`q6X{>&+Ppu~xeZoDnTVC|-okm;-i0hWqHsoHo zqGCZAIP&gQ3!XdT+l&4s{vG&?=<@DnPfF%oUKVLWVD$3 zi=w(+wRk=4fW29)Bb#S653upr{rmau-LhW!Yfq8liRRpdc;h?BWrlZvoi;FvHK0V^ zl6ZG&sXxw?RnOqutU-oO;f?1ZS}(Kx@h#d~VE>`HS zeSN@Qw&;7F${qjo-H!WF_9e-Eh3oEPzi17#=#BKp6L1^DJLl2n+4YpyJG50VJ>_*r z6MMpU*mSab+p<->yVoIJE=wvB+r7hQ$_f#(@2b!PlOj zVdJb|-)?zUT4nSA^x^0qn`W3AbSN!8c*p?m?RowV-`R!I4g7|u z#&$*@_~`gF?H}r{_(fYPYp3Y#V^er@BbB=$M8gdFo%BHA<$siRP}6BcZsDeTobvWD zhE`F&NpX}fZ`l{-viF!f)Kvy*2ML|cmd9|ns!X&dY_e81zZ&**LIRNrmSP`5|k zMV2kiH7(bWrs}lNty8`8lIGfZ^}LC`Bf3_&?P5FpuHZ7-=U3FN_}O~mSK5aBi$13= zFVkHKX3MB{X)@QEGX9>Ya|?&sw`TI$yHmisK8eQq zX!I51H(9!T&{^<}U`vB9jINua=NC?7-WyKWH;nG#4@=YUj7?5mu#T?1Ykt;xd(yrN zBFHCx3)tti4P684PY&PF@5Atjze7Xmm8Rt*K;dKT6Q}1b}e_Ro^GCvhmYAXRu52>=)Cpd>@U%N#Aka%?0x8*O}P)< zvueRFfApi=U;gMj3z{QueFlDE^`ERodHth}x7qZ?+XnO%-QRZkW$#*@zrO>1@F{x@ zmv%E-K3kGFd}HL)TCWc;4eE!)}m2bT|Cb!K@9TpGl=`9=+Vm?~E+6guI2$ zGUw${9vQx1OLx9?H^3eAhll}2=lw4~+|{lF_&->B-(lvj89x6m-g;miP(0Y}3!)GI zNfT2t^bYv?$r13S#4x_}?b@WEnZJT^SV3DfzVVCmW0kKf-F)?`O}d0T29rqU@FK=fdmnr~=fK;S?>O?2cP;vn;02Y^o6(0`d5qdF zcH9ZxE4F}meObJZ104}rZG79IE0Vo;*r}c~$ERdeLl^6P!^OYbrx#S;z@PCYREE$A z(2l1>_eSqBzL0e#^HB_SG67w;S2y|HRz4il)pYZZpPeE4n$9*gk~NS=*`Hc}bq(~y z#51q&%o`NE{q6WUMIPGIaSJpwBKs+i@Wskr$ep1HT9>``nQGdI)($sO*ODtfL-xpm zZpPpE!!JLbyW#^o_H?2zs-9|Suga_Q`>9oq?n_~`mQn~$Nxj?pAAtWF>VGuv0nnzM zxN6+E{Z)U z8I>b1Zn-yV?>p>A3h%?uPd1E!lWMhp@UXuscg0{U_xLEU@{8H`8OgcTu(R0ZtkZg9 z*g&7vEmkp4s3PugePhqj=%im9u`4{SJY>tNu=UDZT#W!4d9M|{JSa^czQ|6bj7>Qy?JCliJd{n@R^4W08)rO0zNvQh zVW^L{qk(Z->8bo0d820i*bek{o#C~1&yUquKdHIKf8^EFriQ=ORBZfPs( zJqGDI;3bqT`uGHN&|AUXm}gh!?UYK?qm$$rk+V%+UOLEW19Uc-a)7Tf}++4Chxql4j=6HW3Hj=${2dO8mqj>vU z^7@+=bd_5Q=vV3=T63zPEE_1xaQ=qQJUy>J<6JM&C;t@@UAh;NS9C&ym9I$379KX7 zI|@1b<*hNZr|)6j{2R60;qwZoHseoO&YdS#58xlx_S@6v?;E3YQC6;d{V~yN*z02X zh%vt5>;-i696|QJHC!94t6#1*jcf(&+UFEqx~RF3bqMX*+D6;cem;#!+D}^zpYZWc zkZ9p-UyH)`*gv9KXU6lXKlS5=Yuolre><#wWYagvTU{=8sweblvD=88gHEd*vWGrG)ZN zCtu|Q?HWos-$CM5IM3hh)F=D;TJl_b$(DJPkN2%Ukat(xH|-=oZ)MxJv*!DNmErvz zuVVxi8pqocPPHx9z_in!{5zsJU(QRiQ`ze(k80O2~nSp}tW9oeDVHC|@6~DLt zN3x{SI?h|Bl1)54N}K+}ws*-5Jvq}axxnGo#(yMgMey@{#>A8pd{i<=|RO6Gk|FDF5T|}MUOkK7_#t;9Tw>P~uSI}!r-E7)rVVA6y9NuY) z@pYOwk-NTzoUyC#by>mrv(J0DZxQv&o$C{Ik5n}Ic{FSA5zWVQ(5=8vCl>UI(6~}r z*oC(X8IPl*cRif4KK7Bq7g8zj-U)H{=X&TO<^1=eM{1Ene%D(Jccb7)QM~)NDCYZrwe^Hu#>ZKR6+A1=#_j}up}w{~nA9UgR2pH`pK-a1c4 zQ9OP-UVdTx`J4|Z`(gD;Q}fFOizsc1Yr9EYad#ArD&*Dj~JOeo^eEs|T-1pIR zQPS`bV_Fupe7`T}R~Z|ddYH0`({StUU>$26bxn)=clYEE&hM1ze(Dzq6Y9d3Bi(QVv0r!}(b<(zH5wO2nA{idU{Q(Z4a7gT*)uYSF->peDD z_Zhs?$KAH-E8e-(CUiz>x8j|KwS;_RpBEzRJSLId@dVTF^G+)JpFAm{^!v%USZh?4N!% z8n;i}bwQomnh5=}(_T}p`zbxj##wjU$?u}s+?&chYek%O)wD+eX%+dU0Mw zWu|x~cQPNLZ`rX<^{;XiZ#dO_C+|*2Rym1}X$?}coA_4&=)a1&4)X8&zxyt{B&H~N zdwE|^?$BBj{#wI_#!6RW<+H}~gDt1Ja~R&SkvAS*Yot$DeM7V}E_=My>p$`*nT&V6 z9e<)HDa!n`vEx_Y@vn7L^^cyB=GnaA(7qbpLf<&Zy}!;nc0753$E2>0=%#sxzjt}= z0QTA{ZjCS1tjqb!lDb#Z=NF;xE+CF-c+8^V%wcEarup`4_ze4Q6-Hyt{a5;Gw&dc@ zc}4NQe9FJz>Y#J?k@!Ed(;DA;JD*S(KV?|~&x*#4w!9`~k=1kQd_fAbY6Ja%0j(v9 za!p@kocCF|m-JQf%YTJ`x32Rc`)Mrdl|Wstusl;`v)(DwHn|Udk<-5>qU+E)Z&`P} zrC8ow>!KcyPF|8xi_V~^_vY{S)!O8u2=dB0r`DUXpI?NW*oUyC5fN(^M?|8Jk8<8P zU&8&Z2WkIaJbuoO_?L{VJ?QKsZ=>M~?6wh)_9%W&=SSGXY0AoKHFjJ1-1@clBWopJ z41wMT=7M^kd?)K9+c*zYjxJI2trOg_5+06pFRzF+s-N>j>kfs3SH$o;dr29(Uiv8S zhOa}P?VZDmC2vdaU@bqgcM*4It99@)Z0)>(Dw+L)qjm zrd*d&J_X(F`|q^x;r#}@(Kma^&uc4|6x8mrbLC zBzc9;R9&+e{qhvmgZyhRg6PtkbcnOVmF&AdO!>}p2;RC-#6x=+v{9Hu;K7N<1R5AE9^>{r!1z(;u@ zpRS(4Jn0?u-<}+*@HLAISS#$cEA@*pug&Hyyzw1;>c`9>5}Z3xWT|tL)n)?jGE_79DimWPf+JyZd&H zySMKu^8ctWu4or+Wk^{{?WGu7CcTR$x_9Yqi?lkrQ;i$L*prljK^GFr#=zI4<7yoT z!sW?UeuP{p{w$vP^Oa*-v_HZRzvJA0i~oD$TaX`H9ze&+_yNDL?H+#r(LvV7t55q* zosV~qJwBp1s=Hj`l)JxM{nZ~M(;?qX^uoah>f{bjZ&BUIkLUg=YtZ7u<)UK9&7Clygr@zskgA=xVkH9htZ1fYEYU7rrF`jbKk=-0ko~fwE^*|X zC*gN$V~2-#Uh_VEbRusk6-VD$cPV{vPUk!7zEw7-b`@>wp2c%&hm{r7t{Q2&zaqmt z^+R9hiJc=lPkb91U%BF*t6#pgbHArL|E}*-Kf3$sO}KR8HJC+ky@Neful=rRob)C4~^>c20`PFZC zh$}khnS1;0Cf-fNBO339uBV{o?!`lEi=cJY;v$E>Rf~tzP9%S7zr4rY?NRmtOeEjx zU*5R+&-Be|uLIFXrdEt;@egZjmobc;{<7K4{x7mC{a<9gHo>rWJ!@>;O`NYCN}7)% zL#RwOH`E@obK;`be8~Rek0Lv7WFO}0xCrhHFZ)UDrKS0`8=(DB)46B>bDx_iyTQ@E z$_bZ@tvhY!d6jwl^S1uX*R5#QmG@tbyf<-Xm+gJOyVTc@jy3=Il-HdZ|s(Jg9 zw{~RA37ME8grg~^k!Id)Nj+%K!+&JrC%(tqS-&wIV&68tqK|pQ{5Wqd{RaEg0F&hSBGw~gFyy+(DWyd0rC#kZ8t zZlLliJ;O%Y>XY1!Gaf^KaMnF1M8}dw;npmlmqzMVkGG3oO0O#UQR510pyB~_sbDH- ze9;rXYP^vwlOS2fy?a5jO!yct`AxFSL1!)6$_wg;H*=OU+)jFsThMPDWIe#+Cwbhz z6do7)>66BEzsC82R!(ZznDu!RhWC{h53%ybtKne_VtQ7ZGm$l@JN0Eh^A|@(q3=pJ zTrkke=|z;c$~1h8*6&mCTTdpoxQQ`>%x;2R^J9)tbXU|Hz@i%*yYMfmiN z19N`g?+0A#XI-MY-57ItXL4ognVjK=S6{%LGXT_VD#;UBA#gBnVG$Vs0z`iTI59G;OD?Fj zXP$Z&?Lw9+2<6=``R=gJrEFjEFm0pziX|zvO^nOcjG3GluiL`fwe}A^M;ltP_~xym zy?0q@b2V~*LbqUDHS~_)ogzOvtMbK*x3J4(HnhTJI4*|-z6@&e?PuI zf2*K27)ieht5@Tu`!;WhJPD7Bh>Gf>zIYg3v+VRum!0vQ;EA#O9`7>Xz!~TG8Iz@( zR~v7l9V4eB_nP7IH*iqY9JxuyamV7at&tgL^dG=Gn~}U1n};@PjDKMN2uw0{q51oZ zBa{2f?s|+#IS0Sg5hkd&4)u0ReSZIB+KI`azWhb@ZWi*Lzj(=3AO7+eU$j*+o8Ay% zoe9~mZ&5OI-5!}xq&L|rxsO!iliG;Jx^3t)KD=mq@dxK`FaB5FZxByBnOE~ZI{F9k zPSIcDt_`h4zs&ehr?n!D0oCr>D{0;r&Qty6%s+=R=kq=Kuy|~Wsmg6KDY&-8A31V>7cW@tF_uqA6Y0@=`b+F7m%*@-mE|t$-B(u@q^JHLKo{Mb<1KJ z9v02PC^G_Cd-z!jgM9_|O(9=Rh&%5J;nypOJF4@JhYxY5u+|EjI1_?CxGwK3?h2U9 zn$-->*uSzVH^1{e3lv{HYdMFw`%ZCk53%EK#$&!UH(bnq0qA?@e6!}yW3B!uPkI1! zT1}uwqvB9LnmEhqr~EWFY?Gb?d7{1kNMohtcM%&ihuOD3&LBVjWau8cDYx(*cRwg? zPjyXwQ0Hy?*mWMIkMhLap7iR>Ao9c<^j&Dox@=SKvUAwmhW~Q%B>6jA`cvN-t-Ma{ z5?#KtZmqgjyV4vmJdGOaBbxc-*X6B`IT$SCw%ksCilclIgcs`^nwgsCg1yuU{| z-pP1(S6EqUzxkitxl|r>R^Zlz>?3-c&}TQmS5^=P{bXeYI~rmne+f|GM<{ z%oDd?bcr$bx_*XlI(&O6&Rje$kl4 z<81jE5UkS=i<#q3g?IZts_=m%ZBjer^S)-H(*FWB`3i1zsR|ON&#!dPA zfasv}>DdSG{fBSjyVd1L2dGIaS2M;dZV%@#)9-54?VgB*j_Ps3eo?z~F z6SR0t;p=~vw#!W?L*>h#=f6+znycbwJ^1%^t?mhT<@0~jsnbm;3Od0}x$AzN{e~`; z1?Cr)u0F26jIj?tq`w`RBY%+l*f-u@_7CxX?~SvXV$bPzu?_c-OUFDXeEAjiHlF&o zf>$_ypJZBmJ=4qocgMXqA>rFkWX@WcmXW)?KGS|b=YH?W{BY#wUyeEFH`^?}vF#5t zue~m*(_h{2Ehp1MxfuO<!$;x7JuXa96$421cCZ&kF~BxqQg1Z}$8w^YCYn zeHnRwz=^*#A2#0P?;P?2L&-c-P*O5);V1`2nQvY)#ayv))`GOG8)wZa zG1r%s%vu;Yb7q>!&7X7QEHi#aS=yzuO7h3$m*k^u$(}N0(xe4*OUvx9xeH31AD7I@ zzrJ{uDV#TVW?FIK^$YSBl#McHE=)dip}BePg6j(xn$Be8vbo6%=PsHv(~QZQJo((= z=cMChUh$$E3+I?|vu?;=R9s@NoLe}9c&03xGx^d z`1(aR8L}~p2QlUro3V3mx=9)S=Bzmjuv(Bmqli=%&M;GE-8645&hyF^6y8`+VzLy_ zjceSjg)44<9zn6wjTJuc$_uLQ452O1W@O$tW{p?i{jKl2$xx z&W$AnZaq5IijHkyP%kOVtreo${mSG;iJcZ$IZYNI>l4V^W8RmA( zM$BH!F${MpnSPivF=u0vFYuE5N~XyUMoc#1J0;=c=HFzDOOPH5?inGTKj zL3bTas;fpC$=hFqLa&|(h3aS!YiSTOX%K^H41b{^JVZkncRUn2OhfoChe`&}7=HfO zP$-AS@b-~VXyN;zQ1szY=<)YLp|LcI!-oh%!B^y+Ag zQ=#KrXbM8#3TTam_TP|~Uy#4Qkmm`M)ghSpvncd_!6wMR^)qJL0AoHo%b0CL5d?=D zvkxhw9~}R?ml)G4hx*Q?j;}K2<~(B-+-S_QIh6Av%6BPcdk3R-CG~nAQV@+}f0Z#` z{@9qFKcNnvV~jvb`u&T>+`W@J*=x+oH!1%=8uQ0@jd}jCF@+x*bAZOw<8#K95O$G1 zlZHZS3Y$aEjq@4ya+?#qeCBW;pSdH^XMW4Yx?7TcW;_=z-*tx16b$m2W0?MD`V6w+ zwiiF~W2&FuFfZ`@w0mFp)ek>B`&a#cT(I?LOBVbR84a0ocjm}@-pxF7{C$}#Dk?Jl z1MbWm;9s5@6|pQ6IWjXjSf1%mF3*gJD@QGZJQ0P7!1&5D%T0OaoBcZ^otHEx>B*$S zNh!%wlb=lfV{+F4mk;>PfL#N63>+~K8IF>Zv3~=vM9`Uz&Bexy+XVg+`&*6aHpH05 za~N!stiNPHf~o}5AZ8LK4>J!_j#-VV!feLWV;V8eAPZ2X&VZT#CSy`C!!Z9WF1-A= z!X^_wh{?m0W2!Lqm`03fOU48-d6;rc6{a4ezhunU(O89hJ*E+32ouDVhlTxTd8{H> zJ*E-kh1bv1Ff@PD9i#G+vS1K~rtcj79Rp6n}irtUJF3Qxdl^?(ciyA(|@;|zKW*1pd-AT!pk=fw|GqZI!wn-`BGV5jhTZ{ zJSwl3Fsj33%IQkXW0+Ibo#KWyI&C8bRGeclQ!ukJDyw>o{{9(Fs{7#>O*FGHQ!$F8 z9J3DdJmxQ$cxYjL-)ZAtM^hqx&%!9qAVzIei?~K#W zR)YsH7eIp^VI74Tjky@(m6IR;sxvQs)tAaT53>|gg?S9K0rLc=9%CY$KYsZ1r*H4K z_bm_dY5&51%O=wKE+}5obD>NdEgG6vgJ+4(212!Usbg&GwMr zEDN#2DimXUU&b2WiB87X+}Ze!bum6JVe{3;8DIJTE#W&lx%dKFqsi01mXC1y{}W!V z;D28EMKYd=@>A8H>i0kH|7*)9g5Ktpzsmc6^|!}wRNwzjU-x*{e>Z%1dpcG6|8Z|? zZ>K7s@bdq6`HkxEe|q@;*V{*U|5yG0=evzRo~k?~sQsV+L%P%ywADzel##^f8Bfyu zyQ7)xhTNzSAEA5v4BaG3sn9@^YzCm?>`vHjp!MqNgQ2FZsJ!4#oL{Ge98-%7%NTvFjn@3TDo|RG>2&zQU7E-$19RIfFwxbt* zlal#>lCgPI$xOzlO6C&MSBj!16jJHvtEW>k>DY8ILF91RsboT-^Bo#Qk&R2#oQJ(f zhqVoFLkg>QW^3w>(09>4KNZ@62Kxv#ZsWei+>HB;W|5Qnx0xxHIKRGWW?_G&SxAl* z&xOoEg(}Mna9Lo^rj~4)-#~}e5xcW6%AaaEkKZFG>-pwGeCgP8C^W-d@6v8tgKZ05 z$>%d84>5OA>*!!qW+&%9h>KSrQLXJlG}*dPP1q2pYUSSz-5dHbZR7ROpJ}Nl=l$DG z&Xn^|=$n{D<_ee2SwBW3}zDyAxg<#P)E}VO!$ep&zg& z@tTu&kK3r`Z^Z8+b8`N#bZDDJz7_sL%3^_Au4mH*l-v2OxwZAKyo!U!zb&0{_{*bx zheFq*%TTVA!+dj^6Q{}!eKs7ytBK3GkRFXXebDAdZGQ|l>Vb;&d?)W}@hT1LCkjp# z>GlBiLDjnFru?IU#a8)`{4)B>GruhQ@@HRu_T~AZ8$)-~3wF7^K(%V)`_TN(ylwtu zbb;rW<_jm?znT+#ePI6X_JVEZDBmw*J~uz)-&f2Zak1flVh)%i*gbDroUo6g*$RdJ zz($b|-Lh#m_hPdf^S(Lklu8r7KQr%{+nukc_x8=ujcF+K2D&)8oWt*T(8aPw zhE~m^yNh`po9X7aPKc#uA78bm(rr(dni{?zHoxKDV)L5$1ANIV&4Bs2c@_IKv)74# z3BP}BraAFEWPXfx$*Z@;tSfFYr#mitOlSO6qnq-2%}XW+o99ds|GtRsOXW0_%g=<@ zm

v^EzXvI2o&H_*sGOh`V1g6VW8uvYKtaZ+?c&MVJb%>$bk1;p=Mi0RK+Fe3wTm z6~}mf-$K6{f-j}Pr4S93trG!LL={@i z7?*+quDBfO*xqlxLx`#LUF-Wklj_*37vJGfkb!%9E`Fg)%^K6k@x2vIBe@8Qe?+X~ul*>!t?Bf5H_b2eX9KC{E zELYE?=eNli8W-%CCk~;$Z{t+|7yldMgdD_3oaKxIqR``giqnpK`qkqrq#L<;5>~e_ z$A0;PFI&DGPrv_}!~eapFJ!(Xy$|W@q0nD3Z`0c?CBHKt@ck$HeJHdIbJV=zy8O|6 z&i7B~=}O~y`n>o-OKXd7>-BQ?di-HG^bgHv_`lt}<%E8UzRvnH=6(95Mm&X4&lfhC zdvN*0{NDMx4lWT2-DY;W^}dPTFJC_}`&p^guWuRk`%L=%+l+9wb<8n;!|q(nUrblW zmwIz3v;$4B&8fIRTb~v$;DrNpyj~A(V10yjV)KR*`X+k2_`)M@=yx0ragI6Yw7mYf zHJUE``?{IVdh2_wQpRu5(z2pyYWeq4OeH@n?0`Jm>gPAAiW{zc0ccYzh3>EXH;=rV}e`>ieP43-tdT$Yow0 zuYn7&K5teydE`n^zS?^K&*=RZIWA?a3xq^%#1)4XwT|K61a4r;+@=g|)#@=sT<|?1E~q_1@=7ZmGES!K|TA z+ZfcZ+s5@fSeddM!MZMI^^lza=+f=?H%&R;e&jt-)F$tE6id>xqrTj)Fufgr8u@3q zF^CIT9v~lQA=3!e=O@z^KX7=ul>pT9?Z_`5>iI&+dt=?W(%o_YeEg};XCVpLnpCfs zZ;kusIlp>1(zhpDM9??hnS}s z!!5V@6DvbX{Rlin_%f2h`|jAX8$WNEryTqD=<}PPOn%mxHyOA8z?co zs~lqw$r$~CRyzkF$o z-{XeYIIbT3l0!)mqyCFd`N-e1&e&~7>J{`*PXamE%DDor{BXKMo5pYT-@R_!;u-9( zak#?^{2FSmaiknuN{J2^*FC_f{rS-`D6asvaDmkABbk9O}?{{2-s;v??2L--VKcKDUK^!&=}|CFTowD%i#c;?J3m@ z33;U>?W_0OynKV1z&s=YPZsQrAMpUi@sAw9_IL3B8>1wC&An~!w==)XnIXK5+~c)` zQ;q-OW4|5wm7b>yu=5_-wDo>{d1HUz%SuN4_x`1R{}X8YoROT}TFB{M4{v6~_WHeI zR*&bMASCWOS2q9Hk+~&fi&l-UA2HUx2iIdSnNvD{b)|`;Zrc+-P`|hR|A2X!ulJcP zc-%>I2F()=JE4Dww7`xnWChzcx3YQ~3f<$%1wUw&3qq!6Xg(5-#$7KaNeOl?VCzsl zau2fv`=$B7I^6$E-?z1NEnmNY$Am(+A_FMD8vlid%sX%bFWxtpC4@p3!x7{rUZDPW z(50~dS4jN_Tj^?({1slZzefL8-SCq6?Z_|J)7g#23ri=B`VV0v$zJY~?S-A`voE?a zjD}Z)LW{%XeM$S<&2O3Yec;xc#(T;9Tinu+eDE_TrdZaK*E_X25g+RPivRn}GlVhp zwrI*rzb}HL2qhB?antrB0?iBx;RKS!Y453W|uo@1{_bv6B>05c<=GKn?RtxkpqpviSw$wE9*XVCY{*$#p zo~|p)ZIO}z+Uq>LnV;?b(sy*nXwI)PY14SU8>Z*#OrMmDX0d=* zBtIe}qavcPj`GJP2lL9=GdL&zrdc)oQ*rPi7~+}>pgpnJ%^J0f?>y>&sqkhZDL0X zZZe;bwMKTUx3j~Ku)T;wMsdkcGIkAFFYjKJY2zr*(mKI^{{HVPfpypag&nN_`~Ftv zbo(!*H}w9C|4ZTS3+((ah5O%EA~vNJA9NDC`M3WHB2Ikw-wyPj0RQC@u>7noxaEy) z-|hKaRGX9YOXE)XpB+uxY+~AeI=`I5C}DQ(aV`3tAzf8y_o9(Esz&N?Aux@S!|tHPJuCW5w1%yhqH7i@L&IeuhUelh>> z$MnYevtM8RZwgNPB28L6$XzLE^FZESNt^0^SAcKvy$+;pq;Z7D^o~Mx5AuK7G3;ab zJ_L3G4}jeDoU`9zpaJX^X>wk&7|^+fX#54iSa35q6nxOdQm`}MO<)wLz2aTLJO-97 z;3O~-ln~wz)E@Hg;4m-(Oa|k?4X*uKumj(`0qD4wxbFMuND6l+cp6v=b_9ok3cnwJ z2gr8?0}S)1v{De>pEeKt1@_axKatO=76UopFR>4T%I|24fpk#e8o<6P2aAENAb0kp zHG_;XX-8f6Cf9v4mK^CyTL*3v9WKrURX^F_0O%YFav4WjBB=W71U?BWQiVHChxrM3 z2z(Aa0CFcx@qUZb8$kMWT0JQLwczvMCh&dyRa>0C4%~$OYVfbvud+CuJ1`A**%jYu zae6uUN4}R@oL&m@c2{wU#p%VM(wPY=ov9%A5fo3cI6WI=4xN?(%HL4%=U_6Zc9`JW z$GPZt@dS)T^c@97Uz5e@hd|NSXmR>J@Mrj|b#WEAo$q4s8E_gnm~st*D&Jv3>TRgS zz#woS-^msO3E&xg$6E|Ufuj2aj7)eOd7BrL`Sx3!Zb0>mV=!USa|o;jUjomf zUDSf#k1#n~ECx2Y_Eq2m*srq~(D_{XuK>S?{hbyArC^43(>b8%90xuNjt0e73tXHBivKu1K(o0 z;+vzvAMm}ls~vw~up!nT!+*My3vk?Zk55*am_JEL_R_%T_GL~LKJ`Pw6>;@G- z4@5Y0RD+d#Ys{?xC%N_~n1x=>5mxRGXQdW8LFFR{RJz#~1L>ghGswktFz?=kTLp60 zXxdaz@uY(aKgh)cRI1{g2Yw0$LAfV_ia)_(AP&?x-Aukk_cR7<&a|cN<{yU0v<;xz zRh7lSDp2Lx$;G26>d@uoG+7KB0_9%sVk!6|zKh-O98mtVEe6K9_Q@_blm0#UKL)M> z_knvT-#r!sn?TWDZ85NxOS3g@&2(`X_ypfv5Nq}lF3w_LG)lv_upb7dQ4T4f=!^pI z22bFx20RX`T{MD9=YYk)Qv9vMz5tZ{OpAd{p!`4R+OKu(#|@;tlTF}EZKgq0_Cq5Y#^RNF7mdaW4{UH z{CZjisC<{ZSOO-I-aPOz%BR?3U>c})KM8ck0~b?3_1AdtY|>%lhj|2lyQxHd*Mbl5 zT?&ex9MA{dK`?@H8f`I<0iH#@r&|mR0@vc-5558(INg|6p=ZCvz)PU$*$S=!*MahX zC#ZC?!3V)X;P=22iJZ{~o4}XB{ornJ6{z?(qeOPf6%_r$-0u?{DwX{{Q1LwoJ_N1; z&wyUt{tX5a!C3Ou3G4)(=;P?gbDAv%nm~oy@7nKk?e~C+XSc<`I&dH5whHutrJ(9* z66o+Xa2Mahzy>fLRDJN~z2pA`?Mr<27`UGDI%+W>rM>8@A~9hB_#*L-14VBFRg)eb2$Hi5{jrkD!xOAJ| zA-+H7dpD?Zn})rQ^wUXfEa@bIYEOPJ3p|0lkR>=LU(FX-47%ULz)Ns11r=|BYoF)h zR2O%Xi3#`{?c#xvHl1v69QGNY$}Is*fF3_Mp7tJPG0>dBg;@Ao3d+40lzV~2Kr%Q6 z_YCceac1E}kHq?DvDy zz-c6^emfdexuv_fDVKX?a9<0mJ|=-ID(2)^49tYMD8BP72C64ne+8iY&9oSpGR3xo zC~zI~6}Y&S zLU)@TwDh#-nF30XAhCfy&jZ(t&3GIu5xi2 zsPdR109K=Yh)K%o{9U4!RgOi*^AWoh$|p6j-|V zxtLIB!&l6<_T?_l1jXN`fTAl3RQ_~%0~pv!IOVU_Vqi6>@|fx3rUlO36KPeT>?^=? zi6`jdAQ$6ZjB@e#eCzL!i~C&Mv+rF>Nm%AuW)f4*bRTRp!~n&+V63{dEBOK?FlfK2kYEbb$2r9i* zw_AS|UjMiF5U@l<+~XCC71y!K0ids z--%@w>s{RBVzG-EE)E4>!+#=pH`qix%Fk{pTkUrXC_T(37dL>1df~vP<@F6e(R6Kqc8=+tE?FXlj&Tdfdn?bdsDXx1qsB#)- zF%YCN%3lVkc#jjG;%Nfq?~uj7zVBFn)u8gb4*VVYTm{O1IVk^2Ee1+ukG~+;0Za!~ zE-B!9d>gPYxSDi*;1n8(=xC&oOd#I}EC%+0%J+ld@4ymp4_FMo3}%CS!Q&Ku0{PAW z5Ac1I#-#WTfJ%20C^|Q|-|O^^|4HE6_)iBlZZ^{xl#k;U1NGn!aIXM0e;Ws0hnx_! z7&v;DO?NY>baOz3&$bvy2SxudQ0Wh&b2#Mys(mE8-wEI+`0M0;s}nuQce7hA`&`@r zDxL>HrL)#zU=Wp}a!vp#lC-0Q*Y`db>p`kKtptShw3)8|X&_cXEUhwKMu#=(k@QmsPZ@lsyvQb4D16{9-F|4wCie%fem11 z?5jY9TLmh=!$|yN&<`<<;3V)Mm7Wa+ZF>Gz#PI?Sqv-%KOtWmpi}wGdDzOE$u1tlUhVG?-zvZTF75-BuiY-L1C{=2 zQ0cF-7^raVOF*YwAF=TyyO;=41ZnZ0-1mcucLPY3r#%R&yjO#wv(&XO0F~aLbsg7dQ<3f^b7E2K=D->mCBB9B1-98TUMkfriIyKKE>}?j>MK zgxMe@zMOgPw~+6^P%s{Mq1;p4Z=u{z@Q>QpQE&?BG+7L+1)FFOt1Si!!1wr`X)zE4 zMPD-b7wi))2987DpZPv!F_8Qt>u;)yQ$UsT9~&!o z7$~o?@k{}KPxx%`D%{6e3V{lk^fGh=$iym#cA2#=cGT*Vqh3Z(@fg{{tT=F zdAu=aoyEW^Q1l-Fufcx5#lY0fHvVzov$!|?#Ma+_@Ndww&tjkfJe~U50CHb#PL;*L zYEXKJ5^x&!^DG8NgQC0Kjem=an?dE{rJu4N0r#z7Ew}~zjPRQ+21-E5$thqn_Jb@2 zqCn;2s2d;0oXoYjpTHgr90xy!?qe1M<<5~IpZt_sz^uvnq1risvOpm`8vkI z3a}O|1*K1)3d;W!@VDSF@OAtrf?t69evTXjKip$6uoX1Wy%{`#|0+=H@a3RGAE018rPyM2I~JmuHHYqv8sCCZu6r} zr)8*6v|!bORg1P#q-vFJtyraM(5gkN){j-IR;^mKYSpR%0|W>VAV3BJgdsBo2oNL# zVF(f=K!5;Y2oQz;&cbt!0r9R>8Z_Pep0+pnU%_ z0m}KT4?F;Qp?j2m@Mgq4;4VBj;Z}Zk4NReY8If=5LXl1?9SRl<~%0`n_QRl<~#Eeb8PQ zTwgCr69A*YC|T;@?Pt27yKy+2U) zZwQqA8&n!UDCa>JDE+U3GR_%rAMEdGrI`Tbco?`(^SVg0vj1oA z*Zu7T<$OH^O8ZIVOFKbOwm+aWE>PlAIpqk5Lv6UidU-MgO8a%h&}8#fK%Z0-~{*_j+b%ecgtu8yK*=M%J-qf5BxsXyH{yEpd1fN;B%l8l<^FLvOh;3SN4Lp z!z)GIt_&#drLT|^pv->{DD@p=6XOyufU-S{Pv~|`gWtip@@PK}#zC342FfMBLY6^U zuQ^cGmA|TS4~SFC@Ctny976qh5Qo6i=qey=D^Wsi(Bk4I@{K?}w+3Cg^Ufa~J}W&XNBnP&%>1?#(TpC03_DNPmp zGrXcSG4O8Wg~30fJft)}@E(*egL2+o0=Hlsi%K&Ko{RW2DC^#-G$Wv#AN#?(aNPDO zP5dc6Zla*PpLsz$xCTo9qx2ERd+5cIZeI@UL_b-jSp?;|m*kUr-iU*8yhK2`9tbOq z54;KO&x3M)?tfm_Ul;fW=C}DDy&qWzI}opeZD5(62W7n`$PgJIeWZtUk*nk~xk%2F zv*a{6MNWWkqQ7psgKQxiJZ@^BjI#vZ4vu1b`mny-pqyXIFX*^)WReV!KGH+F$W?Ng zoFNCuZnDC8%#lg5{vy7|K>rDF6%2!alXayuUhuDQkJ7loHMmP@R=~f&mz8D#+<^T# zuQan@2Yg0pMnPHUnV0bWJl1DgX;L5#6lYRtM!+}G?vT<9f^WbFlxA(OzE2N;uVVfu z|F`~o>xcWmk77F<4ULE3@_rt9Mb~eD^n*vBd=|u8)bKbc?<=FA97hA7tj})nJUD&@ z#QOIrNwh0@aS(5v!x2#O*1%ig)1b6F_nP)M3rfC|oCJ3uZv=b*>}GlM)s~h|pk5J_ z<19f&$S^4F_(AD!k>#`G1b7bW^?w5p)p!6pXg>_**i*2nfvtSyuU_YglW*(IB4uP#GA5@wiP_7TE_SW^|F$;bh z^<$v4=LY5dYZR1zy1*HD0}oA#7eQ$^56XO{L3#fUgF*N*_&s>Q+S>A6a0-;`kTKAL z_z)=D*8|Epik8;(&(|?fK2LkWIdBI2E#i})1Nmd%{#a+DN;3qmAGdf2@_yvW!;r!d z&f-g`9{}ZjV*-@-%@OckF#aZVQg~f54g_On(;w@!(0hH^j9*53r6)ydiG|yR7n&JkX?>Kk{ z^8Fw#HHTdtTHZi?Strw=tdjzEqU@h6SODYnFerHe@HEf`J_4>VJ`YNL`I1V;+k}H= zgg&G+L;Gs`ePk~v>!O=%A(>TKec8#f?n?)%7r_s~J>U;bAfU_GyqC_y`=onngxub zi4WzVX@DO>UIp}kIdBw=fl_Y@l=q8bk9r!kp?*qfe4wm<4=DS?tu!7S#8Q6+JPRBF zWj=2{QAx)|O?|7fSs! zT`2Yapsa^AP}adTeS%)V{zl$#jckxrTr5aG6%a+kWl+YS0Y8WNO0Yc6@-QgZ+kWsx z#9iQzG43^`S)k9;yTKnJ-la4Sa3A#7d}nJ5mez0@l>M6kWuD_o;|FD2(=2zgd<;Ac z{kn0JPR2O_O8rq#>W?T*@4K~rHz@C44V15MCs_n#zVe{FUnW2~4zsM6B4ePOFGJu( zpqJ$?Q0gy$GT+_(+WzW$l=(qj$9@nWk%m`5>3z`Mg-~s4wN@@DRhtZz{{0aK8DNXHQ%};@npH!L{_+j)L1ZCU-r5Oih zJ~EiM_46Sp^SKJ*Bj@k}=d%kRswLjQJjpzV;WB;?DCdy{()++6PG1UDdWL1}E@;TTU1CvW+D83ScK zxWS`joS@Vn0%d;d*nXMEfe}59TR_<_O^h2fZkErod`4;d57&0;@O{yLO=*hY$Iwp} z+=%jw(#$h|8pKDx;UsuA7zMwM<30?^b%Y0$@f1Iz9sp&$tK=*w<931vgCn5i_b}c- zeaWwaa-BOns_VQLlywt3Lf5$qlztaLsXzTut>*;gxR?axc<5(&AIlqPN7^ru88Qt@ zy*McS_(3^;#92Sa`T@ERl)N=i`j32E+x3&VkG10WB4fXR(qD~v6Jy%X5GeIq!27YC zb<~snR#Tb^*ou0NPiTD`DB~-#UJjJ}tkQ%)>1P>~@vO4mBDui&GvFS?M?pC*TRz!} z-%5@7fXg`YptPG)nhYrGFpfNFKL*M;7U>K0QBd0JJ5uv{z%$`>ls^q7Sso(Ypsa&s zP{unnuJs1NXW$M{>P0|&lpC%wUIl&d0^=)2>y3btANZ8I{C1`F`5934&%lWIMG+9vUXOt!a zO8y!s`)vi|UPQmkN|QLMwdGUT{uKCc#K%6X`9q+z-v!G0EhGLc;x4%4jZSLb0ND>p zelPeO;@zOst0G_ady(y>*j^Bn_DZamBLm=nQSN5_RZzBPMQOS|ul+he>96@YUDs() zwlhk)Kroe}V0 zX&>x>2T2bo<8p)2{wlaWZ%VTaz8CeDz*n)q=fKmz8Srw@3ChnoE__MnXO5gACqbF7 zQLr8C2j%l|FZeZlKJHN(o0KEo_+o1dE-{Adpm-j993BBf=qChj2K`_kjt`&GxWTt0 ze-V`ZGz&(MHwL~Fd80}*1a3k30OPeU;Q9w%2EAYeyae=s1L$`dlzDW5((V*}43zmA z0%g7im8O^8LwA7kxvznFs)1EdeA%h(j)HRh4uW#OwFi6;`t7E7fmh(Tb0|#{^Ca;G zDET$;a>T1j69Z*jVNk{uQkpF4%k@);bR5&#@>A5aDNPF~*Y`EVrCwEOY+uD+fIeCn(3+IQVmH@0ijIg0g)jv?tq_2c`d<(xgFYe;g-s$?F9r zuM3nshte#9GOh(s&LeZ6)LZ$6mJfo`e-|k2WDu8jlAyGcP?|V+Ao9YXobN+Q;|Ha^ z{%>k~z2IfoPgS;`Bcq_?B@mbQ*%0%6qzAkd_2xmzo1NA6CdfL=%k(T6042ZiEzK{H zIZ)O~0>lyK zZ})+?)jOO6W&V?72$cMw(s)=NoYOoX=^@>q^t%emd21Pz^T{mZGmKAyGM+I|+8OWHuG=Lh9}+8WDOK-up8|I_;2WCP_g zuDa4>L8+exWgKbd#lVZOoo;dll=d2o*XaG<)AoBoiBHid=q=yZcynIg&vKybhb-6* zCP8`sh=I5@?Tji-NXilSfO5Zj5nMlhKzU!B0pA5qfX9Qqpd1f9N|QnVavn~Aw}4Ub z6|^5w8XqX*_5VQI^MbN}SHPXv?io-%_fLRwJ>0-{$bKz@ohUDWk{<=-{1If_4KCsQ z;ZmA4#?xp=#$P6TeyH9BzJ~Jb&$PV=83GT%`U-$@JgkBT%X$Z89Mzxd_EwZ8L66fT z^f28=_tIDCD|9D)iatsoq07TdGXC149(Or14a&TylqL$wID?>!)5Ex%@p<|jeUv^z zAE5Ws<>4x6zxk7OnwrvCrI+YMdY+!6`@#LOKYU8#VcgBQ3zYr12%d}W8vG!?K1`!A{POt3r%_M_ax zayQGDL0K2mEO)YekmcQAE86c;niAG~xVA*`#|wI`V2ku3ysIg5a}b=K>0j856b7pJ|V`@t29ltBj<$*_y|}8-;KO1 z7{PwXC`}T?S2DxBztrb2<69eUZ8wR_qYm}FirU)JYFDOkClyQVf zFZdqx<53zH_-^=`(yV~XsK2Z->|RKgP*XQ0k2+%^>&_zzeVt{axt^!;QG+yfs6<^E3^l=~qOFa3`yNFSl+j?>R!K2YMT^ifc* zuTm~8p95b(e2DG<4?w%_ziE7lOrhO(p}hC+*q>k*_)f5b^8LV(6LfzKfbzMp7wo}5 zyFu9xT}tBs|APHzQ<|DvuTLxB{(3iyz>S#iBq;OZ2W5VzSUyG{WZVYcf&AW+b=}2I!S*444SWYULmvTUUV7+d ze;T+s%OT`9DQp1Eu|GP_}yIfPG;W`^<5HSsP~IOGKm#EyahChY1#%RWenymLh~*Wu zC*@_O@q!nlUpM$ZY==u}7C`BLUTG43^|;c6LAk%-V)+`&mq3}nIq-4prwPW#86N^= z{q}*fz20;6zNnjA0zZJ1DNxq?04V40eo)RgJ)j$Go}=@h2RqPS7L@%G0j0hR9K`ml zDa|stKJQ915B?4FIHxqTp!72X%Kn=q$3U5fQKcCIcVgTFpxn>x17%!Qj;{d9_Gdt; zmsXn0d0HL^B|ienb!-5Xe*K^vPhRj)jDHD~^*#?u-XtjP4uMj?50v(Mm8J`n_ZQy< zdVIUU522k^P}-dVrM>3)t?R$1umIvwzTq7BD%$shvRxi<{e1vD74ZprKivV!x~^~H z_t)S%F^^uQDFoE>O5+3f#W)thA+S4$@qjTQ#uEe&f-itFzA15R*QC;nWpSTdwio;` z^5XYkKH!zR@tg^~>n?qstdzm`qwq91jQ`y9N${gmerIdTN5B{;@l|r_4!uqpy&d1< zqI^ExDqj^1kAnDvbYUUJ?Hr*C;ii0BYs<%x=K-fc7ubh+SW}uY@CcNL|E1d#Qkv+k ztu05Rd<~TPi{NL$LHa~WedHE=&x3ORKQ*s%voZxr{%EqbWfCmkq~*2k$}lMH`@t`O zvo~tFKY{OENAPnDplpwiE|l#V0A*f!L8%|TUh9QG>2DG|1}trBZTUPn3$A}2P?||F zj`oGp{sdhp?N7#ATRx3?+3WDU3+M;MEB|P1ITDP3GXImH%uDcE-47m6d;**R!!fPr z1!aEb=?mB3`t7imuu%G+rwiBnzZ&<=ux?vGnU~U4_#gg@g5s;>6!=AWCaUEVp!nch zemOP<-UZ6I5)sXtAt%8vqr7mLmb*czKTa=h)$)GQ0ZRVL7A;SQHQxuyxK=rZm}{mgkt4ei+YDATO{(Iq`@- zM==7*b(yQ6$LZWoJ$_~$!}TfJn^v0XqF#@LO8WUBs5GOXeBKxY4@Ulg()5A-GJd5g zKdGNXN=lQU$LW2bw9_q)dRW+kO8%tM zjDTL`3nhPuE|mQ8<9N{i5-O3NM8!(H! zdHfu|@H5!X3|$B}{^xZa47{lAbb->&Yz^;2_z^WB&PUD}x)5%{b-Yi?IF)7*JPf{| zH1ptx;d4sU4}J*Vr!>9b2jM+R)5W-haU0_;jMw&R{i@PbK&f9=nmj#6PtlX~D44Rg zgoRVso(NqCH$m{dXfL2Ne((^uPiZ{h0NkxKF2>gwUjpBU_@dGbfigdXO4AFjp?{(D z-$NHl|BaV$y@dR_($v5Yz^h7=2E(W?l=>;UQ0lwD_alEzX=cD-__WeE!6EpR(u{#V zv?rAIM(ILnuYz?T+f!DWEVzVxq2y=iLdo~PuIpzSl=WS2Dr02vwbqs|p?r``ysGEV z{#W$4?o*mDk2Yw9hRT>ZYQMg-aR`HPUq3Ab{ zhn7Er@|@Cy!8-b%1*N|krICl5{|;~BhZ8_k0Oh*W2g-AHOW+9Ni%Jv5hiJKe^nr5S z>H_8ZaT%2B<8e^lr@BD7Zz~_VO{QkE%ZVpI2A1Lu8 zZf;533rat3P@cD21>b?~Tm&U=gzN+5zDpA~u_V6+%5%OYQ1Y^%+L^Tz@x+cg8qa}87A7{)iL zG(+@3dK&emUK%bek>j|S?!&l7!FPgga6hpBGnVzA6Nyb&)}K@F0{20A`qLKq3Tk*9 zly#r|l%?fY@I~-9VBIK}Kv_>+pv05oT0RF#dG$!k`hD1n(v(4|A0$V>-@^My2U+~2 zmWM#epCx<9#wRQ-?U=8+(j>vhF)sQ1at=^LYyM8B>}?y!nVP zC`}O;12Ud8DD9<`#s&To050>yIFHC|Cvm8SZBEsv8upv1eCrh+$9 z={EyPd0J^2xTvVZ>q?V;fq3vwW}~ck^Hd$8oh^ zeF>Cx9K*%5+;1Dg#k|~y8C05ucWIvID9if&)+Q+Hr2_s0Opm0Sn*+xQy~&g7e@KI1By=oCak(rod6K{sny>DuA-R8Sp14p96mdPJ*(1BcQZ9 z0LnZ%7_XrnDbImYo&bLVM!_S%xi9MWj(~F9_>Zxy|DF{2Wo>6-eKeixG&S%HcvWe9 zpd4RbrI`SKigAR$r04Bk4T*CELi7tejz_GZFK|SxcbUT}~dR}ZOO#=KK z>cy2N3a-E-O5;@yuaI+~oL6U+CiYF8kEqgkL7C6RZ|M38eOu!}rRk^l(VO6bXs@9( zc~H*F_3voCn$oPyt1m0f>Vo=;(scdEvVK2g6<@lYiuz07aoEobpp0h{^rCzO{2R&# z!M}pZUs+mCLwPTm{-vem1b7&f{TxynAIn!*zRdDb@D$_^fznSG_-%Oo7ka!Gz?0z_ za1H%AK^fmDDE;(-JEb1zf!n~7z{-+k{rB-?K{-y7WDt~b1(e1I%Kgh}Q2HMNrQL3p zcl}!P9ZFMO(es24l>XeHoG;cuIi6NPIbY0ya$L)oz~2H3ztwmalz5U1gA!i`<$SgX z%JDV;N_$Ow`6}nh5-8`3JSgQ^P})y}(q0sl^JqkAJfP&wFg^jwdAJXhetJOZr-bd2 zybLJUS8-7KiLg8bO8fJmd~cHagXYIUIbVgqpP{_#_c%^L`7&MFt^N-4h~uxKG-VK% zF3ytDgg}`$Ke#XG0`~(KR&{^QkWTR9Xm1jf?Opzpu8&zz)=d}KkNK(p(b94VSOlZ! zr=T=>@Je`2X(FHx^*o?#?=pA>j@Kon83a#<4=7DH_$cakDNPpRko^@0<$Wm(%KMTZ zl=(?wJhC36WEzz9mQtGKKkIrN0cE{)gA(sjn*P7wyovT|YnJur1*%F@22YgvQ<}Ns zG;au$=L!aurXTzy^7@n}>(=%&N|Qa=vi@_NY4954rIaS_!#ttiMesVX2b6JjD^2Be zOG^ah1yGKUk<)M!2OI$9ykG-g#r9OaTAl(WKMqQK7Q6)PXS{H#wi5@XoggTAE1>jW zI>pjr!F&#a(oP>JaR(^lvMEg!^@CT-_AAZUxmv$?j-}-v$m{j%c`kLf z_P-3Cg#0C?SpbiO&nwL!DC6z}L&CFkT&^><-33tQV-l2c41qGfL8Vy;>i!-BZ?OFt5U<>1g^VQR!tdkfh{fEKLV09C>3zYgHP{!E^Xn6&caTP%sPeEyB zHd|V*K)DT+^Jw`JWs-D}tK=d%3d;VS3~Bpgp!8e1So_U`GQRvp+MWxP{ue+wf7w78 zx938wzXq;vHz?yl72r^r#Vo2*7Po+g9jA~^}lyo`dff16ioze!N`TkjRRy`{^w zTz*L4a`c;uDC1=GGR+HuGVbtJbw9Yi-JtB>QBdZ&9~_r;t~5QMe4jD0MaNqYbKIcR zUnDD+>VD`3<+!qeGCx(U2iXr5rSWdld3A$Zq&_J7WgL|JK~UDu04Vd{2VM$xfzn?# zuJfD#Wxq#2$)5rX7-u&qc{A53o#4grF>(aNsmVE{G=rcAKA<%7|Ip)Vnw%g<$X-y| z?*^sa7BYFQjwcREJOax01jseUmqD5D1yJVO3CeZEIGK!T{TL|iM@Sd=N3636P}V~) zDD&E*G#Si~cv@*vpgeC72j%&`C@ACVzh2jCh4kH^<6Hx!-B7|J_c@2hL1}MHX<9(} zd9x<+K$8Wfy)^Su%v-t9(sCKf2gxo_@&em+J3XKrFGZ9~`vs*Lzsb@fe%z|>B zF5imx6X^%M8e9Xf0td)?NXrVb z^Hl()pS;pUL1{OFcBMS5G$Byx7g=6l`TXtrzSRdxey`Hhz@5mih+{ly##4-s+^zHN z0A;>=@6!44-Kku;LpcxPZ_$Q@czm11m_SJN_>hgl=wI(;~G<%AyDQ&nO%<$ zd+yV5u7dLZ+7HTc-UZ4$)b3S}gEEg!Q09LEl=U_SO8cWq(+kS+w(yv4cOQ5#w%NNE;8ECJ`d(#$bF%eW1ce##GN{St_!<}4~r43zl_gEC(;pyZE|nLO@uBR{P) zUQpu8U>Ek&lG02FQQk$yAJn`6DD$%b%KDvP`5?>Xhtwn<+o24A(*7XX&2rBJI{q~f zr%vap(sY56U&`rzOM>D~a)9LyQ1)ZvevQY-RZ!-8MQM6iZUbd|LQm*@=Kv`8xmQ4$ zuTfC$zYl`){7o+?_kFq~j`kc%W0P{^H6B-1K-vF!Q2Na&O$?Nu69|D1fvey_;4Jtl zZ10THjDZF|sx*V3v@@VI4p8osCyUx&43znGfl|Ii_JQ(qG`&hw!SN*V40t>^P}2R? z1IqUo%_r6KWR^^mNpSt|jDUBdz6ZP;Tm?O-zX+ZJ&Vo09Q{eh~0AEJlD7~NT1>b{m z2Pn_owSXO91@n0@xWw_zkuzi#Y+`@JL3#cz3U0@FETS|)DMx)D=>}#0^zYLB-2=uk zJ{u_OsQwh!0VwNd8IG{L0LDGpgf;72FmvpL-Z>8dAGC+ z%KFKpT+VN4@clA=P>##NvYuCZ!JCjj0lp3GUP>!=oRmU3v4};H;6J+H%Esv3Ia+w??TgV#QpL-tLjkhl0U07eUbRpc7 z{)7Ae7=IqT5AmGROoK8$=LO|W$S809W753Yh6P`(UyfQumB2R6=w{{&~jo55-DCU6RLAa4R}2gkrRa0Il2 zgP;xU2d!W)XaT#yR?q=rVXklAo6;T@=}yT5QFkM@t>sb40}EgS>5qUl@L{k5z7Kix zi0^O3_`v7)-!X-io#9R5s0EoBpjTt-sE(R!nxBf*i0@fr>ddO9Bk(?!` z$T4yd#3^!PFX$Owp2_(l(iQ}xDG5N{P57eTxQY@7x07O-& PzG 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

h`#jTBZQRdTM3sKKP!c16W2fH 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 ydCELbndd3bprQ_nijA<#w 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

    mToN2G;_Q9zfoOf#Lji2km|0>|0bK?8Z)3&9s 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

    +8|`Fe}5he^`<0O^nL5??QI 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 - - PreserveNewest - - - PreserveNewest - From 1351bfdd1fb2aeac020f6f032125db47bda0e3c0 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 9 Aug 2019 19:21:21 +0930 Subject: [PATCH 196/645] Add iOS FFmpeg references --- osu.iOS.props | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.iOS.props b/osu.iOS.props index 82c60d0aed..58c2a55b74 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -97,6 +97,11 @@ False True + + Static + False + True + From f68e41f7b9fef17f238cf322d655f9c7b8164074 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 9 Aug 2019 19:30:31 +0930 Subject: [PATCH 197/645] Remove BASS references from osu.Game.Tests.iOS --- osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj b/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj index ea5ab699f3..5c0713b895 100644 --- a/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj +++ b/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj @@ -13,14 +13,6 @@ - - libbass.a - PreserveNewest - - - libbass_fx.a - PreserveNewest - Linker.xml From 90b1fe81f3ffa99167bfa20af7b87ba3c60c8ca9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 19:12:29 +0900 Subject: [PATCH 198/645] Update cached usage in line with framework changes --- osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- osu.Game.Tournament/Screens/Ladder/LadderScreen.cs | 2 +- osu.Game/Graphics/Backgrounds/Triangles.cs | 4 ++-- osu.Game/Graphics/UserInterface/LineGraph.cs | 2 +- osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 2 +- osu.Game/Screens/Play/SquareGraph.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++-- osu.Game/Storyboards/CommandTimeline.cs | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index 8102718edf..a92e56d3c3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces } } - private Cached subtractionCache = new Cached(); + private readonly Cached subtractionCache = new Cached(); public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index a4638c31f2..d3279652c7 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Objects public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; - private Cached endPositionCache; + private readonly Cached endPositionCache = new Cached(); public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1); diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 67531ce5d3..83a41a662f 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -88,7 +88,7 @@ namespace osu.Game.Tournament.Screens.Ladder }; } - private Cached layout = new Cached(); + private readonly Cached layout = new Cached(); protected override void Update() { diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 2b68e8530d..dffa0c4fd5 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -191,7 +191,7 @@ namespace osu.Game.Graphics.Backgrounds private readonly List parts = new List(); private Vector2 size; - private TriangleBatch vertexBatch; + private QuadBatch vertexBatch; public TrianglesDrawNode(Triangles source) : base(source) @@ -217,7 +217,7 @@ namespace osu.Game.Graphics.Backgrounds if (Source.AimCount > 0 && (vertexBatch == null || vertexBatch.Size != Source.AimCount)) { vertexBatch?.Dispose(); - vertexBatch = new TriangleBatch(Source.AimCount, 1); + vertexBatch = new QuadBatch(Source.AimCount, 1); } shader.Bind(); diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index 714e953816..6d65b77cbf 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface return base.Invalidate(invalidation, source, shallPropagate); } - private Cached pathCached = new Cached(); + private readonly Cached pathCached = new Cached(); protected override void Update() { diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 069e2d1a0b..19247d8a37 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.UI.Scrolling [Resolved] private IScrollingInfo scrollingInfo { get; set; } - private Cached initialStateCache = new Cached(); + private readonly Cached initialStateCache = new Cached(); public ScrollingHitObjectContainer() { diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 5b7a9574b6..9c56725c4e 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Play return base.Invalidate(invalidation, source, shallPropagate); } - private Cached layout = new Cached(); + private readonly Cached layout = new Cached(); private ScheduledDelegate scheduledCreate; protected override void Update() diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index cf88b697d9..7366fa8c17 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -93,8 +93,8 @@ namespace osu.Game.Screens.Select } private readonly List yPositions = new List(); - private Cached itemsCache = new Cached(); - private Cached scrollPositionCache = new Cached(); + private readonly Cached itemsCache = new Cached(); + private readonly Cached scrollPositionCache = new Cached(); private readonly Container scrollableContent; diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index aa1f137cf3..bcf642b4ea 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -15,10 +15,10 @@ namespace osu.Game.Storyboards public IEnumerable Commands => commands.OrderBy(c => c.StartTime); public bool HasCommands => commands.Count > 0; - private Cached startTimeBacking; + private readonly Cached startTimeBacking = new Cached(); public double StartTime => startTimeBacking.IsValid ? startTimeBacking : startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue; - private Cached endTimeBacking; + private readonly Cached endTimeBacking = new Cached(); public double EndTime => endTimeBacking.IsValid ? endTimeBacking : endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue; public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default; From cb0cd7ed589ef56f1b9a3cedae662a709397a022 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 20:05:28 +0900 Subject: [PATCH 199/645] Add triangles intro --- .../Visual/Menus/TestSceneIntroTriangles.cs | 15 + osu.Game/Configuration/IntroSequence.cs | 11 + osu.Game/Configuration/OsuConfigManager.cs | 5 +- .../Sections/Audio/MainMenuSettings.cs | 11 +- osu.Game/Screens/BackgroundScreen.cs | 16 +- .../Backgrounds/BackgroundScreenDefault.cs | 5 + osu.Game/Screens/Loader.cs | 19 +- osu.Game/Screens/Menu/IntroTriangles.cs | 413 ++++++++++++++++++ 8 files changed, 486 insertions(+), 9 deletions(-) create mode 100644 osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs create mode 100644 osu.Game/Configuration/IntroSequence.cs create mode 100644 osu.Game/Screens/Menu/IntroTriangles.cs diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs new file mode 100644 index 0000000000..df79584167 --- /dev/null +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs @@ -0,0 +1,15 @@ +// 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.Framework.Screens; +using osu.Game.Screens.Menu; + +namespace osu.Game.Tests.Visual.Menus +{ + [TestFixture] + public class TestSceneIntroTriangles : IntroTestScene + { + protected override IScreen CreateScreen() => new IntroTriangles(); + } +} diff --git a/osu.Game/Configuration/IntroSequence.cs b/osu.Game/Configuration/IntroSequence.cs new file mode 100644 index 0000000000..1eb953be36 --- /dev/null +++ b/osu.Game/Configuration/IntroSequence.cs @@ -0,0 +1,11 @@ +// 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.Configuration +{ + public enum IntroSequence + { + Circles, + Triangles + } +} diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1da7c7ec1d..19f46c1d6a 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -105,6 +105,8 @@ namespace osu.Game.Configuration Set(OsuSetting.ScalingPositionY, 0.5f, 0f, 1f); Set(OsuSetting.UIScale, 1f, 0.8f, 1.6f, 0.01f); + + Set(OsuSetting.IntroSequence, IntroSequence.Triangles); } public OsuConfigManager(Storage storage) @@ -167,6 +169,7 @@ namespace osu.Game.Configuration ScalingPositionY, ScalingSizeX, ScalingSizeY, - UIScale + UIScale, + IntroSequence } } diff --git a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs index 4e43caff23..5ccdc952ba 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs @@ -1,7 +1,10 @@ // 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.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Configuration; namespace osu.Game.Overlays.Settings.Sections.Audio @@ -13,7 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - Children = new[] + Children = new Drawable[] { new SettingsCheckbox { @@ -25,6 +28,12 @@ namespace osu.Game.Overlays.Settings.Sections.Audio LabelText = "osu! music theme", Bindable = config.GetBindable(OsuSetting.MenuMusic) }, + new SettingsDropdown + { + LabelText = "Intro sequence", + Bindable = config.GetBindable(OsuSetting.IntroSequence), + Items = Enum.GetValues(typeof(IntroSequence)).Cast() + }, }; } } diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index bbe162cf7c..5dfaceccf5 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -11,8 +11,11 @@ namespace osu.Game.Screens { public abstract class BackgroundScreen : Screen, IEquatable { - protected BackgroundScreen() + private readonly bool animateOnEnter; + + protected BackgroundScreen(bool animateOnEnter = true) { + this.animateOnEnter = animateOnEnter; Anchor = Anchor.Centre; Origin = Anchor.Centre; } @@ -39,11 +42,14 @@ namespace osu.Game.Screens public override void OnEntering(IScreen last) { - this.FadeOut(); - this.MoveToX(x_movement_amount); + if (animateOnEnter) + { + this.FadeOut(); + this.MoveToX(x_movement_amount); - this.FadeIn(transition_length, Easing.InOutQuart); - this.MoveToX(0, transition_length, Easing.InOutQuart); + this.FadeIn(transition_length, Easing.InOutQuart); + this.MoveToX(0, transition_length, Easing.InOutQuart); + } base.OnEntering(last); } diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index 55338ea01a..2d7fe6a6a3 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -25,6 +25,11 @@ namespace osu.Game.Screens.Backgrounds private Bindable user; private Bindable skin; + public BackgroundScreenDefault(bool animateOnEnter = true) + : base(animateOnEnter) + { + } + [BackgroundDependencyLoader] private void load(IAPIProvider api, SkinManager skinManager) { diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index de00ba2e9f..850349272e 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -9,6 +9,8 @@ using osu.Framework.Graphics.Shaders; using osu.Game.Screens.Menu; using osuTK; using osu.Framework.Screens; +using osu.Game.Configuration; +using IntroSequence = osu.Game.Configuration.IntroSequence; namespace osu.Game.Screens { @@ -45,6 +47,8 @@ namespace osu.Game.Screens private OsuScreen loadableScreen; private ShaderPrecompiler precompiler; + private IntroSequence introSequence; + protected virtual OsuScreen CreateLoadableScreen() { if (showDisclaimer) @@ -53,7 +57,17 @@ namespace osu.Game.Screens return getIntroSequence(); } - private IntroScreen getIntroSequence() => new IntroCircles(); + private IntroScreen getIntroSequence() + { + switch (introSequence) + { + case IntroSequence.Circles: + return new IntroCircles(); + + default: + return new IntroTriangles(); + } + } protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler(); @@ -79,9 +93,10 @@ namespace osu.Game.Screens } [BackgroundDependencyLoader] - private void load(OsuGameBase game) + private void load(OsuGameBase game, OsuConfigManager config) { showDisclaimer = game.IsDeployedBuild; + introSequence = config.Get(OsuSetting.IntroSequence); } ///

    public int MaxCatchUpFrames { get; set; } = 5; + /// + /// Whether to enable frame-stable playback. + /// + internal bool FrameStablePlayback = true; + [Cached] public GameplayClock GameplayClock { get; } @@ -113,6 +118,9 @@ namespace osu.Game.Rulesets.UI try { + if (!FrameStablePlayback) + manualClock.CurrentTime = newProposedTime; + if (firstConsumption) { // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour. From 0f4bada21e05264e6376f2227aa17524e145c474 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 18:27:45 +0900 Subject: [PATCH 285/645] Fix right click absolute scrolling interfering with context menus --- osu.Game/Screens/Select/BeatmapCarousel.cs | 33 +++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 6fda81e47d..7df27de55f 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Select InternalChild = new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, - Child = scroll = new OsuScrollContainer + Child = scroll = new CarouselScrollContainer { Masking = false, RelativeSizeAxes = Axes.Both, @@ -694,5 +694,36 @@ namespace osu.Game.Screens.Select base.PerformSelection(); } } + + private class CarouselScrollContainer : OsuScrollContainer + { + private bool rightMouseScrollBlocked; + + protected override bool OnMouseDown(MouseDownEvent e) + { + if (e.Button == MouseButton.Right) + { + // we need to block right click absolute scrolling when hovering a carousel item so context menus can display. + // this can be reconsidered when we have an alternative to right click scrolling. + if (GetContainingInputManager().HoveredDrawables.OfType().Any()) + { + rightMouseScrollBlocked = true; + return false; + } + + rightMouseScrollBlocked = false; + } + + return base.OnMouseDown(e); + } + + protected override bool OnDragStart(DragStartEvent e) + { + if (rightMouseScrollBlocked) + return false; + + return base.OnDragStart(e); + } + } } } From b57298406ff7f6a40b1dc661ac2769a363d49d3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 19:25:33 +0900 Subject: [PATCH 286/645] Fix right click blocking not resetting correctly --- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 7df27de55f..23c581c6f9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -710,10 +710,9 @@ namespace osu.Game.Screens.Select rightMouseScrollBlocked = true; return false; } - - rightMouseScrollBlocked = false; } + rightMouseScrollBlocked = false; return base.OnMouseDown(e); } From 386d78881394f344ab87054b926bbe3eb6963a81 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Thu, 15 Aug 2019 18:32:45 +0200 Subject: [PATCH 287/645] Change if-else to ternary if --- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index a46ecab6f0..6326c3a044 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -113,11 +113,7 @@ namespace osu.Game.Rulesets.Taiko.Replays else throw new InvalidOperationException("Unknown hit object type."); - TaikoHitObject nextHitObject; - if (i < Beatmap.HitObjects.Count - 1) - nextHitObject = Beatmap.HitObjects[i + 1]; - else - nextHitObject = null; + TaikoHitObject nextHitObject = i < Beatmap.HitObjects.Count - 1 ? Beatmap.HitObjects[i + 1] : null; bool canDelayKeyUp = nextHitObject != null && nextHitObject.StartTime > endTime + KEY_UP_DELAY; From aa3651f65eb98777c6254ae29e2512f2db098ba4 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Thu, 15 Aug 2019 19:45:10 +0200 Subject: [PATCH 288/645] Change the logic so the last button gets unpressed instead of staying pressed forever --- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 6326c3a044..1d35393de0 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko.Replays TaikoHitObject nextHitObject = i < Beatmap.HitObjects.Count - 1 ? Beatmap.HitObjects[i + 1] : null; - bool canDelayKeyUp = nextHitObject != null && nextHitObject.StartTime > endTime + KEY_UP_DELAY; + bool canDelayKeyUp = nextHitObject == null || nextHitObject.StartTime > endTime + KEY_UP_DELAY; if (canDelayKeyUp) Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); From ff601eefe6afaf6683af631f71361e05d644278a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 13:21:28 +0900 Subject: [PATCH 289/645] Fix failing test --- osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs index d42b61ea55..0c5ead10cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs @@ -17,6 +17,8 @@ namespace osu.Game.Tests.Visual.Gameplay { private bool exitAction; + protected override double TimePerAction => 100; // required for the early exit test, since hold-to-confirm delay is 200ms + [BackgroundDependencyLoader] private void load() { From d732d276b1186ce2108c2a5c88a6c2ec45907284 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 13:21:41 +0900 Subject: [PATCH 290/645] Make activation delay customisable --- .../Graphics/Containers/HoldToConfirmContainer.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs index 18a4241a79..773265d19b 100644 --- a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs +++ b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs @@ -12,9 +12,11 @@ namespace osu.Game.Graphics.Containers { public Action Action; - private const int activate_delay = 200; + private const int default_activation_delay = 200; private const int fadeout_delay = 200; + private readonly double activationDelay; + private bool fired; private bool confirming; @@ -25,13 +27,22 @@ namespace osu.Game.Graphics.Containers public Bindable Progress = new BindableDouble(); + /// + /// Create a new instance. + /// + /// The time requried before an action is confirmed. + protected HoldToConfirmContainer(double activationDelay = default_activation_delay) + { + this.activationDelay = activationDelay; + } + protected void BeginConfirm() { if (confirming || (!AllowMultipleFires && fired)) return; confirming = true; - this.TransformBindableTo(Progress, 1, activate_delay * (1 - Progress.Value), Easing.Out).OnComplete(_ => Confirm()); + this.TransformBindableTo(Progress, 1, activationDelay * (1 - Progress.Value), Easing.Out).OnComplete(_ => Confirm()); } protected virtual void Confirm() From 3949d46383b6adece23f0e43445ee92b3ff31585 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 13:46:08 +0900 Subject: [PATCH 291/645] Add test fix to other test --- .../Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs index a017418e3a..f787754aa4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs @@ -13,6 +13,8 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneHoldToConfirmOverlay : OsuTestScene { + protected override double TimePerAction => 100; // required for the early exit test, since hold-to-confirm delay is 200ms + public override IReadOnlyList RequiredTypes => new[] { typeof(ExitConfirmOverlay), From b2e05252d78c32b0e2711354bd9aac50797a2c95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 14:16:00 +0900 Subject: [PATCH 292/645] Update fastlane and dependencies --- Gemfile.lock | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 17c0db12e7..56e640599f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,7 +6,7 @@ GEM public_suffix (>= 2.0.2, < 4.0) atomos (0.1.3) babosa (1.0.2) - claide (1.0.2) + claide (1.0.3) colored (1.2) colored2 (3.1.2) commander-fastlane (4.4.6) @@ -14,11 +14,11 @@ GEM declarative (0.0.10) declarative-option (0.1.0) digest-crc (0.4.1) - domain_name (0.5.20180417) + domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.1) + dotenv (2.7.5) emoji_regex (1.0.1) - excon (0.62.0) + excon (0.66.0) faraday (0.15.4) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) @@ -27,7 +27,7 @@ GEM faraday_middleware (0.13.1) faraday (>= 0.7.4, < 1.0) fastimage (2.1.5) - fastlane (2.117.0) + fastlane (2.129.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) babosa (>= 1.0.2, < 2.0.0) @@ -46,8 +46,8 @@ GEM google-cloud-storage (>= 1.15.0, < 2.0.0) highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) - mini_magick (~> 4.5.1) - multi_json + jwt (~> 2.1.0) + mini_magick (>= 4.9.4, < 5.0.0) multi_xml (~> 0.5) multipart-post (~> 2.0.0) plist (>= 3.1.0, < 4.0.0) @@ -56,12 +56,12 @@ GEM security (= 0.1.3) simctl (~> 1.6.3) slack-notifier (>= 2.0.0, < 3.0.0) - terminal-notifier (>= 1.6.2, < 2.0.0) + terminal-notifier (>= 2.0.0, < 3.0.0) terminal-table (>= 1.4.5, < 2.0.0) tty-screen (>= 0.6.3, < 1.0.0) tty-spinner (>= 0.8.0, < 1.0.0) word_wrap (~> 1.0.0) - xcodeproj (>= 1.6.0, < 2.0.0) + xcodeproj (>= 1.8.1, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) fastlane-plugin-clean_testflight_testers (0.2.0) @@ -79,7 +79,7 @@ GEM signet (~> 0.9) google-cloud-core (1.3.0) google-cloud-env (~> 1.0) - google-cloud-env (1.0.5) + google-cloud-env (1.2.0) faraday (~> 0.11) google-cloud-storage (1.16.0) digest-crc (~> 0.4) @@ -102,8 +102,8 @@ GEM memoist (0.16.0) mime-types (3.2.2) mime-types-data (~> 3.2015) - mime-types-data (3.2018.0812) - mini_magick (4.5.1) + mime-types-data (3.2019.0331) + mini_magick (4.9.5) mini_portile2 (2.4.0) multi_json (1.13.1) multi_xml (0.6.0) @@ -112,7 +112,7 @@ GEM naturally (2.2.0) nokogiri (1.10.1) mini_portile2 (~> 2.4.0) - os (1.0.0) + os (1.0.1) plist (3.5.0) public_suffix (2.0.5) representable (3.0.4) @@ -121,7 +121,7 @@ GEM uber (< 0.2.0) retriable (3.1.2) rouge (2.0.7) - rubyzip (1.2.2) + rubyzip (1.2.3) security (0.1.3) signet (0.11.0) addressable (~> 2.3) @@ -136,20 +136,20 @@ GEM fastlane (>= 2.29.0) highline (~> 1.7) nokogiri (~> 1.7) - terminal-notifier (1.8.0) + terminal-notifier (2.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - tty-cursor (0.6.1) - tty-screen (0.6.5) - tty-spinner (0.9.0) - tty-cursor (~> 0.6.0) + tty-cursor (0.7.0) + tty-screen (0.7.0) + tty-spinner (0.9.1) + tty-cursor (~> 0.7) uber (0.1.0) unf (0.1.4) unf_ext - unf_ext (0.0.7.5) - unicode-display_width (1.4.1) + unf_ext (0.0.7.6) + unicode-display_width (1.6.0) word_wrap (1.0.0) - xcodeproj (1.8.1) + xcodeproj (1.12.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) From 7843b9c532bea4e80934a4da675e37f18d68ab68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 15:44:17 +0900 Subject: [PATCH 293/645] Update fastlane plugins --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 56e640599f..f7c19064b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -64,7 +64,7 @@ GEM xcodeproj (>= 1.8.1, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) - fastlane-plugin-clean_testflight_testers (0.2.0) + fastlane-plugin-clean_testflight_testers (0.3.0) fastlane-plugin-souyuz (0.8.1) souyuz (>= 0.8.1) fastlane-plugin-xamarin (0.6.3) @@ -110,7 +110,7 @@ GEM multipart-post (2.0.0) nanaimo (0.2.6) naturally (2.2.0) - nokogiri (1.10.1) + nokogiri (1.10.4) mini_portile2 (~> 2.4.0) os (1.0.1) plist (3.5.0) From 3c208b709bfdfd9432ab67a695da5503deee83a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 15:44:38 +0900 Subject: [PATCH 294/645] Reorder functions in Fastfile for readability --- fastlane/Fastfile | 29 +++++++++++++---------------- fastlane/README.md | 30 +++++++++++++++--------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 48c16caf0f..0b60e28b0f 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,22 +1,6 @@ update_fastlane -default_platform(:ios) - platform :ios do - lane :testflight_prune_dry do - clean_testflight_testers(days_of_inactivity:45, dry_run: true) - end - - # Specify a custom number for what's "inactive" - lane :testflight_prune do - clean_testflight_testers(days_of_inactivity: 45) # 120 days, so about 4 months - end - - lane :update_version do |options| - options[:plist_path] = '../osu.iOS/Info.plist' - app_version(options) - end - desc 'Deploy to testflight' lane :beta do |options| update_version(options) @@ -62,4 +46,17 @@ platform :ios do match(options) end + + lane :update_version do |options| + options[:plist_path] = '../osu.iOS/Info.plist' + app_version(options) + end + + lane :testflight_prune_dry do + clean_testflight_testers(days_of_inactivity:45, dry_run: true) + end + + lane :testflight_prune do + clean_testflight_testers(days_of_inactivity: 45) + end end diff --git a/fastlane/README.md b/fastlane/README.md index 53bbc62cae..fbccf1c8c0 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -16,21 +16,6 @@ or alternatively using `brew cask install fastlane` # Available Actions ## iOS -### ios testflight_prune_dry -``` -fastlane ios testflight_prune_dry -``` - -### ios testflight_prune -``` -fastlane ios testflight_prune -``` - -### ios update_version -``` -fastlane ios update_version -``` - ### ios beta ``` fastlane ios beta @@ -46,6 +31,21 @@ Compile the project fastlane ios provision ``` Install provisioning profiles using match +### ios update_version +``` +fastlane ios update_version +``` + +### ios testflight_prune_dry +``` +fastlane ios testflight_prune_dry +``` + +### ios testflight_prune +``` +fastlane ios testflight_prune +``` + ---- From 536e7d875736de01a5b574259fcdd8085c37aa60 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 19:32:17 +0900 Subject: [PATCH 295/645] 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 7bc60ef884..bb283dc0c5 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f5e4d4b1fb..758c4dda4c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 63fa354418..d6ad35b663 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,8 +118,8 @@ - - + + From 24d2b504dd4ce36f2e128a28075444f69860de73 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Fri, 16 Aug 2019 12:39:54 +0200 Subject: [PATCH 296/645] Stop autoplay from missing on very dense notes when playing mania --- .../Replays/ManiaAutoGenerator.cs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index e5669816fa..49bb47cc2b 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Replays; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; @@ -77,10 +78,35 @@ namespace osu.Game.Rulesets.Mania.Replays private IEnumerable generateActionPoints() { - foreach (var obj in Beatmap.HitObjects) + for (int i = 0; i < Beatmap.HitObjects.Count; i++) { - yield return new HitPoint { Time = obj.StartTime, Column = obj.Column }; - yield return new ReleasePoint { Time = ((obj as IHasEndTime)?.EndTime ?? obj.StartTime) + RELEASE_DELAY, Column = obj.Column }; + var currentObject = Beatmap.HitObjects[i]; + + double endTime = (currentObject as IHasEndTime)?.EndTime ?? currentObject.StartTime; + + var nextObjectInTheSameColumn = getNextObjectInTheSameColumn(i); + + bool canDelayKeyUp = nextObjectInTheSameColumn == null || + nextObjectInTheSameColumn.StartTime > endTime + KEY_UP_DELAY; + + double releaseDelay = canDelayKeyUp ? RELEASE_DELAY : nextObjectInTheSameColumn.StartTime - endTime - 1; + + yield return new HitPoint { Time = currentObject.StartTime, Column = currentObject.Column }; + + yield return new ReleasePoint { Time = endTime + releaseDelay, Column = currentObject.Column }; + } + + ManiaHitObject getNextObjectInTheSameColumn(int currentIndex) + { + int desiredColumn = Beatmap.HitObjects[currentIndex++].Column; + + for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) + { + if (Beatmap.HitObjects[currentIndex].Column == desiredColumn) + return Beatmap.HitObjects[currentIndex]; + } + + return null; } } From 132d51a2cc7ff16b0f35227fa03cb97efee60088 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 19:47:35 +0900 Subject: [PATCH 297/645] Update tooltip implementation --- .../Profile/Header/Components/RankGraph.cs | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 9cb9d48de7..de760eedfd 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -196,17 +196,30 @@ namespace osu.Game.Overlays.Profile.Header.Components } } - public string TooltipText => Statistics.Value?.Ranks.Global == null ? "" : $"#{ranks[dayIndex].Value:#,##0}|{ranked_days - ranks[dayIndex].Key + 1}"; + public object TooltipContent + { + get + { + if (Statistics.Value?.Ranks.Global == null) + return null; + + var days = ranked_days - ranks[dayIndex].Key + 1; + + return new TooltipDisplayContent + { + Rank = $"#{ranks[dayIndex].Value:#,##0}", + Time = days == 0 ? "now" : $"{days} days ago" + }; + } + } public ITooltip GetCustomTooltip() => new RankGraphTooltip(); - public class RankGraphTooltip : VisibilityContainer, ITooltip + private class RankGraphTooltip : VisibilityContainer, ITooltip { private readonly OsuSpriteText globalRankingText, timeText; private readonly Box background; - public string TooltipText { get; set; } - public RankGraphTooltip() { AutoSizeAxes = Axes.Both; @@ -260,11 +273,14 @@ namespace osu.Game.Overlays.Profile.Header.Components background.Colour = colours.GreySeafoamDark; } - public void Refresh() + public bool SetContent(object content) { - var info = TooltipText.Split('|'); - globalRankingText.Text = info[0]; - timeText.Text = info[1] == "0" ? "now" : $"{info[1]} days ago"; + if (!(content is TooltipDisplayContent info)) + return false; + + globalRankingText.Text = info.Rank; + timeText.Text = info.Time; + return true; } private bool instantMove = true; @@ -280,9 +296,24 @@ namespace osu.Game.Overlays.Profile.Header.Components this.MoveTo(pos, 200, Easing.OutQuint); } + public void Refresh() + { + } + + public string TooltipText + { + set => throw new InvalidOperationException(); + } + protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); } + + private class TooltipDisplayContent + { + public string Rank; + public string Time; + } } } From 7de1757aae1bae0baf006a010cd3be4eb172da62 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Fri, 16 Aug 2019 12:50:48 +0200 Subject: [PATCH 298/645] Small improvements --- osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 49bb47cc2b..4fea834748 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -81,19 +81,18 @@ namespace osu.Game.Rulesets.Mania.Replays for (int i = 0; i < Beatmap.HitObjects.Count; i++) { var currentObject = Beatmap.HitObjects[i]; + var nextObjectInTheSameColumn = getNextObjectInTheSameColumn(i); double endTime = (currentObject as IHasEndTime)?.EndTime ?? currentObject.StartTime; - var nextObjectInTheSameColumn = getNextObjectInTheSameColumn(i); - bool canDelayKeyUp = nextObjectInTheSameColumn == null || nextObjectInTheSameColumn.StartTime > endTime + KEY_UP_DELAY; - double releaseDelay = canDelayKeyUp ? RELEASE_DELAY : nextObjectInTheSameColumn.StartTime - endTime - 1; + double calculatedDelay = canDelayKeyUp ? RELEASE_DELAY : (nextObjectInTheSameColumn.StartTime - endTime) * 0.9; yield return new HitPoint { Time = currentObject.StartTime, Column = currentObject.Column }; - yield return new ReleasePoint { Time = endTime + releaseDelay, Column = currentObject.Column }; + yield return new ReleasePoint { Time = endTime + calculatedDelay, Column = currentObject.Column }; } ManiaHitObject getNextObjectInTheSameColumn(int currentIndex) From 58d2268b9e6da29b4208ab7d4bf8e0e9c96ab0a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 19:52:35 +0900 Subject: [PATCH 299/645] Combine conditionals that provide the same behaviour --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 7c143aa158..66ba6f7e64 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -118,9 +118,6 @@ namespace osu.Game.Rulesets.UI try { - if (!FrameStablePlayback) - manualClock.CurrentTime = newProposedTime; - if (firstConsumption) { // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour. @@ -141,7 +138,7 @@ namespace osu.Game.Rulesets.UI : Math.Max(newProposedTime, manualClock.CurrentTime - sixty_frame_time); } - if (!isAttached) + if (!isAttached || !FrameStablePlayback) { manualClock.CurrentTime = newProposedTime; } From d11b896148508b3e1555982c64ee44ed20b4ff29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 20:21:00 +0900 Subject: [PATCH 300/645] Move FrameStablePlayback handling to early return --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 66ba6f7e64..25fe5cdd96 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -118,7 +118,14 @@ namespace osu.Game.Rulesets.UI try { - if (firstConsumption) + if (!FrameStablePlayback) + { + manualClock.CurrentTime = newProposedTime; + requireMoreUpdateLoops = false; + return; + } + + else if (firstConsumption) { // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour. // Instead we perform an initial seek to the proposed time. @@ -138,7 +145,7 @@ namespace osu.Game.Rulesets.UI : Math.Max(newProposedTime, manualClock.CurrentTime - sixty_frame_time); } - if (!isAttached || !FrameStablePlayback) + if (!isAttached) { manualClock.CurrentTime = newProposedTime; } From 152df9f3d570ee36d05a088c2bbe6d88c3e4a033 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Aug 2019 20:23:09 +0900 Subject: [PATCH 301/645] Remove accidental blank line --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 25fe5cdd96..05d3c02381 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -124,7 +124,6 @@ namespace osu.Game.Rulesets.UI requireMoreUpdateLoops = false; return; } - else if (firstConsumption) { // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour. From 0f9706e7985428f1273fd23a9b0e3925dbf1f357 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Sat, 17 Aug 2019 00:18:25 +0200 Subject: [PATCH 302/645] Fix using invalid constant --- osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 4fea834748..43150958d0 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Replays double endTime = (currentObject as IHasEndTime)?.EndTime ?? currentObject.StartTime; bool canDelayKeyUp = nextObjectInTheSameColumn == null || - nextObjectInTheSameColumn.StartTime > endTime + KEY_UP_DELAY; + nextObjectInTheSameColumn.StartTime > endTime + RELEASE_DELAY; double calculatedDelay = canDelayKeyUp ? RELEASE_DELAY : (nextObjectInTheSameColumn.StartTime - endTime) * 0.9; From 4fa9abeecec9540da8b24faee553fd482006379d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 17 Aug 2019 15:16:24 +0900 Subject: [PATCH 303/645] Replace DifficultyColouredContainer with a more scalable solution --- osu.Game/Beatmaps/BeatmapInfo.cs | 16 ++++ osu.Game/Beatmaps/DifficultyRating.cs | 15 ++++ .../Drawables/DifficultyColouredContainer.cs | 85 ------------------- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 11 ++- osu.Game/Graphics/OsuColour.cs | 26 ++++++ osu.Game/Screens/Select/BeatmapInfoWedge.cs | 14 +-- 6 files changed, 73 insertions(+), 94 deletions(-) create mode 100644 osu.Game/Beatmaps/DifficultyRating.cs delete mode 100644 osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 8042f6b4b9..700f981088 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -129,6 +129,22 @@ namespace osu.Game.Beatmaps ///
    diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs new file mode 100644 index 0000000000..87d6012205 --- /dev/null +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -0,0 +1,413 @@ +// 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.IO; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; +using osu.Framework.Bindables; +using osu.Framework.Screens; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Video; +using osu.Framework.MathUtils; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.IO.Archives; +using osu.Game.Rulesets; +using osu.Game.Screens.Backgrounds; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Menu +{ + public class IntroTriangles : IntroScreen + { + private const string menu_music_beatmap_hash = "a1556d0801b3a6b175dda32ef546f0ec812b400499f575c44fccbe9c67f9b1e5"; + + private SampleChannel welcome; + + protected override BackgroundScreen CreateBackground() => background = new BackgroundScreenDefault(false) + { + Alpha = 0, + }; + + [Resolved] + private AudioManager audio { get; set; } + + private Bindable menuMusic; + private Track track; + private WorkingBeatmap introBeatmap; + + private BackgroundScreenDefault background; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) + { + menuMusic = config.GetBindable(OsuSetting.MenuMusic); + + BeatmapSetInfo setInfo = null; + + if (!menuMusic.Value) + { + var sets = beatmaps.GetAllUsableBeatmapSets(); + if (sets.Count > 0) + setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID); + } + + if (setInfo == null) + { + setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == menu_music_beatmap_hash); + + if (setInfo == null) + { + // we need to import the default menu background beatmap + setInfo = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream(@"Tracks/triangles.osz"), "triangles.osz")).Result; + + setInfo.Protected = true; + beatmaps.Update(setInfo); + } + } + + introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); + + track = introBeatmap.Track; + track.Reset(); + + if (config.Get(OsuSetting.MenuVoice) && !menuMusic.Value) + // triangles has welcome sound included in the track. only play this if the user doesn't want menu music. + welcome = audio.Samples.Get(@"welcome"); + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + base.LogoArriving(logo, resuming); + + logo.Triangles = true; + + if (!resuming) + { + Beatmap.Value = introBeatmap; + introBeatmap = null; + + PrepareMenuLoad(); + + LoadComponentAsync(new TrianglesIntroSequence(logo, background) + { + RelativeSizeAxes = Axes.Both, + Clock = new FramedClock(track), + LoadMenu = LoadMenu + }, t => + { + AddInternal(t); + welcome?.Play(); + + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + if (menuMusic.Value) + track.Start(); + }); + } + } + + public override void OnResuming(IScreen last) + { + base.OnResuming(last); + background.FadeOut(100); + } + + public override void OnSuspending(IScreen next) + { + track = null; + base.OnSuspending(next); + } + + private class TrianglesIntroSequence : CompositeDrawable + { + private readonly OsuLogo logo; + private readonly BackgroundScreenDefault background; + private OsuSpriteText welcomeText; + + private RulesetFlow rulesets; + private Container rulesetsScale; + private Drawable logoContainerSecondary; + private Drawable logoContainer; + + private GlitchingTriangles triangles; + + public Action LoadMenu; + + public TrianglesIntroSequence(OsuLogo logo, BackgroundScreenDefault background) + { + this.logo = logo; + this.background = background; + } + + private OsuGameBase game; + + [BackgroundDependencyLoader] + private void load(TextureStore textures, OsuGameBase game) + { + this.game = game; + + InternalChildren = new[] + { + triangles = new GlitchingTriangles + { + Alpha = 0, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0.4f, 0.16f) + }, + welcomeText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Padding = new MarginPadding { Bottom = 10 }, + Font = OsuFont.GetFont(weight: FontWeight.Light, size: 42), + Alpha = 1, + Spacing = new Vector2(5), + }, + rulesetsScale = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + rulesets = new RulesetFlow() + } + }, + logoContainerSecondary = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = logoContainer = new LazerLogo(textures.GetStream("Menu/logo-triangles.mp4")) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, + }; + } + + private const double text_1 = 200; + private const double text_2 = 400; + private const double text_3 = 700; + private const double text_4 = 900; + private const double text_glitch = 1060; + + private const double rulesets_1 = 1450; + private const double rulesets_2 = 1650; + private const double rulesets_3 = 1850; + + private const double logo_scale_duration = 920; + private const double logo_1 = 2080; + private const double logo_2 = logo_1 + logo_scale_duration; + + protected override void LoadComplete() + { + base.LoadComplete(); + + const float scale_start = 1.2f; + const float scale_adjust = 0.8f; + + rulesets.Hide(); + logoContainer.Hide(); + background.Hide(); + + using (BeginAbsoluteSequence(0, true)) + { + using (BeginDelayedSequence(text_1, true)) + welcomeText.FadeIn().OnComplete(t => t.Text = "wel"); + + using (BeginDelayedSequence(text_2, true)) + welcomeText.FadeIn().OnComplete(t => t.Text = "welcome"); + + using (BeginDelayedSequence(text_3, true)) + welcomeText.FadeIn().OnComplete(t => t.Text = "welcome to"); + + using (BeginDelayedSequence(text_4, true)) + { + welcomeText.FadeIn().OnComplete(t => t.Text = "welcome to osu!"); + welcomeText.TransformTo(nameof(welcomeText.Spacing), new Vector2(50, 0), 5000); + } + + using (BeginDelayedSequence(text_glitch, true)) + triangles.FadeIn(); + + using (BeginDelayedSequence(rulesets_1, true)) + { + rulesetsScale.ScaleTo(0.8f, 1000); + rulesets.FadeIn().ScaleTo(1).TransformSpacingTo(new Vector2(200, 0)); + welcomeText.FadeOut(); + triangles.FadeOut(); + } + + using (BeginDelayedSequence(rulesets_2, true)) + { + rulesets.ScaleTo(2).TransformSpacingTo(new Vector2(30, 0)); + } + + using (BeginDelayedSequence(rulesets_3, true)) + { + rulesets.ScaleTo(4).TransformSpacingTo(new Vector2(10, 0)); + rulesetsScale.ScaleTo(1.3f, 1000); + } + + using (BeginDelayedSequence(logo_1, true)) + { + rulesets.FadeOut(); + + // matching flyte curve y = 0.25x^2 + (max(0, x - 0.7) / 0.3) ^ 5 + logoContainer.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint); + logoContainerSecondary.ScaleTo(scale_start).Then().ScaleTo(scale_start - scale_adjust * 0.25f, logo_scale_duration, Easing.InQuad); + } + + using (BeginDelayedSequence(logo_2, true)) + { + logoContainer.FadeOut().OnComplete(_ => + { + logo.FadeIn(); + background.FadeIn(); + + game.Add(new GameWideFlash()); + + LoadMenu(); + }); + } + } + } + + private class GameWideFlash : Box + { + private const double flash_length = 1000; + + public GameWideFlash() + { + Colour = Color4.White; + RelativeSizeAxes = Axes.Both; + Blending = BlendingMode.Additive; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeOutFromOne(flash_length, Easing.Out); + } + } + + private class LazerLogo : CompositeDrawable + { + public LazerLogo(Stream videoStream) + { + Size = new Vector2(960); + + InternalChild = new VideoSprite(videoStream) + { + RelativeSizeAxes = Axes.Both, + Clock = new FramedOffsetClock(Clock) { Offset = -logo_1 } + }; + } + } + + private class RulesetFlow : FillFlowContainer + { + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + var modes = new List(); + + foreach (var ruleset in rulesets.AvailableRulesets) + { + var icon = new ConstrainedIconContainer + { + Icon = ruleset.CreateInstance().CreateIcon(), + Size = new Vector2(30), + }; + + modes.Add(icon); + } + + AutoSizeAxes = Axes.Both; + Children = modes; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + } + + private class GlitchingTriangles : CompositeDrawable + { + public GlitchingTriangles() + { + RelativeSizeAxes = Axes.Both; + } + + private double? lastGenTime; + + private const double time_between_triangles = 22; + + protected override void Update() + { + base.Update(); + + if (lastGenTime == null || Time.Current - lastGenTime > time_between_triangles) + { + lastGenTime = (lastGenTime ?? Time.Current) + time_between_triangles; + + Drawable triangle = new OutlineTriangle(RNG.NextBool(), (RNG.NextSingle() + 0.2f) * 80) + { + RelativePositionAxes = Axes.Both, + Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), + }; + + AddInternal(triangle); + + triangle.FadeOutFromOne(120); + } + } + + /// + /// Represents a sprite that is drawn in a triangle shape, instead of a rectangle shape. + /// + public class OutlineTriangle : BufferedContainer + { + public OutlineTriangle(bool outlineOnly, float size) + { + Size = new Vector2(size); + + InternalChildren = new Drawable[] + { + new Triangle { RelativeSizeAxes = Axes.Both }, + }; + + if (outlineOnly) + { + AddInternal(new Triangle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Color4.Black, + Size = new Vector2(size - 5), + Blending = BlendingMode.None, + }); + } + + Blending = BlendingMode.Additive; + CacheDrawnFrameBuffer = true; + } + } + } + } + } +} From 8e6a3162ab3bfead6842379973fd671f927e39c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 20:05:36 +0900 Subject: [PATCH 200/645] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 40c15a1162..4ec67ab30d 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -62,7 +62,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8ee325c2ac..fb9269e5f0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b46438f766..1532e2d71b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - + From 6264a6a1c95b9b3c924e2ace2b4f8ff0594862f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 20:18:02 +0900 Subject: [PATCH 201/645] Adjust slider snaking and hitcircle fading to match stable --- .../Objects/Drawables/Pieces/SnakingSliderBody.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs index 0590ca1d96..70a1bad4a3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var spanProgress = slider.ProgressAt(completionProgress); double start = 0; - double end = SnakingIn.Value ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadeIn, 0, 1) : 1; + double end = SnakingIn.Value ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / (slider.TimePreempt / 3), 0, 1) : 1; if (span >= slider.SpanCount() - 1) { diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index d1221fd2d3..b52bfcd181 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Objects base.ApplyDefaultsToSelf(controlPointInfo, difficulty); TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); - TimeFadeIn = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300); + TimeFadeIn = 400; // as per osu-stable Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } From 7dd62ae6f350211cb09bd7b58afc4adf2f83e80b Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 9 Aug 2019 20:48:08 +0930 Subject: [PATCH 202/645] Remove Android BASS libraries --- osu.Android.props | 4 +--- osu.Android/lib/arm64-v8a/libbass.so | Bin 308904 -> 0 bytes osu.Android/lib/arm64-v8a/libbass_fx.so | Bin 154408 -> 0 bytes osu.Android/lib/armeabi-v7a/libbass.so | Bin 222620 -> 0 bytes osu.Android/lib/armeabi-v7a/libbass_fx.so | Bin 92176 -> 0 bytes osu.Android/lib/x86/libbass.so | Bin 316716 -> 0 bytes osu.Android/lib/x86/libbass_fx.so | Bin 153532 -> 0 bytes 7 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 osu.Android/lib/arm64-v8a/libbass.so delete mode 100644 osu.Android/lib/arm64-v8a/libbass_fx.so delete mode 100644 osu.Android/lib/armeabi-v7a/libbass.so delete mode 100644 osu.Android/lib/armeabi-v7a/libbass_fx.so delete mode 100644 osu.Android/lib/x86/libbass.so delete mode 100644 osu.Android/lib/x86/libbass_fx.so diff --git a/osu.Android.props b/osu.Android.props index 40c15a1162..82d8696ca5 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -49,9 +49,7 @@ osu.licenseheader - - Always - + diff --git a/osu.Android/lib/arm64-v8a/libbass.so b/osu.Android/lib/arm64-v8a/libbass.so deleted file mode 100644 index d5c24b3e4b2918a33153cf6a0561366996be16f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308904 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

    ^m>m@_QI`Gyr3D`HGSXQzB#7TNkp#fsh! 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%0A0ic&Bx^ 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 T?MJo0F6IAiepbA(NM`E) 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 z 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 EAM_!vo&W#< diff --git a/osu.Android/lib/armeabi-v7a/libbass_fx.so b/osu.Android/lib/armeabi-v7a/libbass_fx.so deleted file mode 100644 index 006e2feb30bb005eec727f829cc3965fb136f16c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92176 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 V>7s+MhuN$Sd><=0>Ypgz{{j9{WcmOA diff --git a/osu.Android/lib/x86/libbass.so b/osu.Android/lib/x86/libbass.so deleted file mode 100644 index b0f758a42b7397b3289557f51de6b55df7b3b4ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 316716 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 z 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 kkiFcJ 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 E0opfv^#A|> From caf13ae52ddbf06fbf11fe3c711e1fb304f8915f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 23:29:32 +0900 Subject: [PATCH 203/645] 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 40c15a1162..3b2e6574ac 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -63,6 +63,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8ee325c2ac..1dd19ac7ed 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b46438f766..1c3faeed39 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From fc4c0cc2e72d9108881cba86f1854110ee17549e Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 10:52:37 +0200 Subject: [PATCH 204/645] Fix visual discrepancies with master --- osu.Game/Overlays/OSD/Toast.cs | 1 + osu.Game/Overlays/OSD/TrackedSettingToast.cs | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index 67c9b46c77..db5e6e4a6a 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -65,6 +65,7 @@ namespace osu.Game.Overlays.OSD Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, Name = "Shortcut", + Alpha = 0.3f, Margin = new MarginPadding { Bottom = 15 }, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Text = string.IsNullOrEmpty(keybinding) ? "NO KEY BOUND" : keybinding.ToUpperInvariant() diff --git a/osu.Game/Overlays/OSD/TrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs index 9812dcd797..0f4bd34779 100644 --- a/osu.Game/Overlays/OSD/TrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -17,6 +17,8 @@ namespace osu.Game.Overlays.OSD { public class TrackedSettingToast : Toast { + private const int lights_bottom_margin = 40; + public TrackedSettingToast(SettingDescription description) : base(description.Name, description.Value, description.Shortcut) { @@ -24,17 +26,16 @@ namespace osu.Game.Overlays.OSD Children = new Drawable[] { - new FillFlowContainer + new Container { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Direction = FillDirection.Vertical, - Margin = new MarginPadding { Top = 70 }, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Margin = new MarginPadding { Bottom = lights_bottom_margin }, Children = new Drawable[] { optionLights = new FillFlowContainer { - Padding = new MarginPadding { Bottom = 5 }, + Margin = new MarginPadding { Bottom = 5 }, Spacing = new Vector2(5, 0), Direction = FillDirection.Horizontal, Anchor = Anchor.TopCentre, From b0a71779877c55e6b181e8e50207de80ff79e96a Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 13:26:19 +0200 Subject: [PATCH 205/645] Add ScreenTitleIcon class, used for displaying custom specific icons on overlays. --- .../Graphics/UserInterface/ScreenTitle.cs | 2 +- .../Graphics/UserInterface/ScreenTitleIcon.cs | 61 +++++++++++++++++++ .../Overlays/Changelog/ChangelogHeader.cs | 45 +------------- 3 files changed, 63 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs diff --git a/osu.Game/Graphics/UserInterface/ScreenTitle.cs b/osu.Game/Graphics/UserInterface/ScreenTitle.cs index 7b39238e5e..10fc312d8b 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitle.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitle.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface { public const float ICON_WIDTH = ICON_SIZE + icon_spacing; - protected const float ICON_SIZE = 25; + public const float ICON_SIZE = 25; private SpriteIcon iconSprite; private readonly OsuSpriteText titleText, pageText; diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs new file mode 100644 index 0000000000..12e0617e35 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs @@ -0,0 +1,61 @@ +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osuTK; + +namespace osu.Game.Graphics.UserInterface +{ + ///

    + /// A custom icon class for use with + /// + public class ScreenTitleIcon : CompositeDrawable + { + private const float circle_allowance = 0.8f; + + private string icon; + + public ScreenTitleIcon(string icon) + { + this.icon = icon; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures, OsuColour colours) + { + Size = new Vector2(ScreenTitle.ICON_SIZE / circle_allowance); + + InternalChildren = new Drawable[] + { + new CircularContainer + { + Masking = true, + BorderColour = colours.Violet, + BorderThickness = 3, + MaskingSmoothness = 1, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(icon), + Size = new Vector2(circle_allowance), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Violet, + Alpha = 0, + AlwaysPresent = true, + }, + } + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index fca62fbb44..8b78216136 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -7,13 +7,11 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; -using osuTK; namespace osu.Game.Overlays.Changelog { @@ -123,48 +121,7 @@ namespace osu.Game.Overlays.Changelog AccentColour = colours.Violet; } - protected override Drawable CreateIcon() => new ChangelogIcon(); - - internal class ChangelogIcon : CompositeDrawable - { - private const float circle_allowance = 0.8f; - - [BackgroundDependencyLoader] - private void load(TextureStore textures, OsuColour colours) - { - Size = new Vector2(ICON_SIZE / circle_allowance); - - InternalChildren = new Drawable[] - { - new CircularContainer - { - Masking = true, - BorderColour = colours.Violet, - BorderThickness = 3, - MaskingSmoothness = 1, - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Sprite - { - RelativeSizeAxes = Axes.Both, - Texture = textures.Get(@"Icons/changelog"), - Size = new Vector2(circle_allowance), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Violet, - Alpha = 0, - AlwaysPresent = true, - }, - } - }, - }; - } - } + protected override Drawable CreateIcon() => new ScreenTitleIcon(@"Icons/changelog"); } } } From 8eb3409a648bb03ff702d2f66807e6c0e0c02c86 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 14:03:44 +0200 Subject: [PATCH 206/645] Add missing licence header --- osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs index 12e0617e35..8a42645b37 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From d55f9404dab5cd639d8f3524df9e97c31bf909f3 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 14:23:37 +0200 Subject: [PATCH 207/645] Fix CI issues --- osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs index 8a42645b37..4ce554009a 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface { private const float circle_allowance = 0.8f; - private string icon; + private readonly string icon; public ScreenTitleIcon(string icon) { From 7825923cb63f157e7e9fcd7307ae05b9d3d0b51d Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 16:33:16 +0200 Subject: [PATCH 208/645] Use media keys as default bindings for jukebox. --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 6 +++--- osu.Game/Overlays/MusicController.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 8c927c2bc6..809ec9a09e 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -45,9 +45,9 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Enter, GlobalAction.Select), new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select), - new KeyBinding(InputKey.F1, GlobalAction.MusicPrev), - new KeyBinding(InputKey.F5, GlobalAction.MusicNext), - new KeyBinding(InputKey.F3, GlobalAction.MusicPlay), + new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev), + new KeyBinding(InputKey.TrackNext, GlobalAction.MusicNext), + new KeyBinding(InputKey.PlayPause, GlobalAction.MusicPlay), }; public IEnumerable InGameKeyBindings => new[] diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 724be21957..ed51a80924 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -565,7 +565,7 @@ namespace osu.Game.Overlays { if (beatmap.Disabled) return false; - play(); + togglePause(); return true; } From 684c37bf05e8bc3367d5c48d4997a7e1bab75157 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 11 Aug 2019 16:15:44 +0900 Subject: [PATCH 209/645] Rename class to better match usage --- ...{ScreenTitleIcon.cs => ScreenTitleTextureIcon.cs} | 12 ++++++------ osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) rename osu.Game/Graphics/UserInterface/{ScreenTitleIcon.cs => ScreenTitleTextureIcon.cs} (85%) diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleTextureIcon.cs similarity index 85% rename from osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs rename to osu.Game/Graphics/UserInterface/ScreenTitleTextureIcon.cs index 4ce554009a..f590e7e357 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitleTextureIcon.cs @@ -12,17 +12,17 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { /// - /// A custom icon class for use with + /// A custom icon class for use with based off a texture resource. /// - public class ScreenTitleIcon : CompositeDrawable + public class ScreenTitleTextureIcon : CompositeDrawable { private const float circle_allowance = 0.8f; - private readonly string icon; + private readonly string textureName; - public ScreenTitleIcon(string icon) + public ScreenTitleTextureIcon(string textureName) { - this.icon = icon; + this.textureName = textureName; } [BackgroundDependencyLoader] @@ -44,7 +44,7 @@ namespace osu.Game.Graphics.UserInterface new Sprite { RelativeSizeAxes = Axes.Both, - Texture = textures.Get(icon), + Texture = textures.Get(textureName), Size = new Vector2(circle_allowance), Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 8b78216136..b2e9be24b3 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.Changelog AccentColour = colours.Violet; } - protected override Drawable CreateIcon() => new ScreenTitleIcon(@"Icons/changelog"); + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog"); } } } From fd334e0319729576afb81d600b71128f1fff2970 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 14:57:21 +0300 Subject: [PATCH 210/645] Implement basic layout for AccuracyBar --- osu.Game/Screens/Play/HUD/AccuracyBar.cs | 19 +++++++++++++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/AccuracyBar.cs diff --git a/osu.Game/Screens/Play/HUD/AccuracyBar.cs b/osu.Game/Screens/Play/HUD/AccuracyBar.cs new file mode 100644 index 0000000000..8b85014b2f --- /dev/null +++ b/osu.Game/Screens/Play/HUD/AccuracyBar.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.Graphics.Containers; +using osu.Game.Rulesets.Judgements; + +namespace osu.Game.Screens.Play.HUD +{ + public class AccuracyBar : Container + { + public AccuracyBar(bool mirrored) + { + } + + public void OnNewJudgement(JudgementResult judgement) + { + } + } +} diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 43b9491750..88ad57c175 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -35,6 +35,8 @@ namespace osu.Game.Screens.Play public readonly ModDisplay ModDisplay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; + public readonly AccuracyBar LeftAccuracyBar; + public readonly AccuracyBar RightAccuracyBar; public Bindable ShowHealthbar = new Bindable(true); @@ -84,6 +86,8 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), + LeftAccuracyBar = CreateAccuracyBar(false), + RightAccuracyBar = CreateAccuracyBar(), } }, PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), @@ -256,6 +260,15 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; + protected virtual AccuracyBar CreateAccuracyBar(bool mirrored = true) => new AccuracyBar(mirrored) + { + Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, + AutoSizeAxes = Axes.X, + Height = 300, + Margin = new MarginPadding { Horizontal = 20 } + }; + protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); protected virtual void BindProcessor(ScoreProcessor processor) @@ -265,6 +278,12 @@ namespace osu.Game.Screens.Play ComboCounter?.Current.BindTo(processor.Combo); HealthDisplay?.Current.BindTo(processor.Health); + if (LeftAccuracyBar != null) + processor.NewJudgement += LeftAccuracyBar.OnNewJudgement; + + if (RightAccuracyBar != null) + processor.NewJudgement += RightAccuracyBar.OnNewJudgement; + if (HealthDisplay is StandardHealthDisplay shd) processor.NewJudgement += shd.Flash; } From ed409d113b2e02bc49c252c4074468393bc6a8ae Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 15:53:15 +0300 Subject: [PATCH 211/645] Add judgement lines generator --- osu.Game/Screens/Play/HUD/AccuracyBar.cs | 42 +++++++++++++++++++++++- osu.Game/Screens/Play/HUDOverlay.cs | 4 +-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/AccuracyBar.cs b/osu.Game/Screens/Play/HUD/AccuracyBar.cs index 8b85014b2f..8b14bc47eb 100644 --- a/osu.Game/Screens/Play/HUD/AccuracyBar.cs +++ b/osu.Game/Screens/Play/HUD/AccuracyBar.cs @@ -1,19 +1,59 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Judgements; +using osuTK.Graphics; +using osuTK; namespace osu.Game.Screens.Play.HUD { public class AccuracyBar : Container { - public AccuracyBar(bool mirrored) + private const int bar_width = 5; + private const int bar_height = 250; + private const int spacing = 3; + + private readonly bool mirrored; + + public AccuracyBar(bool mirrored = false) { + this.mirrored = mirrored; + + Size = new Vector2(bar_width, bar_height); + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }; } public void OnNewJudgement(JudgementResult judgement) { + Container judgementLine; + + Add(judgementLine = CreateJudgementLine(judgement.TimeOffset)); + + judgementLine.FadeOut(5000, Easing.OutQuint); + judgementLine.Expire(); } + + protected virtual Container CreateJudgementLine(double offset) => new CircularContainer + { + Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = mirrored ? Anchor.CentreLeft : Anchor.CentreRight, + Masking = true, + Size = new Vector2(10, 2), + RelativePositionAxes = Axes.Y, + Y = (float)offset / bar_height, + X = mirrored ? spacing : -spacing, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + } + }; } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 88ad57c175..3fafc21ea8 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -264,9 +264,7 @@ namespace osu.Game.Screens.Play { Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, Origin = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, - AutoSizeAxes = Axes.X, - Height = 300, - Margin = new MarginPadding { Horizontal = 20 } + Margin = new MarginPadding { Horizontal = 30 } }; protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From 0a255fe4d1750440e02fc429f40021f7df9b55c8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 16:38:03 +0300 Subject: [PATCH 212/645] Add moving arrow --- osu.Game/Screens/Play/HUD/AccuracyBar.cs | 46 ++++++++++++++++++++---- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/AccuracyBar.cs b/osu.Game/Screens/Play/HUD/AccuracyBar.cs index 8b14bc47eb..3c13111b22 100644 --- a/osu.Game/Screens/Play/HUD/AccuracyBar.cs +++ b/osu.Game/Screens/Play/HUD/AccuracyBar.cs @@ -7,6 +7,8 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Judgements; using osuTK.Graphics; using osuTK; +using osu.Framework.Graphics.Sprites; +using System.Collections.Generic; namespace osu.Game.Screens.Play.HUD { @@ -17,16 +19,31 @@ namespace osu.Game.Screens.Play.HUD private const int spacing = 3; private readonly bool mirrored; + private readonly SpriteIcon arrow; + private readonly List judgementOffsets = new List(); public AccuracyBar(bool mirrored = false) { this.mirrored = mirrored; Size = new Vector2(bar_width, bar_height); - Child = new Box + + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + arrow = new SpriteIcon + { + Anchor = mirrored ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, + X = mirrored ? -spacing : spacing, + RelativePositionAxes = Axes.Y, + Icon = mirrored ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, + Size = new Vector2(10), + } }; } @@ -34,20 +51,22 @@ namespace osu.Game.Screens.Play.HUD { Container judgementLine; - Add(judgementLine = CreateJudgementLine(judgement.TimeOffset)); + Add(judgementLine = CreateJudgementLine(judgement)); judgementLine.FadeOut(5000, Easing.OutQuint); judgementLine.Expire(); + + arrow.MoveToY(calculateArrowPosition(judgement) / bar_height, 500, Easing.OutQuint); } - protected virtual Container CreateJudgementLine(double offset) => new CircularContainer + protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer { Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, Origin = mirrored ? Anchor.CentreLeft : Anchor.CentreRight, Masking = true, Size = new Vector2(10, 2), RelativePositionAxes = Axes.Y, - Y = (float)offset / bar_height, + Y = (float)judgement.TimeOffset / bar_height, X = mirrored ? spacing : -spacing, Child = new Box { @@ -55,5 +74,20 @@ namespace osu.Game.Screens.Play.HUD Colour = Color4.White, } }; + + private float calculateArrowPosition(JudgementResult judgement) + { + if (judgementOffsets.Count > 5) + judgementOffsets.RemoveAt(0); + + judgementOffsets.Add(judgement.TimeOffset); + + double offsets = 0; + + foreach (var offset in judgementOffsets) + offsets += offset; + + return (float)offsets / judgementOffsets.Count; + } } } From cc4ee2df0591301b420675255a28e0612862654f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 11 Aug 2019 16:41:56 +0200 Subject: [PATCH 213/645] add ToString() override to Beatmap class --- osu.Game/Beatmaps/Beatmap.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 4ebeee40bf..6079a112e6 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -60,5 +60,7 @@ namespace osu.Game.Beatmaps public class Beatmap : Beatmap { public new Beatmap Clone() => (Beatmap)base.Clone(); + + public override string ToString() => BeatmapInfo?.ToString(); } } From 2a35c3c3e24708ef174f5482250d4de773ccb6d9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 18:04:54 +0300 Subject: [PATCH 214/645] Calculate real position for judgement lines --- osu.Game/Screens/Play/HUD/AccuracyBar.cs | 25 ++++++++++++++++++++---- osu.Game/Screens/Play/HUDOverlay.cs | 6 ++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/AccuracyBar.cs b/osu.Game/Screens/Play/HUD/AccuracyBar.cs index 3c13111b22..590e9ca4d9 100644 --- a/osu.Game/Screens/Play/HUD/AccuracyBar.cs +++ b/osu.Game/Screens/Play/HUD/AccuracyBar.cs @@ -9,6 +9,10 @@ using osuTK.Graphics; using osuTK; using osu.Framework.Graphics.Sprites; using System.Collections.Generic; +using osu.Game.Rulesets.Objects; +using osu.Game.Beatmaps; +using osu.Framework.Bindables; +using osu.Framework.Allocation; namespace osu.Game.Screens.Play.HUD { @@ -18,6 +22,11 @@ namespace osu.Game.Screens.Play.HUD private const int bar_height = 250; private const int spacing = 3; + public HitWindows HitWindows { get; set; } + + [Resolved] + private Bindable beatmap { get; set; } + private readonly bool mirrored; private readonly SpriteIcon arrow; private readonly List judgementOffsets = new List(); @@ -47,6 +56,12 @@ namespace osu.Game.Screens.Play.HUD }; } + protected override void LoadComplete() + { + base.LoadComplete(); + HitWindows.SetDifficulty(beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); + } + public void OnNewJudgement(JudgementResult judgement) { Container judgementLine; @@ -56,7 +71,7 @@ namespace osu.Game.Screens.Play.HUD judgementLine.FadeOut(5000, Easing.OutQuint); judgementLine.Expire(); - arrow.MoveToY(calculateArrowPosition(judgement) / bar_height, 500, Easing.OutQuint); + arrow.MoveToY(getRelativeJudgementPosition(calculateArrowPosition(judgement)), 500, Easing.OutQuint); } protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer @@ -66,7 +81,7 @@ namespace osu.Game.Screens.Play.HUD Masking = true, Size = new Vector2(10, 2), RelativePositionAxes = Axes.Y, - Y = (float)judgement.TimeOffset / bar_height, + Y = getRelativeJudgementPosition(judgement.TimeOffset), X = mirrored ? spacing : -spacing, Child = new Box { @@ -75,7 +90,9 @@ namespace osu.Game.Screens.Play.HUD } }; - private float calculateArrowPosition(JudgementResult judgement) + private float getRelativeJudgementPosition(double value) => (float)(value / HitWindows.Miss); + + private double calculateArrowPosition(JudgementResult judgement) { if (judgementOffsets.Count > 5) judgementOffsets.RemoveAt(0); @@ -87,7 +104,7 @@ namespace osu.Game.Screens.Play.HUD foreach (var offset in judgementOffsets) offsets += offset; - return (float)offsets / judgementOffsets.Count; + return offsets / judgementOffsets.Count; } } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 3fafc21ea8..d30a32343a 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -277,10 +277,16 @@ namespace osu.Game.Screens.Play HealthDisplay?.Current.BindTo(processor.Health); if (LeftAccuracyBar != null) + { processor.NewJudgement += LeftAccuracyBar.OnNewJudgement; + LeftAccuracyBar.HitWindows = processor.CreateHitWindows(); + } if (RightAccuracyBar != null) + { processor.NewJudgement += RightAccuracyBar.OnNewJudgement; + RightAccuracyBar.HitWindows = processor.CreateHitWindows(); + } if (HealthDisplay is StandardHealthDisplay shd) processor.NewJudgement += shd.Flash; From 177a317a48b34d73643b946a90db01fe245e24c9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 18:11:49 +0300 Subject: [PATCH 215/645] rename AccuracyBar to HitErrorDisplay --- .../{AccuracyBar.cs => HitErrorDisplay.cs} | 4 ++-- osu.Game/Screens/Play/HUDOverlay.cs | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) rename osu.Game/Screens/Play/HUD/{AccuracyBar.cs => HitErrorDisplay.cs} (97%) diff --git a/osu.Game/Screens/Play/HUD/AccuracyBar.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs similarity index 97% rename from osu.Game/Screens/Play/HUD/AccuracyBar.cs rename to osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 590e9ca4d9..2d33cb08a0 100644 --- a/osu.Game/Screens/Play/HUD/AccuracyBar.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -16,7 +16,7 @@ using osu.Framework.Allocation; namespace osu.Game.Screens.Play.HUD { - public class AccuracyBar : Container + public class HitErrorDisplay : Container { private const int bar_width = 5; private const int bar_height = 250; @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Play.HUD private readonly SpriteIcon arrow; private readonly List judgementOffsets = new List(); - public AccuracyBar(bool mirrored = false) + public HitErrorDisplay(bool mirrored = false) { this.mirrored = mirrored; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index d30a32343a..a9a469486e 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -35,8 +35,8 @@ namespace osu.Game.Screens.Play public readonly ModDisplay ModDisplay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; - public readonly AccuracyBar LeftAccuracyBar; - public readonly AccuracyBar RightAccuracyBar; + public readonly HitErrorDisplay LeftHitErrorDisplay; + public readonly HitErrorDisplay RightHitErrorDisplay; public Bindable ShowHealthbar = new Bindable(true); @@ -86,8 +86,8 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), - LeftAccuracyBar = CreateAccuracyBar(false), - RightAccuracyBar = CreateAccuracyBar(), + LeftHitErrorDisplay = CreateAccuracyBar(false), + RightHitErrorDisplay = CreateAccuracyBar(), } }, PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), @@ -260,7 +260,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual AccuracyBar CreateAccuracyBar(bool mirrored = true) => new AccuracyBar(mirrored) + protected virtual HitErrorDisplay CreateAccuracyBar(bool mirrored = true) => new HitErrorDisplay(mirrored) { Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, Origin = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, @@ -276,16 +276,16 @@ namespace osu.Game.Screens.Play ComboCounter?.Current.BindTo(processor.Combo); HealthDisplay?.Current.BindTo(processor.Health); - if (LeftAccuracyBar != null) + if (LeftHitErrorDisplay != null) { - processor.NewJudgement += LeftAccuracyBar.OnNewJudgement; - LeftAccuracyBar.HitWindows = processor.CreateHitWindows(); + processor.NewJudgement += LeftHitErrorDisplay.OnNewJudgement; + LeftHitErrorDisplay.HitWindows = processor.CreateHitWindows(); } - if (RightAccuracyBar != null) + if (RightHitErrorDisplay != null) { - processor.NewJudgement += RightAccuracyBar.OnNewJudgement; - RightAccuracyBar.HitWindows = processor.CreateHitWindows(); + processor.NewJudgement += RightHitErrorDisplay.OnNewJudgement; + RightHitErrorDisplay.HitWindows = processor.CreateHitWindows(); } if (HealthDisplay is StandardHealthDisplay shd) From 5e0ac28ca88cecd41586c162d5d3b6862b11cfdd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 18:30:03 +0300 Subject: [PATCH 216/645] Add basic colours --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 41 ++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 2d33cb08a0..dba32d4ef8 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -13,12 +13,14 @@ using osu.Game.Rulesets.Objects; using osu.Game.Beatmaps; using osu.Framework.Bindables; using osu.Framework.Allocation; +using osu.Framework.Graphics.Colour; +using osu.Framework.Extensions.Color4Extensions; namespace osu.Game.Screens.Play.HUD { public class HitErrorDisplay : Container { - private const int bar_width = 5; + private const int bar_width = 4; private const int bar_height = 250; private const int spacing = 3; @@ -39,10 +41,43 @@ namespace osu.Game.Screens.Play.HUD Children = new Drawable[] { - new Box + new FillFlowContainer { RelativeSizeAxes = Axes.Both, - Colour = Color4.White, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Color4.Orange), + Height = 0.3f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Green, + Height = 0.15f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Blue, + Height = 0.1f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Green, + Height = 0.15f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Orange, Color4.Black.Opacity(0)), + Height = 0.3f + } + } }, arrow = new SpriteIcon { From 3136d46c7f366c169413f6d3f64f135dbdb98ff2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 19:04:56 +0300 Subject: [PATCH 217/645] Do not generate new judgement line on miss --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index dba32d4ef8..874a2cc088 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -99,6 +99,9 @@ namespace osu.Game.Screens.Play.HUD public void OnNewJudgement(JudgementResult judgement) { + if (!judgement.IsHit) + return; + Container judgementLine; Add(judgementLine = CreateJudgementLine(judgement)); From e7964c165f3c2c206dc404d23c7f3e6bcb4f5acd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 11 Aug 2019 19:09:50 +0300 Subject: [PATCH 218/645] Make judgement lines alive for a bit longer --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 874a2cc088..4cac73c975 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Play.HUD Add(judgementLine = CreateJudgementLine(judgement)); - judgementLine.FadeOut(5000, Easing.OutQuint); + judgementLine.FadeOut(10000, Easing.OutQuint); judgementLine.Expire(); arrow.MoveToY(getRelativeJudgementPosition(calculateArrowPosition(judgement)), 500, Easing.OutQuint); From ce62f6b56e76e13f7ca17891d37453514e3eb3e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 01:40:11 +0900 Subject: [PATCH 219/645] ToString should never return null --- osu.Game/Beatmaps/Beatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 6079a112e6..a09a1bb9cb 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -61,6 +61,6 @@ namespace osu.Game.Beatmaps { public new Beatmap Clone() => (Beatmap)base.Clone(); - public override string ToString() => BeatmapInfo?.ToString(); + public override string ToString() => BeatmapInfo?.ToString() ?? base.ToString(); } } From ff4b271f64c508227f8d70c4301046afad16f2e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 01:42:05 +0900 Subject: [PATCH 220/645] Add extra quotations around output --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index d6d6804d16..9a8197ad82 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps.Formats { if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section)) { - Logger.Log($"Unknown section \"{line}\" in {output}"); + Logger.Log($"Unknown section \"{line}\" in \"{output}\""); section = Section.None; } @@ -49,7 +49,7 @@ namespace osu.Game.Beatmaps.Formats } catch (Exception e) { - Logger.Log($"Failed to process line \"{line}\" into {output}: {e.Message}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Failed to process line \"{line}\" into \"{output}\": {e.Message}", LoggingTarget.Runtime, LogLevel.Important); } } } From 359261d4a47353221ac5ca15f86b71f7253a8087 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 02:04:06 +0900 Subject: [PATCH 221/645] Fix game not starting if intro music is disabled --- osu.Game/Screens/Menu/IntroTriangles.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 87d6012205..ba0d624959 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -104,14 +104,14 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(track), + Clock = new FramedClock(menuMusic.Value ? track : null), LoadMenu = LoadMenu }, t => { AddInternal(t); welcome?.Play(); - // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (menuMusic.Value) track.Start(); }); From e4eed83d85bec2274d40c14d4965cde6f3743def Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 11 Aug 2019 19:14:49 +0200 Subject: [PATCH 222/645] Add dual bindings for Jukebox hotkeys --- .../Input/Bindings/GlobalActionContainer.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 809ec9a09e..b2cbb77087 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -46,8 +46,11 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select), new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev), + new KeyBinding(InputKey.F1, GlobalAction.MusicPrev), new KeyBinding(InputKey.TrackNext, GlobalAction.MusicNext), + new KeyBinding(InputKey.F5, GlobalAction.MusicNext), new KeyBinding(InputKey.PlayPause, GlobalAction.MusicPlay), + new KeyBinding(InputKey.F3, GlobalAction.MusicPlay) }; public IEnumerable InGameKeyBindings => new[] @@ -92,16 +95,6 @@ namespace osu.Game.Input.Bindings [Description("Toggle mute")] ToggleMute, - // Game-wide beatmap jukebox keybindings - [Description("Jukebox next track")] - MusicNext, - - [Description("Jukebox previous track")] - MusicPrev, - - [Description("Jukebox play / pause current track")] - MusicPlay, - // In-Game Keybindings [Description("Skip cutscene")] SkipCutscene, @@ -129,5 +122,15 @@ namespace osu.Game.Input.Bindings [Description("Quick exit (Hold)")] QuickExit, + + // Game-wide beatmap jukebox keybindings + [Description("Jukebox next track")] + MusicNext, + + [Description("Jukebox previous track")] + MusicPrev, + + [Description("Jukebox play / pause current track")] + MusicPlay, } } From bc32726f3caee2c95c3111095f4b089e0326fc64 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 11 Aug 2019 23:08:14 +0300 Subject: [PATCH 223/645] Apply renaming suggestions Co-Authored-By: Dean Herbert --- osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index bffee7f1f7..813ca904ca 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -149,7 +149,7 @@ namespace osu.Game.Tests.Visual.Background } /// - /// Check if the is properly accepting user-defined visual changes in background at all. + /// Ensure is properly accepting user-defined visual changes for a background. /// [Test] public void DisableUserDimBackgroundTest() @@ -166,7 +166,7 @@ namespace osu.Game.Tests.Visual.Background } /// - /// Check if the is properly accepting user-defined visual changes in storyboard at all. + /// Ensure is properly accepting user-defined visual changes for a storyboard. /// [Test] public void DisableUserDimStoryboardTest() From fe20e1924352fcfea0918e14f55b0c43b6038ffd Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 11 Aug 2019 23:19:22 +0300 Subject: [PATCH 224/645] Rename toggling steps --- .../Visual/Background/TestSceneUserDimContainer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 813ca904ca..3061a3a542 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -119,14 +119,14 @@ namespace osu.Game.Tests.Visual.Background { performFullSetup(); createFakeStoryboard(); - AddStep("Storyboard Enabled", () => + AddStep("Enable Storyboard", () => { player.ReplacesBackground.Value = true; player.StoryboardEnabled.Value = true; }); waitForDim(); AddAssert("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible); - AddStep("Storyboard Disabled", () => + AddStep("Disable Storyboard", () => { player.ReplacesBackground.Value = false; player.StoryboardEnabled.Value = false; @@ -157,10 +157,10 @@ namespace osu.Game.Tests.Visual.Background performFullSetup(); waitForDim(); AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied()); - AddStep("EnableUserDim disabled", () => songSelect.DimEnabled.Value = false); + AddStep("Enable user dim", () => songSelect.DimEnabled.Value = false); waitForDim(); AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsUserBlurDisabled()); - AddStep("EnableUserDim enabled", () => songSelect.DimEnabled.Value = true); + AddStep("Disable user dim", () => songSelect.DimEnabled.Value = true); waitForDim(); AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied()); } @@ -173,16 +173,16 @@ namespace osu.Game.Tests.Visual.Background { performFullSetup(); createFakeStoryboard(); - AddStep("Storyboard Enabled", () => + AddStep("Enable Storyboard", () => { player.ReplacesBackground.Value = true; player.StoryboardEnabled.Value = true; }); - AddStep("EnableUserDim enabled", () => player.DimmableStoryboard.EnableUserDim.Value = true); + AddStep("Enable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = true); AddStep("Set dim level to 1", () => songSelect.DimLevel.Value = 1f); waitForDim(); AddAssert("Storyboard is invisible", () => !player.IsStoryboardVisible); - AddStep("EnableUserDim disabled", () => player.DimmableStoryboard.EnableUserDim.Value = false); + AddStep("Disable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = false); waitForDim(); AddAssert("Storyboard is visible", () => player.IsStoryboardVisible); } From 45b4fc9201849483d0d08ec770c6c5b89d413d6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 15:00:32 +0900 Subject: [PATCH 225/645] Add xmldoc --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 58e275ba26..cdea7276f3 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -18,6 +18,10 @@ namespace osu.Game.Rulesets.Osu set => ((OsuKeyBindingContainer)KeyBindingContainer).AllowUserPresses = value; } + /// + /// Whether the user's cursor movement events should be accepted. + /// Can be used to block only movement while still accepting button input. + /// public bool AllowUserCursorMovement { get; set; } = true; protected override RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) From 707911acac196e5c97ce6d6f5b95a0dbeb3dcdbc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 15:05:27 +0900 Subject: [PATCH 226/645] Tidy up code formatting / variable naming --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 1853b0228f..ca72f18e9c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -29,19 +29,21 @@ namespace osu.Game.Rulesets.Osu.Mods private OsuInputManager inputManager; private List replayFrames; - private int frameIndex; + + private int currentFrame; public void Update(Playfield playfield) { - // If we are on the last replay frame, no need to do anything - if (frameIndex == replayFrames.Count - 1) return; + if (currentFrame == replayFrames.Count - 1) return; - // Check if we are closer to the next replay frame then the current one - if (Math.Abs(replayFrames[frameIndex].Time - playfield.Time.Current) >= Math.Abs(replayFrames[frameIndex + 1].Time - playfield.Time.Current)) + double time = playfield.Time.Current; + + // Very naive implementation of autopilot based on proximity to replay frames. + // TODO: this needs to be based on user interactions to better match stable (pausing until judgement is registered). + if (Math.Abs(replayFrames[currentFrame + 1].Time - time) <= Math.Abs(replayFrames[currentFrame].Time - time)) { - // If we are, move to the next frame, and update the mouse position - frameIndex++; - new MousePositionAbsoluteInput { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); + currentFrame++; + new MousePositionAbsoluteInput { Position = playfield.ToScreenSpace(replayFrames[currentFrame].Position) }.Apply(inputManager.CurrentState, inputManager); } // TODO: Implement the functionality to automatically spin spinners From 520924b440c0a642597d25d58d24efbcd705ff3a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 09:45:21 +0300 Subject: [PATCH 227/645] Don't create a new request if onlineId is null --- .../Screens/Multi/Match/Components/MatchBeatmapPanel.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index f73059d069..397f158f2b 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -40,15 +40,15 @@ namespace osu.Game.Screens.Multi.Match.Components panel = null; } - var onlineId = item.NewValue?.Beatmap.OnlineBeatmapID ?? 0; + var onlineId = item.NewValue?.Beatmap.OnlineBeatmapID; - if (onlineId != 0) + if (onlineId.HasValue) { - request = new GetBeatmapSetRequest(onlineId, BeatmapSetLookupType.BeatmapId); + request = new GetBeatmapSetRequest(onlineId.Value, BeatmapSetLookupType.BeatmapId); request.Success += beatmap => { panel = new DirectGridPanel(beatmap.ToBeatmapSet(rulesets)); - LoadComponentAsync(panel, p => { AddInternal(panel); }); + LoadComponentAsync(panel, p => { AddInternal(p); }); }; api.Queue(request); } From 5b68a2f34a2acc1abe91bbb65197e8dcde93ff0d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 09:50:49 +0300 Subject: [PATCH 228/645] Rename trackManager to previewTrackManager --- .../Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs | 4 ++-- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs index db2b61cdd9..f148170847 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }; [Resolved] - private PreviewTrackManager trackManager { get; set; } + private PreviewTrackManager previewTrackManager { get; set; } public TestSceneMatchBeatmapPanel() { @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("Select random beatmap", () => { Room.CurrentItem.Value = Room.Playlist[RNG.Next(Room.Playlist.Count)]; - trackManager.StopAnyPlaying(this); + previewTrackManager.StopAnyPlaying(this); }); } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index c89c32759d..8d79b21b16 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Multi.Match private BeatmapManager beatmapManager { get; set; } [Resolved] - private PreviewTrackManager trackManager { get; set; } + private PreviewTrackManager previewTrackManager { get; set; } [Resolved(CanBeNull = true)] private OsuGame game { get; set; } @@ -188,7 +188,7 @@ namespace osu.Game.Screens.Multi.Match Mods.Value = Array.Empty(); - trackManager.StopAnyPlaying(this); + previewTrackManager.StopAnyPlaying(this); return base.OnExiting(next); } @@ -207,7 +207,7 @@ namespace osu.Game.Screens.Multi.Match if (e.NewValue?.Ruleset != null) Ruleset.Value = e.NewValue.Ruleset; - trackManager.StopAnyPlaying(this); + previewTrackManager.StopAnyPlaying(this); } /// @@ -233,7 +233,7 @@ namespace osu.Game.Screens.Multi.Match private void onStart() { - trackManager.StopAnyPlaying(this); + previewTrackManager.StopAnyPlaying(this); switch (type.Value) { From cb910a651881819595c639c542af9c1f8686c6c2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 10:02:45 +0300 Subject: [PATCH 229/645] Replace if/else statement --- .../Screens/Multi/Match/MatchSubScreen.cs | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 8d79b21b16..dafea70092 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -150,20 +150,12 @@ namespace osu.Game.Screens.Multi.Match { const float fade_duration = 500; - if (tab.NewValue is SettingsMatchPage) - { - header.ShowBeatmapPanel.Value = false; - settings.Show(); - info.FadeOut(fade_duration, Easing.OutQuint); - bottomRow.FadeOut(fade_duration, Easing.OutQuint); - } - else - { - header.ShowBeatmapPanel.Value = true; - settings.Hide(); - info.FadeIn(fade_duration, Easing.OutQuint); - bottomRow.FadeIn(fade_duration, Easing.OutQuint); - } + var settingsDisplayed = tab.NewValue is SettingsMatchPage; + + header.ShowBeatmapPanel.Value = !settingsDisplayed; + settings.State.Value = settingsDisplayed ? Visibility.Visible : Visibility.Hidden; + info.FadeTo(settingsDisplayed ? 0 : 1, fade_duration, Easing.OutQuint); + bottomRow.FadeTo(settingsDisplayed ? 0 : 1, fade_duration, Easing.OutQuint); }, true); chat.Exit += () => From 75cb0d093b59cf74b50a328f7331158be5f6feca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 16:10:25 +0900 Subject: [PATCH 230/645] Use description correctly Required for localisation --- osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs | 2 +- .../Select/Leaderboards/BeatmapLeaderboardScope.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index c74c7cbc2b..7eb9b1829c 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Bottom = 8 }, Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, - Text = value.GetDescription() + " Ranking", + Text = value.GetDescription(), Font = OsuFont.GetFont(weight: FontWeight.Regular), }, box = new Box diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs index 9e480b61c6..dc4c2ba4e2 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboardScope.cs @@ -1,13 +1,22 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.ComponentModel; + namespace osu.Game.Screens.Select.Leaderboards { public enum BeatmapLeaderboardScope { + [Description("Local Ranking")] Local, + + [Description("Country Ranking")] Country, + + [Description("Global Ranking")] Global, + + [Description("Friend Ranking")] Friend, } } From 982066dfdfe2bf2356ff1d7acfc5c0827d0894cd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 10:38:34 +0300 Subject: [PATCH 231/645] Convert to method group --- osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index 397f158f2b..7939b18e97 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Multi.Match.Components request.Success += beatmap => { panel = new DirectGridPanel(beatmap.ToBeatmapSet(rulesets)); - LoadComponentAsync(panel, p => { AddInternal(p); }); + LoadComponentAsync(panel, AddInternal); }; api.Queue(request); } From 1bbd0ca54e0bcb4ab90b40cbaa0b533223bf043f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2019 08:30:26 +0000 Subject: [PATCH 232/645] Bump ppy.osu.Game.Resources from 2019.731.1 to 2019.809.0 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.731.1 to 2019.809.0. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.731.1...2019.809.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 3b2e6574ac..721d341c08 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -62,7 +62,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1dd19ac7ed..b5266fd75d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 1c3faeed39..103d89cadc 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - + From 9c15024014d9e196e97a9dee1e817c30993080af Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 12 Aug 2019 10:53:06 +0200 Subject: [PATCH 233/645] Reword and add missing xmldoc to OnScreenDisplay --- osu.Game/Overlays/OnScreenDisplay.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index a30ce5c56f..a92320945e 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -16,6 +16,10 @@ using osu.Game.Overlays.OSD; namespace osu.Game.Overlays { + /// + /// An on-screen display which automatically tracks and displays toast notifications for . + /// Can also display custom content via + /// public class OnScreenDisplay : Container { private readonly Container box; @@ -97,7 +101,7 @@ namespace osu.Game.Overlays } /// - /// Displays the given as parameter on the OSD + /// Displays the provided temporarily. /// /// public void Display(Toast toast) From 144d41f143fb429a848591ecb77bce3d548b64c9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 12:33:01 +0300 Subject: [PATCH 234/645] Add ability to not add all the items if enum --- osu.Game/Graphics/UserInterface/OsuTabControl.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 11f41b1a48..1bb37560b2 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -31,6 +31,8 @@ namespace osu.Game.Graphics.UserInterface protected virtual float StripWidth() => TabContainer.Children.Sum(c => c.IsPresent ? c.DrawWidth + TabContainer.Spacing.X : 0) - TabContainer.Spacing.X; protected virtual float StripHeight() => 1; + protected virtual bool AddAllItemsIfEnum => true; + private static bool isEnumType => typeof(T).IsEnum; public OsuTabControl() @@ -45,7 +47,7 @@ namespace osu.Game.Graphics.UserInterface Colour = Color4.White.Opacity(0), }); - if (isEnumType) + if (isEnumType && AddAllItemsIfEnum) foreach (var val in (T[])Enum.GetValues(typeof(T))) AddItem(val); } From fc521ac93b3727bc69c3dbebdb94ee53085be1eb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 13:08:15 +0300 Subject: [PATCH 235/645] Expose BoxColour property --- osu.Game/Graphics/UserInterface/PageTabControl.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/PageTabControl.cs b/osu.Game/Graphics/UserInterface/PageTabControl.cs index 156a556b5e..f8d1c7502a 100644 --- a/osu.Game/Graphics/UserInterface/PageTabControl.cs +++ b/osu.Game/Graphics/UserInterface/PageTabControl.cs @@ -32,6 +32,12 @@ namespace osu.Game.Graphics.UserInterface protected readonly SpriteText Text; + protected Color4 BoxColour + { + get => box.Colour; + set => box.Colour = value; + } + public PageTabItem(T value) : base(value) { @@ -66,7 +72,7 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - box.Colour = colours.Yellow; + BoxColour = colours.Yellow; } protected override bool OnHover(HoverEvent e) From 6533f114d42762d30e98a06770033fdfae247b8b Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 12 Aug 2019 12:09:09 +0200 Subject: [PATCH 236/645] Apply review suggestions --- .../UserInterface/TestSceneOnScreenDisplay.cs | 14 ++++++++++++++ osu.Game/Overlays/OSD/Toast.cs | 14 +++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index 4decfc7dd6..558c027e1d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -24,6 +24,11 @@ namespace osu.Game.Tests.Visual.UserInterface Add(osd); AddStep("Display empty osd toast", () => osd.Display(new EmptyToast())); + AddAssert("Toast width is 240", () => osd.Child.Width == 240); + + AddStep("Display toast with lengthy text", () => osd.Display(new LengthyToast())); + AddAssert("Toast width is greater than 240", () => osd.Child.Width > 240); + AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); @@ -96,6 +101,15 @@ namespace osu.Game.Tests.Visual.UserInterface } } + private class LengthyToast : Toast + { + public LengthyToast() + : base("Toast with a very very very long text", "A very very very very very very long text also", "A very very very very very long shortcut") + { + + } + } + private class TestOnScreenDisplay : OnScreenDisplay { protected override void DisplayTemporarily(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110); diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index db5e6e4a6a..46c53ec409 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -13,22 +13,30 @@ namespace osu.Game.Overlays.OSD { public abstract class Toast : Container { + private const int toast_minimum_width = 240; + private readonly Container content; protected override Container Content => content; protected readonly OsuSpriteText ValueText; - protected Toast(string description, string value, string keybinding) + protected Toast(string description, string value, string shortcut) { Anchor = Anchor.Centre; Origin = Anchor.Centre; - Width = 240; // A toast's height is decided (and transformed) by the containing OnScreenDisplay. RelativeSizeAxes = Axes.Y; + AutoSizeAxes = Axes.X; InternalChildren = new Drawable[] { + new Container //this container exists just to set a minimum width for the toast + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = toast_minimum_width + }, new Box { RelativeSizeAxes = Axes.Both, @@ -68,7 +76,7 @@ namespace osu.Game.Overlays.OSD Alpha = 0.3f, Margin = new MarginPadding { Bottom = 15 }, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Text = string.IsNullOrEmpty(keybinding) ? "NO KEY BOUND" : keybinding.ToUpperInvariant() + Text = string.IsNullOrEmpty(shortcut) ? "NO KEY BOUND" : shortcut.ToUpperInvariant() }, }; } From 5e49d0fb28e704a5c53f34ce1358a20173269cdb Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 12 Aug 2019 12:11:01 +0200 Subject: [PATCH 237/645] Fix CI issues --- osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index 558c027e1d..45720548c8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -106,7 +106,6 @@ namespace osu.Game.Tests.Visual.UserInterface public LengthyToast() : base("Toast with a very very very long text", "A very very very very very very long text also", "A very very very very very long shortcut") { - } } From ba49a4c2da7d0791c53ac49955a41114acfa3a88 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 13:16:57 +0300 Subject: [PATCH 238/645] Use existing PageTabControl for layout --- .../BeatmapSet/LeaderboardScopeSelector.cs | 63 ++++--------------- 1 file changed, 12 insertions(+), 51 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index 7eb9b1829c..f54509ff77 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -8,25 +8,24 @@ using osu.Framework.Graphics.Containers; using osuTK; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics.Sprites; -using osu.Framework.Extensions; using osu.Game.Graphics; using osu.Framework.Allocation; using osuTK.Graphics; -using osu.Framework.Input.Events; using osu.Framework.Graphics.Colour; +using osu.Framework.Input.Events; namespace osu.Game.Overlays.BeatmapSet { - public class LeaderboardScopeSelector : TabControl + public class LeaderboardScopeSelector : PageTabControl { + protected override bool AddAllItemsIfEnum => false; + protected override Dropdown CreateDropdown() => null; protected override TabItem CreateTabItem(BeatmapLeaderboardScope value) => new ScopeSelectorTabItem(value); public LeaderboardScopeSelector() { - AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; AddItem(BeatmapLeaderboardScope.Global); @@ -42,57 +41,31 @@ namespace osu.Game.Overlays.BeatmapSet protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - AutoSizeAxes = Axes.Both, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, Direction = FillDirection.Horizontal, Spacing = new Vector2(20, 0), }; - private class ScopeSelectorTabItem : TabItem + private class ScopeSelectorTabItem : PageTabItem { - private const float transition_duration = 100; - - private readonly Box box; - - protected readonly OsuSpriteText Text; - public ScopeSelectorTabItem(BeatmapLeaderboardScope value) : base(value) { - AutoSizeAxes = Axes.Both; - - Children = new Drawable[] - { - Text = new OsuSpriteText - { - Margin = new MarginPadding { Bottom = 8 }, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - Text = value.GetDescription(), - Font = OsuFont.GetFont(weight: FontWeight.Regular), - }, - box = new Box - { - RelativeSizeAxes = Axes.X, - Height = 5, - Scale = new Vector2(1f, 0f), - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - }, - new HoverClickSounds() - }; + Text.Font = OsuFont.GetFont(size: 16); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - box.Colour = colours.Blue; + BoxColour = colours.Blue; } protected override bool OnHover(HoverEvent e) { - Text.FadeColour(Color4.LightSkyBlue); + Text.FadeColour(BoxColour); return base.OnHover(e); } @@ -103,18 +76,6 @@ namespace osu.Game.Overlays.BeatmapSet Text.FadeColour(Color4.White); } - - protected override void OnActivated() - { - box.ScaleTo(new Vector2(1f), transition_duration); - Text.Font = Text.Font.With(weight: FontWeight.Black); - } - - protected override void OnDeactivated() - { - box.ScaleTo(new Vector2(1f, 0f), transition_duration); - Text.Font = Text.Font.With(weight: FontWeight.Regular); - } } private class Line : GridContainer From 9c36cb4af4f60a8675640471a99adf65968ea7dd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Aug 2019 14:33:30 +0300 Subject: [PATCH 239/645] Use existing AccentColour logic instead of weird BoxColour --- .../Graphics/UserInterface/PageTabControl.cs | 26 ++++++++++++------- .../BeatmapSet/LeaderboardScopeSelector.cs | 14 +++++----- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/PageTabControl.cs b/osu.Game/Graphics/UserInterface/PageTabControl.cs index f8d1c7502a..a0d3745180 100644 --- a/osu.Game/Graphics/UserInterface/PageTabControl.cs +++ b/osu.Game/Graphics/UserInterface/PageTabControl.cs @@ -24,7 +24,13 @@ namespace osu.Game.Graphics.UserInterface Height = 30; } - public class PageTabItem : TabItem + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.Yellow; + } + + public class PageTabItem : TabItem, IHasAccentColour { private const float transition_duration = 100; @@ -32,10 +38,16 @@ namespace osu.Game.Graphics.UserInterface protected readonly SpriteText Text; - protected Color4 BoxColour + private Color4 accentColour; + + public Color4 AccentColour { - get => box.Colour; - set => box.Colour = value; + get => accentColour; + set + { + accentColour = value; + box.Colour = accentColour; + } } public PageTabItem(T value) @@ -69,12 +81,6 @@ namespace osu.Game.Graphics.UserInterface Active.BindValueChanged(active => Text.Font = Text.Font.With(Typeface.Exo, weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium), true); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BoxColour = colours.Yellow; - } - protected override bool OnHover(HoverEvent e) { if (!Active.Value) diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index f54509ff77..c867cc3780 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -39,6 +39,12 @@ namespace osu.Game.Overlays.BeatmapSet }); } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.Blue; + } + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { Anchor = Anchor.BottomCentre, @@ -57,15 +63,9 @@ namespace osu.Game.Overlays.BeatmapSet Text.Font = OsuFont.GetFont(size: 16); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BoxColour = colours.Blue; - } - protected override bool OnHover(HoverEvent e) { - Text.FadeColour(BoxColour); + Text.FadeColour(AccentColour); return base.OnHover(e); } From 883102ee5d912b503db9ea9a9e7e162657023b40 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 12 Aug 2019 16:40:52 +0300 Subject: [PATCH 240/645] Move score multiplier logic inside score calculation --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ba2375bec1..c8858233aa 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -398,7 +398,7 @@ namespace osu.Game.Rulesets.Scoring if (rollingMaxBaseScore != 0) Accuracy.Value = baseScore / rollingMaxBaseScore; - TotalScore.Value = getScore(Mode.Value) * scoreMultiplier; + TotalScore.Value = getScore(Mode.Value); } private double getScore(ScoringMode mode) @@ -407,11 +407,11 @@ namespace osu.Game.Rulesets.Scoring { default: case ScoringMode.Standardised: - return max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo.Value / maxHighestCombo) + bonusScore; + return (max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo.Value / maxHighestCombo) + bonusScore) * scoreMultiplier; case ScoringMode.Classic: // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) - return bonusScore + baseScore * (1 + Math.Max(0, HighestCombo.Value - 1) / 25); + return bonusScore + baseScore * ((1 + Math.Max(0, HighestCombo.Value - 1) * scoreMultiplier) / 25); } } From c0f0fbbaa93927fb5c520182e0ece74eaaff5e09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 00:14:37 +0900 Subject: [PATCH 241/645] Rename variable and add xmldoc --- osu.Game/Graphics/UserInterface/OsuTabControl.cs | 7 +++++-- osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 1bb37560b2..c55d14456b 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -31,7 +31,10 @@ namespace osu.Game.Graphics.UserInterface protected virtual float StripWidth() => TabContainer.Children.Sum(c => c.IsPresent ? c.DrawWidth + TabContainer.Spacing.X : 0) - TabContainer.Spacing.X; protected virtual float StripHeight() => 1; - protected virtual bool AddAllItemsIfEnum => true; + /// + /// Whether entries should be automatically populated if is an type. + /// + protected virtual bool AddEnumEntriesAutomatically => true; private static bool isEnumType => typeof(T).IsEnum; @@ -47,7 +50,7 @@ namespace osu.Game.Graphics.UserInterface Colour = Color4.White.Opacity(0), }); - if (isEnumType && AddAllItemsIfEnum) + if (isEnumType && AddEnumEntriesAutomatically) foreach (var val in (T[])Enum.GetValues(typeof(T))) AddItem(val); } diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index c867cc3780..04713fd88c 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.BeatmapSet { public class LeaderboardScopeSelector : PageTabControl { - protected override bool AddAllItemsIfEnum => false; + protected override bool AddEnumEntriesAutomatically => false; protected override Dropdown CreateDropdown() => null; From 433b701df3478eb7038ed4002d7f0ba9d9489f86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 00:21:47 +0900 Subject: [PATCH 242/645] Make line slightly thicker (to display better at low resolutions) Also tidies up code. --- .../Overlays/BeatmapSet/LeaderboardScopeSelector.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index 04713fd88c..dcd58db427 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.BeatmapSet AddItem(BeatmapLeaderboardScope.Country); AddItem(BeatmapLeaderboardScope.Friend); - AddInternal(new Line + AddInternal(new GradientLine { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, @@ -78,19 +78,20 @@ namespace osu.Game.Overlays.BeatmapSet } } - private class Line : GridContainer + private class GradientLine : GridContainer { - public Line() + public GradientLine() { - Height = 1; RelativeSizeAxes = Axes.X; - Width = 0.8f; + Size = new Vector2(0.8f, 1.5f); + ColumnDimensions = new[] { new Dimension(), new Dimension(mode: GridSizeMode.Relative, size: 0.4f), new Dimension(), }; + Content = new[] { new Drawable[] From 5447e7cf222ea170409d18e0a8261185b090119a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 11:34:45 +0900 Subject: [PATCH 243/645] Fix file ordering --- osu.Game/Overlays/OSD/TrackedSettingToast.cs | 35 +++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/OSD/TrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs index 0f4bd34779..8e8a99a0a7 100644 --- a/osu.Game/Overlays/OSD/TrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -66,12 +66,7 @@ namespace osu.Game.Overlays.OSD ValueText.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; for (int i = 0; i < optionCount; i++) - { - optionLights.Add(new OptionLight - { - Glowing = i == selectedOption - }); - } + optionLights.Add(new OptionLight { Glowing = i == selectedOption }); } private class OptionLight : Container @@ -109,20 +104,6 @@ namespace osu.Game.Overlays.OSD } } - private void updateGlow() - { - if (glowing) - { - fill.FadeColour(glowingColour, transition_speed, Easing.OutQuint); - FadeEdgeEffectTo(glow_strength, transition_speed, Easing.OutQuint); - } - else - { - FadeEdgeEffectTo(0, transition_speed, Easing.OutQuint); - fill.FadeColour(idleColour, transition_speed, Easing.OutQuint); - } - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -147,6 +128,20 @@ namespace osu.Game.Overlays.OSD updateGlow(); FinishTransforms(true); } + + private void updateGlow() + { + if (glowing) + { + fill.FadeColour(glowingColour, transition_speed, Easing.OutQuint); + FadeEdgeEffectTo(glow_strength, transition_speed, Easing.OutQuint); + } + else + { + FadeEdgeEffectTo(0, transition_speed, Easing.OutQuint); + fill.FadeColour(idleColour, transition_speed, Easing.OutQuint); + } + } } } } From f3380c9372c14a2c87db03b832c27001845a1e55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 12:06:57 +0900 Subject: [PATCH 244/645] Remove "jukebox" terminology --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 6 +++--- osu.Game/OsuGame.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index b2cbb77087..c54e3f596e 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -124,13 +124,13 @@ namespace osu.Game.Input.Bindings QuickExit, // Game-wide beatmap jukebox keybindings - [Description("Jukebox next track")] + [Description("Next track")] MusicNext, - [Description("Jukebox previous track")] + [Description("Previous track")] MusicPrev, - [Description("Jukebox play / pause current track")] + [Description("Play / pause")] MusicPlay, } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index af77c8816a..1541d1fa29 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -301,7 +301,7 @@ namespace osu.Game }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); } - #region Beatmap jukebox progression + #region Beatmap progression private void beatmapChanged(ValueChangedEvent beatmap) { From 0c0c4052168e9cba36bcd096c359c9c89c1e4a1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 12:27:49 +0900 Subject: [PATCH 245/645] Add note to README about ffmpeg requirement on linux --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4d676f4be..5dc4da12a4 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh ## Requirements - A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed. +- When running on linux, please have a system-wide ffmpeg installation available to support video decoding. +- When running on Windows 7 or 8.1, there are **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. - When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). -- Note that there are **[additional requirements for Windows 7 and Windows 8.1](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** which you may need to manually install if your operating system is not up-to-date. ## Running osu! From 33a119b7263501823c8f2c1f71a0d881bfd602fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 12:35:06 +0900 Subject: [PATCH 246/645] Fix double grammar Co-Authored-By: Dan Balasescu --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dc4da12a4..56491a4be4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh - A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed. - When running on linux, please have a system-wide ffmpeg installation available to support video decoding. -- When running on Windows 7 or 8.1, there are **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. +- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. - When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). ## Running osu! From 5dbde38a6b00586a7d7b9223e775ea7b4fddbf61 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 12:40:20 +0900 Subject: [PATCH 247/645] Group key bindings together --- .../Input/Bindings/GlobalActionContainer.cs | 30 +++++++++++-------- .../KeyBinding/GlobalKeyBindingsSection.cs | 12 ++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index c54e3f596e..8073200c47 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Input.Bindings handler = game; } - public override IEnumerable DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings); + public override IEnumerable DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings); public IEnumerable GlobalKeyBindings => new[] { @@ -32,11 +32,6 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), - new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume), - new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume), - new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume), - new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), - new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), new KeyBinding(InputKey.Escape, GlobalAction.Back), new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back), @@ -44,13 +39,6 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Space, GlobalAction.Select), new KeyBinding(InputKey.Enter, GlobalAction.Select), new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select), - - new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev), - new KeyBinding(InputKey.F1, GlobalAction.MusicPrev), - new KeyBinding(InputKey.TrackNext, GlobalAction.MusicNext), - new KeyBinding(InputKey.F5, GlobalAction.MusicNext), - new KeyBinding(InputKey.PlayPause, GlobalAction.MusicPlay), - new KeyBinding(InputKey.F3, GlobalAction.MusicPlay) }; public IEnumerable InGameKeyBindings => new[] @@ -62,6 +50,22 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed), }; + public IEnumerable AudioControlKeyBindings => new[] + { + new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume), + new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume), + new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume), + new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), + new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), + + new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev), + new KeyBinding(InputKey.F1, GlobalAction.MusicPrev), + new KeyBinding(InputKey.TrackNext, GlobalAction.MusicNext), + new KeyBinding(InputKey.F5, GlobalAction.MusicNext), + new KeyBinding(InputKey.PlayPause, GlobalAction.MusicPlay), + new KeyBinding(InputKey.F3, GlobalAction.MusicPlay) + }; + protected override IEnumerable KeyBindingInputQueue => handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler); } diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index 7e33d7ba27..56e93b6a1e 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -15,6 +15,7 @@ namespace osu.Game.Overlays.KeyBinding public GlobalKeyBindingsSection(GlobalActionContainer manager) { Add(new DefaultBindingsSubsection(manager)); + Add(new AudioControlKeyBindingsSubsection(manager)); Add(new InGameKeyBindingsSubsection(manager)); } @@ -39,5 +40,16 @@ namespace osu.Game.Overlays.KeyBinding Defaults = manager.InGameKeyBindings; } } + + private class AudioControlKeyBindingsSubsection : KeyBindingsSubsection + { + protected override string Header => "Audio"; + + public AudioControlKeyBindingsSubsection(GlobalActionContainer manager) + : base(null) + { + Defaults = manager.AudioControlKeyBindings; + } + } } } From 5681d1097c107c4cbbe060c36997c08cc19ebe74 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 14:07:40 +0900 Subject: [PATCH 248/645] Move into components namespace --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 +- .../Header/{ => Components}/PreviousUsernamesContainer.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Overlays/Profile/Header/{ => Components}/PreviousUsernamesContainer.cs (99%) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index b891fda0f4..43373f872a 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -7,7 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API; using osu.Game.Online.API.Requests; -using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs similarity index 99% rename from osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs index b53ac8eb80..ef9c01e12b 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.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 System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -11,10 +13,8 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Users; using osuTK; -using System; -using System.Linq; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class PreviousUsernamesContainer : CompositeDrawable { From 8d3f2f76459d062cd2ee54afa747d96981794e9a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 14:09:10 +0900 Subject: [PATCH 249/645] Drop container from name --- ....cs => TestSceneUserProfilePreviousUsernames.cs} | 13 ++++++++++--- ...usUsernamesContainer.cs => PreviousUsernames.cs} | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) rename osu.Game.Tests/Visual/Online/{TestScenePreviousUsernamesContainer.cs => TestSceneUserProfilePreviousUsernames.cs} (85%) rename osu.Game/Overlays/Profile/Header/Components/{PreviousUsernamesContainer.cs => PreviousUsernames.cs} (98%) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs similarity index 85% rename from osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs rename to osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs index 43373f872a..d09a50b12c 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.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 System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -13,16 +15,21 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestScenePreviousUsernamesContainer : OsuTestScene + public class TestSceneUserProfilePreviousUsernames : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(PreviousUsernames) + }; + [Resolved] private IAPIProvider api { get; set; } private readonly Bindable user = new Bindable(); - public TestScenePreviousUsernamesContainer() + public TestSceneUserProfilePreviousUsernames() { - Child = new PreviousUsernamesContainer + Child = new PreviousUsernames { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs similarity index 98% rename from osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs index ef9c01e12b..f18f319e27 100644 --- a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { - public class PreviousUsernamesContainer : CompositeDrawable + public class PreviousUsernames : CompositeDrawable { private const int duration = 200; private const int margin = 10; @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private readonly Box background; private readonly SpriteText header; - public PreviousUsernamesContainer() + public PreviousUsernames() { HoverIconContainer hoverIcon; From ad24265730b98ac86b5b8c739afdf2da172782ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 14:29:58 +0900 Subject: [PATCH 250/645] Split visual component out of MusicController --- .../Visual/Gameplay/TestSceneStoryboard.cs | 40 +- .../TestSceneBeatSyncedContainer.cs | 29 +- ...oller.cs => TestSceneNowPlayingOverlay.cs} | 18 +- osu.Game/OsuGame.cs | 4 +- osu.Game/Overlays/MusicController.cs | 475 +++--------------- osu.Game/Overlays/NowPlayingOverlay.cs | 403 +++++++++++++++ .../Overlays/Toolbar/ToolbarMusicButton.cs | 2 +- 7 files changed, 532 insertions(+), 439 deletions(-) rename osu.Game.Tests/Visual/UserInterface/{TestSceneMusicController.cs => TestSceneNowPlayingOverlay.cs} (58%) create mode 100644 osu.Game/Overlays/NowPlayingOverlay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index ead7a4b7fc..ff8437311e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -21,32 +21,38 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly Container storyboardContainer; private DrawableStoryboard storyboard; + [Cached] + private MusicController musicController = new MusicController(); + public TestSceneStoryboard() { Clock = new FramedClock(); - Add(new Container + AddRange(new Drawable[] { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + musicController, + new Container { - new Box + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - storyboardContainer = new Container - { - RelativeSizeAxes = Axes.Both, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + storyboardContainer = new Container + { + RelativeSizeAxes = Axes.Both, + }, }, }, - }); - - Add(new MusicController - { - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - State = { Value = Visibility.Visible }, + new NowPlayingOverlay + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + State = { Value = Visibility.Visible }, + } }); AddStep("Restart", restart); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 28f0cc027e..94228e22f0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -3,6 +3,7 @@ using System; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -22,30 +23,36 @@ namespace osu.Game.Tests.Visual.UserInterface [TestFixture] public class TestSceneBeatSyncedContainer : OsuTestScene { - private readonly MusicController mc; + private readonly NowPlayingOverlay np; + + [Cached] + private MusicController musicController = new MusicController(); public TestSceneBeatSyncedContainer() { Clock = new FramedClock(); Clock.ProcessFrame(); - Add(new BeatContainer + AddRange(new Drawable[] { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - }); - - Add(mc = new MusicController - { - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, + musicController, + new BeatContainer + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + }, + np = new NowPlayingOverlay + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + } }); } protected override void LoadComplete() { base.LoadComplete(); - mc.ToggleVisibility(); + np.ToggleVisibility(); } private class BeatContainer : BeatSyncedContainer diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneMusicController.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs similarity index 58% rename from osu.Game.Tests/Visual/UserInterface/TestSceneMusicController.cs rename to osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index ab2ca47100..e3daa9c279 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneMusicController.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Timing; using osu.Game.Overlays; @@ -9,22 +10,27 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneMusicController : OsuTestScene + public class TestSceneNowPlayingOverlay : OsuTestScene { - public TestSceneMusicController() + [Cached] + private MusicController musicController = new MusicController(); + + public TestSceneNowPlayingOverlay() { Clock = new FramedClock(); - var mc = new MusicController + var np = new NowPlayingOverlay { Origin = Anchor.Centre, Anchor = Anchor.Centre }; - Add(mc); - AddStep(@"show", () => mc.Show()); + Add(musicController); + Add(np); + + AddStep(@"show", () => np.Show()); AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state); - AddStep(@"show", () => mc.Hide()); + AddStep(@"show", () => np.Hide()); } } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b9e2b79b05..edf3424e0e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -469,6 +469,8 @@ namespace osu.Game loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add); loadComponentSingleFile(new OnScreenDisplay(), Add, true); + loadComponentSingleFile(musicController = new MusicController(), Add, true); + loadComponentSingleFile(notifications = new NotificationOverlay { GetToolbarHeight = () => ToolbarOffset, @@ -495,7 +497,7 @@ namespace osu.Game Origin = Anchor.TopRight, }, rightFloatingOverlayContent.Add, true); - loadComponentSingleFile(musicController = new MusicController + loadComponentSingleFile(new NowPlayingOverlay { GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index abbcec5094..d1086d589d 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -4,281 +4,87 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; 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.Effects; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Events; -using osu.Framework.Localisation; using osu.Framework.Threading; using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Music; using osu.Game.Rulesets.Mods; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays { - public class MusicController : OsuFocusedOverlayContainer + /// + /// Handles playback of the global music track. + /// + public class MusicController : Component { - private const float player_height = 130; - private const float transition_length = 800; - private const float progress_height = 10; - private const float bottom_black_area_height = 55; - - private Drawable background; - private ProgressBar progressBar; - - private IconButton prevButton; - private IconButton playButton; - private IconButton nextButton; - private IconButton playlistButton; - - private SpriteText title, artist; - - private PlaylistOverlay playlist; - - private BeatmapManager beatmaps; + [Resolved] + private BeatmapManager beatmaps { get; set; } private List beatmapSets; - private Container dragContainer; - private Container playerContainer; - public bool IsUserPaused { get; private set; } + /// + /// Fired when the global has changed. + /// Includes direction information for display purposes. + /// + public event Action TrackChanged; + [Resolved] - private Bindable beatmap { get; set; } + private IBindable beatmap { get; set; } [Resolved] private IBindable> mods { get; set; } - /// - /// Provide a source for the toolbar height. - /// - public Func GetToolbarHeight; - - public MusicController() - { - Width = 400; - Margin = new MarginPadding(10); - } - [BackgroundDependencyLoader] - private void load(Bindable beatmap, BeatmapManager beatmaps, OsuColour colours) + private void load() { - this.beatmaps = beatmaps; - - Children = new Drawable[] - { - dragContainer = new DragContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - playlist = new PlaylistOverlay - { - RelativeSizeAxes = Axes.X, - Y = player_height + 10, - OrderChanged = playlistOrderChanged - }, - playerContainer = new Container - { - RelativeSizeAxes = Axes.X, - Height = player_height, - Masking = true, - CornerRadius = 5, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(40), - Radius = 5, - }, - Children = new[] - { - background = new Background(), - title = new OsuSpriteText - { - Origin = Anchor.BottomCentre, - Anchor = Anchor.TopCentre, - Position = new Vector2(0, 40), - Font = OsuFont.GetFont(size: 25, italics: true), - Colour = Color4.White, - Text = @"Nothing to play", - }, - artist = new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Position = new Vector2(0, 45), - Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold, italics: true), - Colour = Color4.White, - Text = @"Nothing to play", - }, - new Container - { - Padding = new MarginPadding { Bottom = progress_height }, - Height = bottom_black_area_height, - RelativeSizeAxes = Axes.X, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5), - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Children = new[] - { - prevButton = new MusicIconButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Action = prev, - Icon = FontAwesome.Solid.StepBackward, - }, - playButton = new MusicIconButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(1.4f), - IconScale = new Vector2(1.4f), - Action = togglePause, - Icon = FontAwesome.Regular.PlayCircle, - }, - nextButton = new MusicIconButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Action = () => next(), - Icon = FontAwesome.Solid.StepForward, - }, - } - }, - playlistButton = new MusicIconButton - { - Origin = Anchor.Centre, - Anchor = Anchor.CentreRight, - Position = new Vector2(-bottom_black_area_height / 2, 0), - Icon = FontAwesome.Solid.Bars, - Action = () => playlist.ToggleVisibility(), - }, - } - }, - progressBar = new ProgressBar - { - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - Height = progress_height, - FillColour = colours.Yellow, - OnSeek = attemptSeek - } - }, - }, - } - } - }; - beatmapSets = beatmaps.GetAllUsableBeatmapSets(); beatmaps.ItemAdded += handleBeatmapAdded; beatmaps.ItemRemoved += handleBeatmapRemoved; - - playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } - private ScheduledDelegate seekDelegate; - - private void attemptSeek(double progress) + protected override void LoadComplete() { - seekDelegate?.Cancel(); - seekDelegate = Schedule(() => - { - if (!beatmap.Disabled) - current?.Track.Seek(progress); - }); + beatmap.BindValueChanged(beatmapChanged, true); + mods.BindValueChanged(_ => updateAudioAdjustments(), true); + base.LoadComplete(); } - private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index) + /// + /// Change the position of a in the current playlist. + /// + /// The beatmap to move. + /// The new position. + public void ChangeBeatmapSetPosition(BeatmapSetInfo beatmapSetInfo, int index) { beatmapSets.Remove(beatmapSetInfo); beatmapSets.Insert(index, beatmapSetInfo); } - private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => beatmapSets.Add(set)); + private void handleBeatmapAdded(BeatmapSetInfo set) => + Schedule(() => beatmapSets.Add(set)); - private void handleBeatmapRemoved(BeatmapSetInfo set) => Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID)); + private void handleBeatmapRemoved(BeatmapSetInfo set) => + Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID)); - protected override void LoadComplete() + private ScheduledDelegate seekDelegate; + + public void SeekTo(double position) { - beatmap.BindValueChanged(beatmapChanged, true); - beatmap.BindDisabledChanged(beatmapDisabledChanged, true); - mods.BindValueChanged(_ => updateAudioAdjustments(), true); - base.LoadComplete(); - } - - private void beatmapDisabledChanged(bool disabled) - { - if (disabled) - playlist.Hide(); - - playButton.Enabled.Value = !disabled; - prevButton.Enabled.Value = !disabled; - nextButton.Enabled.Value = !disabled; - playlistButton.Enabled.Value = !disabled; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - Height = dragContainer.Height; - - dragContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 }; - } - - protected override void Update() - { - base.Update(); - - if (pendingBeatmapSwitch != null) + seekDelegate?.Cancel(); + seekDelegate = Schedule(() => { - pendingBeatmapSwitch(); - pendingBeatmapSwitch = null; - } - - var track = current?.TrackLoaded ?? false ? current.Track : null; - - if (track?.IsDummyDevice == false) - { - progressBar.EndTime = track.Length; - progressBar.CurrentTime = track.CurrentTime; - - playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; - } - else - { - progressBar.CurrentTime = 0; - progressBar.EndTime = 1; - playButton.Icon = FontAwesome.Regular.PlayCircle; - } + if (!beatmap.Disabled) + current?.Track.Seek(position); + }); } - private void togglePause() + /// + /// Toggle pause / play. + /// + public void TogglePause() { var track = current?.Track; @@ -301,46 +107,57 @@ namespace osu.Game.Overlays } } - private void prev() + /// + /// Play the previous track. + /// + public void PrevTrack() { - queuedDirection = TransformDirection.Prev; + queuedDirection = TrackChangeDirection.Prev; var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault(); if (playable != null) { - beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); + if (beatmap is Bindable working) + working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); beatmap.Value.Track.Restart(); } } + /// + /// Play the next random or playlist track. + /// + public void NextTrack() => next(); + private void next(bool instant = false) { if (!instant) - queuedDirection = TransformDirection.Next; + queuedDirection = TrackChangeDirection.Next; var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); if (playable != null) { - beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); + if (beatmap is Bindable working) + working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); beatmap.Value.Track.Restart(); } } private WorkingBeatmap current; - private TransformDirection? queuedDirection; + + private TrackChangeDirection? queuedDirection; private void beatmapChanged(ValueChangedEvent beatmap) { - TransformDirection direction = TransformDirection.None; + TrackChangeDirection direction = TrackChangeDirection.None; if (current != null) { bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current.BeatmapInfo) ?? false; if (audioEquals) - direction = TransformDirection.None; + direction = TrackChangeDirection.None; else if (queuedDirection.HasValue) { direction = queuedDirection.Value; @@ -352,13 +169,13 @@ namespace osu.Game.Overlays var last = beatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); var next = beatmap.NewValue == null ? -1 : beatmapSets.TakeWhile(b => b.ID != beatmap.NewValue.BeatmapSetInfo?.ID).Count(); - direction = last > next ? TransformDirection.Prev : TransformDirection.Next; + direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next; } } - progressBar.CurrentTime = 0; + current = beatmap.NewValue; + TrackChanged?.Invoke(current, direction); - updateDisplay(current = beatmap.NewValue, direction); updateAudioAdjustments(); queuedDirection = null; @@ -376,167 +193,19 @@ namespace osu.Game.Overlays mod.ApplyToClock(track); } - private Action pendingBeatmapSwitch; - - private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction) + protected override void Dispose(bool isDisposing) { - // avoid using scheduler as our scheduler may not be run for a long time, holding references to beatmaps. - pendingBeatmapSwitch = delegate - { - // todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync() - Task.Run(() => - { - if (beatmap?.Beatmap == null) //this is not needed if a placeholder exists - { - title.Text = @"Nothing to play"; - artist.Text = @"Nothing to play"; - } - else - { - BeatmapMetadata metadata = beatmap.Metadata; - title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)); - artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)); - } - }); + base.Dispose(isDisposing); - LoadComponentAsync(new Background(beatmap) { Depth = float.MaxValue }, newBackground => - { - switch (direction) - { - case TransformDirection.Next: - newBackground.Position = new Vector2(400, 0); - newBackground.MoveToX(0, 500, Easing.OutCubic); - background.MoveToX(-400, 500, Easing.OutCubic); - break; - - case TransformDirection.Prev: - newBackground.Position = new Vector2(-400, 0); - newBackground.MoveToX(0, 500, Easing.OutCubic); - background.MoveToX(400, 500, Easing.OutCubic); - break; - } - - background.Expire(); - background = newBackground; - - playerContainer.Add(newBackground); - }); - }; + beatmaps.ItemAdded -= handleBeatmapAdded; + beatmaps.ItemRemoved -= handleBeatmapRemoved; } + } - protected override void PopIn() - { - base.PopIn(); - - this.FadeIn(transition_length, Easing.OutQuint); - dragContainer.ScaleTo(1, transition_length, Easing.OutElastic); - } - - protected override void PopOut() - { - base.PopOut(); - - this.FadeOut(transition_length, Easing.OutQuint); - dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint); - } - - private enum TransformDirection - { - None, - Next, - Prev - } - - private class MusicIconButton : IconButton - { - public MusicIconButton() - { - AutoSizeAxes = Axes.Both; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - HoverColour = colours.YellowDark.Opacity(0.6f); - FlashColour = colours.Yellow; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - // works with AutoSizeAxes above to make buttons autosize with the scale animation. - Content.AutoSizeAxes = Axes.None; - Content.Size = new Vector2(DEFAULT_BUTTON_SIZE); - } - } - - private class Background : BufferedContainer - { - private readonly Sprite sprite; - private readonly WorkingBeatmap beatmap; - - public Background(WorkingBeatmap beatmap = null) - { - this.beatmap = beatmap; - CacheDrawnFrameBuffer = true; - Depth = float.MaxValue; - RelativeSizeAxes = Axes.Both; - - Children = new Drawable[] - { - sprite = new Sprite - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(150), - FillMode = FillMode.Fill, - }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = bottom_black_area_height, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - Colour = Color4.Black.Opacity(0.5f) - } - }; - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); - } - } - - private class DragContainer : Container - { - protected override bool OnDragStart(DragStartEvent e) - { - return true; - } - - protected override bool OnDrag(DragEvent e) - { - Vector2 change = e.MousePosition - e.MouseDownPosition; - - // Diminish the drag distance as we go further to simulate "rubber band" feeling. - change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length; - - this.MoveTo(change); - return true; - } - - protected override bool OnDragEnd(DragEndEvent e) - { - this.MoveTo(Vector2.Zero, 800, Easing.OutElastic); - return base.OnDragEnd(e); - } - } - - /// - /// Play the next random or playlist track. - /// - public void NextTrack() => next(); + public enum TrackChangeDirection + { + None, + Next, + Prev } } diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs new file mode 100644 index 0000000000..98bad5323d --- /dev/null +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -0,0 +1,403 @@ +// 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.Threading.Tasks; +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.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Music; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays +{ + public class NowPlayingOverlay : OsuFocusedOverlayContainer + { + private const float player_height = 130; + private const float transition_length = 800; + private const float progress_height = 10; + private const float bottom_black_area_height = 55; + + private Drawable background; + private ProgressBar progressBar; + + private IconButton prevButton; + private IconButton playButton; + private IconButton nextButton; + private IconButton playlistButton; + + private SpriteText title, artist; + + private PlaylistOverlay playlist; + + private Container dragContainer; + private Container playerContainer; + + /// + /// Provide a source for the toolbar height. + /// + public Func GetToolbarHeight; + + [Resolved] + private MusicController musicController { get; set; } + + [Resolved] + private Bindable beatmap { get; set; } + + public NowPlayingOverlay() + { + Width = 400; + Margin = new MarginPadding(10); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Children = new Drawable[] + { + dragContainer = new DragContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + playlist = new PlaylistOverlay + { + RelativeSizeAxes = Axes.X, + Y = player_height + 10, + OrderChanged = musicController.ChangeBeatmapSetPosition + }, + playerContainer = new Container + { + RelativeSizeAxes = Axes.X, + Height = player_height, + Masking = true, + CornerRadius = 5, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(40), + Radius = 5, + }, + Children = new[] + { + background = new Background(), + title = new OsuSpriteText + { + Origin = Anchor.BottomCentre, + Anchor = Anchor.TopCentre, + Position = new Vector2(0, 40), + Font = OsuFont.GetFont(size: 25, italics: true), + Colour = Color4.White, + Text = @"Nothing to play", + }, + artist = new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Position = new Vector2(0, 45), + Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold, italics: true), + Colour = Color4.White, + Text = @"Nothing to play", + }, + new Container + { + Padding = new MarginPadding { Bottom = progress_height }, + Height = bottom_black_area_height, + RelativeSizeAxes = Axes.X, + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Children = new[] + { + prevButton = new MusicIconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Action = musicController.PrevTrack, + Icon = FontAwesome.Solid.StepBackward, + }, + playButton = new MusicIconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(1.4f), + IconScale = new Vector2(1.4f), + Action = musicController.TogglePause, + Icon = FontAwesome.Regular.PlayCircle, + }, + nextButton = new MusicIconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Action = musicController.NextTrack, + Icon = FontAwesome.Solid.StepForward, + }, + } + }, + playlistButton = new MusicIconButton + { + Origin = Anchor.Centre, + Anchor = Anchor.CentreRight, + Position = new Vector2(-bottom_black_area_height / 2, 0), + Icon = FontAwesome.Solid.Bars, + Action = () => playlist.ToggleVisibility(), + }, + } + }, + progressBar = new ProgressBar + { + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + Height = progress_height, + FillColour = colours.Yellow, + OnSeek = musicController.SeekTo + } + }, + }, + } + } + }; + + playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + beatmap.BindDisabledChanged(beatmapDisabledChanged, true); + + musicController.TrackChanged += trackChanged; + trackChanged(beatmap.Value); + } + + protected override void PopIn() + { + base.PopIn(); + + this.FadeIn(transition_length, Easing.OutQuint); + dragContainer.ScaleTo(1, transition_length, Easing.OutElastic); + } + + protected override void PopOut() + { + base.PopOut(); + + this.FadeOut(transition_length, Easing.OutQuint); + dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint); + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Height = dragContainer.Height; + dragContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 }; + } + + protected override void Update() + { + base.Update(); + + if (pendingBeatmapSwitch != null) + { + pendingBeatmapSwitch(); + pendingBeatmapSwitch = null; + } + + var track = beatmap.Value?.TrackLoaded ?? false ? beatmap.Value.Track : null; + + if (track?.IsDummyDevice == false) + { + progressBar.EndTime = track.Length; + progressBar.CurrentTime = track.CurrentTime; + + playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; + } + else + { + progressBar.CurrentTime = 0; + progressBar.EndTime = 1; + playButton.Icon = FontAwesome.Regular.PlayCircle; + } + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + musicController.TrackChanged -= trackChanged; + } + + private Action pendingBeatmapSwitch; + + private void trackChanged(WorkingBeatmap beatmap, TrackChangeDirection direction = TrackChangeDirection.None) + { + // avoid using scheduler as our scheduler may not be run for a long time, holding references to beatmaps. + pendingBeatmapSwitch = delegate + { + // todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync() + Task.Run(() => + { + if (beatmap?.Beatmap == null) //this is not needed if a placeholder exists + { + title.Text = @"Nothing to play"; + artist.Text = @"Nothing to play"; + } + else + { + BeatmapMetadata metadata = beatmap.Metadata; + title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)); + artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)); + } + }); + + LoadComponentAsync(new Background(beatmap) { Depth = float.MaxValue }, newBackground => + { + switch (direction) + { + case TrackChangeDirection.Next: + newBackground.Position = new Vector2(400, 0); + newBackground.MoveToX(0, 500, Easing.OutCubic); + background.MoveToX(-400, 500, Easing.OutCubic); + break; + + case TrackChangeDirection.Prev: + newBackground.Position = new Vector2(-400, 0); + newBackground.MoveToX(0, 500, Easing.OutCubic); + background.MoveToX(400, 500, Easing.OutCubic); + break; + } + + background.Expire(); + background = newBackground; + + playerContainer.Add(newBackground); + }); + }; + } + + private void beatmapDisabledChanged(bool disabled) + { + if (disabled) + playlist.Hide(); + + playButton.Enabled.Value = !disabled; + prevButton.Enabled.Value = !disabled; + nextButton.Enabled.Value = !disabled; + playlistButton.Enabled.Value = !disabled; + } + + private class MusicIconButton : IconButton + { + public MusicIconButton() + { + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + HoverColour = colours.YellowDark.Opacity(0.6f); + FlashColour = colours.Yellow; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + // works with AutoSizeAxes above to make buttons autosize with the scale animation. + Content.AutoSizeAxes = Axes.None; + Content.Size = new Vector2(DEFAULT_BUTTON_SIZE); + } + } + + private class Background : BufferedContainer + { + private readonly Sprite sprite; + private readonly WorkingBeatmap beatmap; + + public Background(WorkingBeatmap beatmap = null) + { + this.beatmap = beatmap; + CacheDrawnFrameBuffer = true; + Depth = float.MaxValue; + RelativeSizeAxes = Axes.Both; + + Children = new Drawable[] + { + sprite = new Sprite + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(150), + FillMode = FillMode.Fill, + }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = bottom_black_area_height, + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + Colour = Color4.Black.Opacity(0.5f) + } + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); + } + } + + private class DragContainer : Container + { + protected override bool OnDragStart(DragStartEvent e) + { + return true; + } + + protected override bool OnDrag(DragEvent e) + { + Vector2 change = e.MousePosition - e.MouseDownPosition; + + // Diminish the drag distance as we go further to simulate "rubber band" feeling. + change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length; + + this.MoveTo(change); + return true; + } + + protected override bool OnDragEnd(DragEndEvent e) + { + this.MoveTo(Vector2.Zero, 800, Easing.OutElastic); + return base.OnDragEnd(e); + } + } + } +} diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index f03df2ed93..b29aec5842 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Toolbar } [BackgroundDependencyLoader(true)] - private void load(MusicController music) + private void load(NowPlayingOverlay music) { StateContainer = music; } From 9aac5efa4e5bf8ff6374731b815ec5e26a8a75d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 14:38:49 +0900 Subject: [PATCH 251/645] Move logic out of OsuGame --- osu.Game/OsuGame.cs | 25 +------ osu.Game/Overlays/MusicController.cs | 74 +++++++++++++++++-- osu.Game/Overlays/NowPlayingOverlay.cs | 6 +- osu.Game/Overlays/OSD/MusicControllerToast.cs | 13 ---- 4 files changed, 70 insertions(+), 48 deletions(-) delete mode 100644 osu.Game/Overlays/OSD/MusicControllerToast.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ab7e5b19d1..0e804ecbaf 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -68,8 +68,6 @@ namespace osu.Game private BeatmapSetOverlay beatmapSetOverlay; - private OnScreenDisplay osd; - [Cached] private readonly ScreenshotManager screenshotManager = new ScreenshotManager(); @@ -469,7 +467,7 @@ namespace osu.Game }); loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add); - loadComponentSingleFile(osd = new OnScreenDisplay(), Add, true); + loadComponentSingleFile(new OnScreenDisplay(), Add, true); loadComponentSingleFile(musicController = new MusicController(), Add, true); @@ -734,27 +732,6 @@ namespace osu.Game case GlobalAction.ToggleGameplayMouseButtons: LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get(OsuSetting.MouseDisableButtons)); return true; - - case GlobalAction.MusicPlay: - if (!musicController.IsLoaded) return true; - - if (musicController.PlayTrack()) - osd.Display(new Overlays.OSD.MusicControllerToast(musicController.IsPlaying ? "Play track" : "Pause track")); - return true; - - case GlobalAction.MusicNext: - if (!musicController.IsLoaded) return true; - - if (musicController.NextTrack()) - osd.Display(new Overlays.OSD.MusicControllerToast("Next track")); - return true; - - case GlobalAction.MusicPrev: - if (!musicController.IsLoaded) return true; - - if (musicController.PreviousTrack()) - osd.Display(new Overlays.OSD.MusicControllerToast("Previous track")); - return true; } return false; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d1086d589d..14f7b574da 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -7,8 +7,11 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Input.Bindings; using osu.Framework.Threading; using osu.Game.Beatmaps; +using osu.Game.Input.Bindings; +using osu.Game.Overlays.OSD; using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays @@ -16,7 +19,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : Component + public class MusicController : Component, IKeyBindingHandler { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -37,6 +40,9 @@ namespace osu.Game.Overlays [Resolved] private IBindable> mods { get; set; } + [Resolved(canBeNull: true)] + private OnScreenDisplay onScreenDisplay { get; set; } + [BackgroundDependencyLoader] private void load() { @@ -58,11 +64,17 @@ namespace osu.Game.Overlays /// The beatmap to move. /// The new position. public void ChangeBeatmapSetPosition(BeatmapSetInfo beatmapSetInfo, int index) + { beatmapSets.Remove(beatmapSetInfo); beatmapSets.Insert(index, beatmapSetInfo); } + /// + /// Returns whether the current beatmap track is playing. + /// + public bool IsPlaying => beatmap.Value.Track.IsRunning; + private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => beatmapSets.Add(set)); @@ -84,15 +96,17 @@ namespace osu.Game.Overlays /// /// Toggle pause / play. /// - public void TogglePause() + public bool TogglePause() { var track = current?.Track; if (track == null) { - if (!beatmap.Disabled) - next(true); - return; + if (beatmap.Disabled) + return false; + + next(true); + return true; } if (track.IsRunning) @@ -105,12 +119,14 @@ namespace osu.Game.Overlays track.Start(); IsUserPaused = false; } + + return true; } /// /// Play the previous track. /// - public void PrevTrack() + public bool PrevTrack() { queuedDirection = TrackChangeDirection.Prev; @@ -121,15 +137,19 @@ namespace osu.Game.Overlays if (beatmap is Bindable working) working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); beatmap.Value.Track.Restart(); + + return true; } + + return false; } /// /// Play the next random or playlist track. /// - public void NextTrack() => next(); + public bool NextTrack() => next(); - private void next(bool instant = false) + private bool next(bool instant = false) { if (!instant) queuedDirection = TrackChangeDirection.Next; @@ -141,7 +161,10 @@ namespace osu.Game.Overlays if (beatmap is Bindable working) working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); beatmap.Value.Track.Restart(); + return true; } + + return false; } private WorkingBeatmap current; @@ -200,6 +223,41 @@ namespace osu.Game.Overlays beatmaps.ItemAdded -= handleBeatmapAdded; beatmaps.ItemRemoved -= handleBeatmapRemoved; } + + public bool OnPressed(GlobalAction action) + { + switch (action) + { + case GlobalAction.MusicPlay: + if (TogglePause()) + onScreenDisplay?.Display(new MusicControllerToast(IsPlaying ? "Play track" : "Pause track")); + return true; + + case GlobalAction.MusicNext: + if (NextTrack()) + onScreenDisplay?.Display(new MusicControllerToast("Next track")); + + return true; + + case GlobalAction.MusicPrev: + if (PrevTrack()) + onScreenDisplay?.Display(new MusicControllerToast("Previous track")); + + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; + + public class MusicControllerToast : Toast + { + public MusicControllerToast(string action) + : base("Music Playback", action, string.Empty) + { + } + } } public enum TrackChangeDirection diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 98bad5323d..f14adcb53d 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -138,7 +138,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = musicController.PrevTrack, + Action = () => musicController.PrevTrack(), Icon = FontAwesome.Solid.StepBackward, }, playButton = new MusicIconButton @@ -147,14 +147,14 @@ namespace osu.Game.Overlays Origin = Anchor.Centre, Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), - Action = musicController.TogglePause, + Action = () => musicController.TogglePause(), Icon = FontAwesome.Regular.PlayCircle, }, nextButton = new MusicIconButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = musicController.NextTrack, + Action = () => musicController.NextTrack(), Icon = FontAwesome.Solid.StepForward, }, } diff --git a/osu.Game/Overlays/OSD/MusicControllerToast.cs b/osu.Game/Overlays/OSD/MusicControllerToast.cs deleted file mode 100644 index d9e0ad2c07..0000000000 --- a/osu.Game/Overlays/OSD/MusicControllerToast.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Overlays.OSD -{ - public class MusicControllerToast : Toast - { - public MusicControllerToast(string value) - : base("Music Playback", value, "") - { - } - } -} From de1ab56a2c28e408879d273fde84c509d91c31cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 14:45:27 +0900 Subject: [PATCH 252/645] Fix potential nullref on disposal --- osu.Game/Overlays/MusicController.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d1086d589d..681e318c92 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -197,8 +197,11 @@ namespace osu.Game.Overlays { base.Dispose(isDisposing); - beatmaps.ItemAdded -= handleBeatmapAdded; - beatmaps.ItemRemoved -= handleBeatmapRemoved; + if (beatmaps != null) + { + beatmaps.ItemAdded -= handleBeatmapAdded; + beatmaps.ItemRemoved -= handleBeatmapRemoved; + } } } From 2cbdf8c01c3044a028a876e6fd9753996b4b34fe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 14:46:57 +0900 Subject: [PATCH 253/645] Update public methods in line with future usage --- osu.Game/Overlays/MusicController.cs | 35 ++++++++++++++++++++------ osu.Game/Overlays/NowPlayingOverlay.cs | 6 ++--- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 681e318c92..da9c34238e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -63,6 +63,11 @@ namespace osu.Game.Overlays beatmapSets.Insert(index, beatmapSetInfo); } + /// + /// Returns whether the current beatmap track is playing. + /// + public bool IsPlaying => beatmap.Value.Track.IsRunning; + private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => beatmapSets.Add(set)); @@ -84,15 +89,18 @@ namespace osu.Game.Overlays /// /// Toggle pause / play. /// - public void TogglePause() + /// Whether the operation was successful. + public bool TogglePause() { var track = current?.Track; if (track == null) { - if (!beatmap.Disabled) - next(true); - return; + if (beatmap.Disabled) + return false; + + next(true); + return true; } if (track.IsRunning) @@ -105,12 +113,15 @@ namespace osu.Game.Overlays track.Start(); IsUserPaused = false; } + + return true; } /// /// Play the previous track. /// - public void PrevTrack() + /// Whether the operation was successful. + public bool PrevTrack() { queuedDirection = TrackChangeDirection.Prev; @@ -121,15 +132,20 @@ namespace osu.Game.Overlays if (beatmap is Bindable working) working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); beatmap.Value.Track.Restart(); + + return true; } + + return false; } /// /// Play the next random or playlist track. /// - public void NextTrack() => next(); + /// Whether the operation was successful. + public bool NextTrack() => next(); - private void next(bool instant = false) + private bool next(bool instant = false) { if (!instant) queuedDirection = TrackChangeDirection.Next; @@ -141,7 +157,10 @@ namespace osu.Game.Overlays if (beatmap is Bindable working) working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); beatmap.Value.Track.Restart(); + return true; } + + return false; } private WorkingBeatmap current; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 98bad5323d..f14adcb53d 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -138,7 +138,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = musicController.PrevTrack, + Action = () => musicController.PrevTrack(), Icon = FontAwesome.Solid.StepBackward, }, playButton = new MusicIconButton @@ -147,14 +147,14 @@ namespace osu.Game.Overlays Origin = Anchor.Centre, Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), - Action = musicController.TogglePause, + Action = () => musicController.TogglePause(), Icon = FontAwesome.Regular.PlayCircle, }, nextButton = new MusicIconButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = musicController.NextTrack, + Action = () => musicController.NextTrack(), Icon = FontAwesome.Solid.StepForward, }, } From 81f8b5f325702b5d1ae227006b9c26b7d2dd2834 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 14:52:51 +0900 Subject: [PATCH 254/645] Fix merge issue --- osu.Game/Overlays/MusicController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index b055c7ef1b..91220907a0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -64,7 +64,6 @@ namespace osu.Game.Overlays /// The beatmap to move. /// The new position. public void ChangeBeatmapSetPosition(BeatmapSetInfo beatmapSetInfo, int index) - { beatmapSets.Remove(beatmapSetInfo); beatmapSets.Insert(index, beatmapSetInfo); From b942192e004c95891e02048d007077836c51f9b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 15:04:04 +0900 Subject: [PATCH 255/645] Fix remaining nullref --- osu.Game/Overlays/NowPlayingOverlay.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index f14adcb53d..a3243a655e 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -247,13 +247,6 @@ namespace osu.Game.Overlays } } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - musicController.TrackChanged -= trackChanged; - } - private Action pendingBeatmapSwitch; private void trackChanged(WorkingBeatmap beatmap, TrackChangeDirection direction = TrackChangeDirection.None) @@ -313,6 +306,14 @@ namespace osu.Game.Overlays playlistButton.Enabled.Value = !disabled; } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (musicController != null) + musicController.TrackChanged -= trackChanged; + } + private class MusicIconButton : IconButton { public MusicIconButton() From 8ef4b2a0f6a1467c0e8fd9dec63e35d63d1df942 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 13 Aug 2019 11:29:48 +0300 Subject: [PATCH 256/645] Hide NotificationOverlay --- osu.Desktop/Overlays/VersionManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 1f1d2cea5f..51e801c185 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -113,13 +113,14 @@ namespace osu.Desktop.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours, ChangelogOverlay changelog) + private void load(OsuColour colours, ChangelogOverlay changelog, NotificationOverlay notificationOverlay) { Icon = FontAwesome.Solid.CheckSquare; IconBackgound.Colour = colours.BlueDark; Activated = delegate { + notificationOverlay.Hide(); changelog.ShowBuild(OsuGameBase.CLIENT_STREAM_NAME, version); return true; }; From 6b57c9801d8e9a97d5d520f4e0705530190bd216 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 17:32:43 +0900 Subject: [PATCH 257/645] Cull some unnecessary whitespace --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index dafea70092..ea7a713e0e 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -177,9 +177,7 @@ namespace osu.Game.Screens.Multi.Match public override bool OnExiting(IScreen next) { RoomManager?.PartRoom(); - Mods.Value = Array.Empty(); - previewTrackManager.StopAnyPlaying(this); return base.OnExiting(next); From 92c2dafa1281048437cf7651caf61643b5b302d7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 17:34:16 +0900 Subject: [PATCH 258/645] Tighten accessibility --- osu.Game/Screens/Multi/Match/Components/Header.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 7f2b1278b7..a52d43acf4 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -25,12 +25,12 @@ namespace osu.Game.Screens.Multi.Match.Components { public const float HEIGHT = 200; - public MatchTabControl Tabs; + public readonly BindableBool ShowBeatmapPanel = new BindableBool(); + + public MatchTabControl Tabs { get; private set; } public Action RequestBeatmapSelection; - public BindableBool ShowBeatmapPanel = new BindableBool(); - private MatchBeatmapPanel beatmapPanel; public Header() From 7c9c9f1ce1f062f667ec38e6d2c300332cbfe857 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 17:38:21 +0900 Subject: [PATCH 259/645] Simplify caching --- .../Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs | 8 +------- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs index f148170847..68ad0b42b4 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs @@ -13,6 +13,7 @@ using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Multiplayer { + [Cached(typeof(IPreviewTrackOwner))] public class TestSceneMatchBeatmapPanel : MultiplayerTestScene, IPreviewTrackOwner { public override IReadOnlyList RequiredTypes => new[] @@ -48,12 +49,5 @@ namespace osu.Game.Tests.Visual.Multiplayer previewTrackManager.StopAnyPlaying(this); }); } - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(this); - return dependencies; - } } } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index ea7a713e0e..f3e10db444 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -19,6 +19,7 @@ using PlaylistItem = osu.Game.Online.Multiplayer.PlaylistItem; namespace osu.Game.Screens.Multi.Match { + [Cached(typeof(IPreviewTrackOwner))] public class MatchSubScreen : MultiplayerSubScreen, IPreviewTrackOwner { public override bool DisallowExternalBeatmapRulesetChanges => true; @@ -237,13 +238,6 @@ namespace osu.Game.Screens.Multi.Match } } - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(this); - return dependencies; - } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From f2e596de1640c4939ada0d6c18d2b71e89295679 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 08:54:17 +0000 Subject: [PATCH 260/645] Bump ppy.osu.Framework from 2019.809.0 to 2019.813.0 Bumps [ppy.osu.Framework](https://github.com/ppy/osu-framework) from 2019.809.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.809.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b5266fd75d..e149c4338d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 103d89cadc..2bb95d0772 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,7 +105,7 @@ - + From e356cc8d9ef288056745f4b0b1899c0503284ee5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 17:57:16 +0900 Subject: [PATCH 261/645] Refactor MatchBeatmapPanel for thread safety --- .../Match/Components/MatchBeatmapPanel.cs | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index 7939b18e97..7c1fe91393 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -1,8 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Threading; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Direct; @@ -18,6 +20,7 @@ namespace osu.Game.Screens.Multi.Match.Components [Resolved] private RulesetStore rulesets { get; set; } + private CancellationTokenSource loadCancellation; private GetBeatmapSetRequest request; private DirectGridPanel panel; @@ -29,30 +32,31 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - CurrentItem.BindValueChanged(item => + CurrentItem.BindValueChanged(item => loadNewPanel(item.NewValue?.Beatmap), true); + } + + private void loadNewPanel(BeatmapInfo beatmap) + { + loadCancellation?.Cancel(); + request?.Cancel(); + + panel?.FadeOut(200); + panel?.Expire(); + panel = null; + + if (beatmap?.OnlineBeatmapID == null) + return; + + loadCancellation = new CancellationTokenSource(); + + request = new GetBeatmapSetRequest(beatmap.OnlineBeatmapID.Value, BeatmapSetLookupType.BeatmapId); + request.Success += res => Schedule(() => { - request?.Cancel(); + panel = new DirectGridPanel(res.ToBeatmapSet(rulesets)); + LoadComponentAsync(panel, AddInternal, loadCancellation.Token); + }); - if (panel != null) - { - panel.FadeOut(200); - panel.Expire(); - panel = null; - } - - var onlineId = item.NewValue?.Beatmap.OnlineBeatmapID; - - if (onlineId.HasValue) - { - request = new GetBeatmapSetRequest(onlineId.Value, BeatmapSetLookupType.BeatmapId); - request.Success += beatmap => - { - panel = new DirectGridPanel(beatmap.ToBeatmapSet(rulesets)); - LoadComponentAsync(panel, AddInternal); - }; - api.Queue(request); - } - }, true); + api.Queue(request); } } } From fe7bc824df6b2eda0b52e48517b37535363f4537 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 09:00:20 +0000 Subject: [PATCH 262/645] Bump ppy.osu.Framework.NativeLibs from 2019.307.0 to 2019.813.0 Bumps [ppy.osu.Framework.NativeLibs](https://github.com/ppy/osu-framework) from 2019.307.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.307.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 103d89cadc..09b9da142c 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -111,6 +111,6 @@ - + From 6b3eeb88fc9dac58b70f60991aceb147aab67895 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 09:00:43 +0000 Subject: [PATCH 263/645] Bump ppy.osu.Framework.iOS from 2019.809.0 to 2019.813.0 Bumps [ppy.osu.Framework.iOS](https://github.com/ppy/osu-framework) from 2019.809.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.809.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 103d89cadc..d444a5893f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -106,7 +106,7 @@ - + From 91068dc5709585c1c4175acd45fca05f581ff583 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 09:01:00 +0000 Subject: [PATCH 264/645] Bump ppy.osu.Framework.Android from 2019.809.0 to 2019.813.0 Bumps [ppy.osu.Framework.Android](https://github.com/ppy/osu-framework) from 2019.809.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.809.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android.props b/osu.Android.props index 721d341c08..85741fcf84 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -63,6 +63,6 @@ - + From 5963f7d9147e7ead009611f4b90b27e67506433b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 19:52:40 +0900 Subject: [PATCH 265/645] Update comment --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 8073200c47..b70072a222 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -127,7 +127,7 @@ namespace osu.Game.Input.Bindings [Description("Quick exit (Hold)")] QuickExit, - // Game-wide beatmap jukebox keybindings + // Game-wide beatmap msi ccotolle keybindings [Description("Next track")] MusicNext, From 2cd0015735fa28996b2c374a3d632e76a019c503 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 23:27:27 +0900 Subject: [PATCH 266/645] Attempt to appease apple with some plist keys --- osu.iOS/Info.plist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 0775d1522d..a118b329aa 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -31,6 +31,10 @@ UIStatusBarHidden + NSCameraUsageDescription + We don't really use the camera. + NSMicrophoneUsageDescription + We don't really use the microphone. UISupportedInterfaceOrientations UIInterfaceOrientationPortrait From b6bc84af2c886f964c5aafada6cd82c2065a3bee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 14 Aug 2019 10:52:26 +0900 Subject: [PATCH 267/645] Fix chat context menus displaying out-of-bounds --- osu.Game/Overlays/Chat/DrawableChannel.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 8d56e250fc..928201581a 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -32,16 +32,16 @@ namespace osu.Game.Overlays.Chat { Children = new Drawable[] { - scroll = new OsuScrollContainer + new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, - // Some chat lines have effects that slightly protrude to the bottom, - // which we do not want to mask away, hence the padding. - Padding = new MarginPadding { Bottom = 5 }, - Child = new OsuContextMenuContainer + Masking = true, + Child = scroll = new OsuScrollContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.Both, + // Some chat lines have effects that slightly protrude to the bottom, + // which we do not want to mask away, hence the padding. + Padding = new MarginPadding { Bottom = 5 }, Child = ChatLineFlow = new ChatLineContainer { Padding = new MarginPadding { Left = 20, Right = 20 }, From 52f42ddadeed12febc7e23897bd243b42448d982 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 14 Aug 2019 10:53:47 +0900 Subject: [PATCH 268/645] Use child instead of children --- osu.Game/Overlays/Chat/DrawableChannel.cs | 31 ++++++++++------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 928201581a..f831266b1b 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -30,27 +30,24 @@ namespace osu.Game.Overlays.Chat [BackgroundDependencyLoader] private void load() { - Children = new Drawable[] + Child = new OsuContextMenuContainer { - new OsuContextMenuContainer + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = scroll = new OsuScrollContainer { RelativeSizeAxes = Axes.Both, - Masking = true, - Child = scroll = new OsuScrollContainer + // Some chat lines have effects that slightly protrude to the bottom, + // which we do not want to mask away, hence the padding. + Padding = new MarginPadding { Bottom = 5 }, + Child = ChatLineFlow = new ChatLineContainer { - RelativeSizeAxes = Axes.Both, - // Some chat lines have effects that slightly protrude to the bottom, - // which we do not want to mask away, hence the padding. - Padding = new MarginPadding { Bottom = 5 }, - Child = ChatLineFlow = new ChatLineContainer - { - Padding = new MarginPadding { Left = 20, Right = 20 }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - } - }, - } + Padding = new MarginPadding { Left = 20, Right = 20 }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + } + }, }; newMessagesArrived(Channel.Messages); From 3a79a4149a430e9f5dec5ab7a47bf425a9cd7cb0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 14 Aug 2019 15:19:21 +0900 Subject: [PATCH 269/645] Disable music controls when beatmap is disabled --- osu.Game/Overlays/MusicController.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 91220907a0..f6208c46cb 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -231,6 +231,9 @@ namespace osu.Game.Overlays public bool OnPressed(GlobalAction action) { + if (beatmap.Disabled) + return false; + switch (action) { case GlobalAction.MusicPlay: From 840a142e98a592ef93d0d8ad1dfbf3796005a039 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2019 12:16:32 +0000 Subject: [PATCH 270/645] Bump ppy.osu.Framework.iOS from 2019.813.0 to 2019.814.0 Bumps [ppy.osu.Framework.iOS](https://github.com/ppy/osu-framework) from 2019.813.0 to 2019.814.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.813.0...2019.814.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 9ea5081658..d50f23c2c2 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -119,7 +119,7 @@ - + From e36e2a899ae1602dc303246eaae217abfd700421 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2019 12:16:53 +0000 Subject: [PATCH 271/645] Bump ppy.osu.Framework.Android from 2019.813.0 to 2019.814.0 Bumps [ppy.osu.Framework.Android](https://github.com/ppy/osu-framework) from 2019.813.0 to 2019.814.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.813.0...2019.814.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android.props b/osu.Android.props index 065c66ebba..7bc60ef884 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + From 3379672a43a9f1f0536e85db3887b51653b12a22 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2019 12:17:17 +0000 Subject: [PATCH 272/645] Bump ppy.osu.Framework from 2019.813.0 to 2019.814.0 Bumps [ppy.osu.Framework](https://github.com/ppy/osu-framework) from 2019.813.0 to 2019.814.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.813.0...2019.814.0) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e149c4338d..f5e4d4b1fb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9ea5081658..e831fdc7cb 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,7 +118,7 @@ - + From f849b4ce54e4b8e75a8286192b4dfbae24f80e25 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Wed, 14 Aug 2019 19:49:32 +0200 Subject: [PATCH 273/645] Make autoplay unpress sooner, if needed --- .../Replays/TaikoAutoGenerator.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 422ba748e3..60fd88882e 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -113,14 +113,21 @@ namespace osu.Game.Rulesets.Taiko.Replays else throw new InvalidOperationException("Unknown hit object type."); - Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); - if (i < Beatmap.HitObjects.Count - 1) { - double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000; + var nextHitObject = Beatmap.HitObjects[i + 1]; + + if (!(nextHitObject.StartTime < endTime + KEY_UP_DELAY)) + Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); + + double waitTime = nextHitObject.StartTime - 1000; if (waitTime > endTime) Frames.Add(new TaikoReplayFrame(waitTime)); } + else + { + Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); + } hitButton = !hitButton; } From e567e81981d6f940a9de97d68a3bab496e6d29cc Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Wed, 14 Aug 2019 20:10:52 +0200 Subject: [PATCH 274/645] Refactoring --- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 60fd88882e..014511d090 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -117,7 +117,7 @@ namespace osu.Game.Rulesets.Taiko.Replays { var nextHitObject = Beatmap.HitObjects[i + 1]; - if (!(nextHitObject.StartTime < endTime + KEY_UP_DELAY)) + if (nextHitObject.StartTime > endTime + KEY_UP_DELAY) Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); double waitTime = nextHitObject.StartTime - 1000; From ba539abac77484c3dd5103333e84231a46d81cf2 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Wed, 14 Aug 2019 21:05:24 +0200 Subject: [PATCH 275/645] Refactoring --- .../Replays/TaikoAutoGenerator.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 014511d090..a46ecab6f0 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -113,21 +113,23 @@ namespace osu.Game.Rulesets.Taiko.Replays else throw new InvalidOperationException("Unknown hit object type."); + TaikoHitObject nextHitObject; if (i < Beatmap.HitObjects.Count - 1) + nextHitObject = Beatmap.HitObjects[i + 1]; + else + nextHitObject = null; + + bool canDelayKeyUp = nextHitObject != null && nextHitObject.StartTime > endTime + KEY_UP_DELAY; + + if (canDelayKeyUp) + Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); + + if (nextHitObject != null) { - var nextHitObject = Beatmap.HitObjects[i + 1]; - - if (nextHitObject.StartTime > endTime + KEY_UP_DELAY) - Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); - double waitTime = nextHitObject.StartTime - 1000; if (waitTime > endTime) Frames.Add(new TaikoReplayFrame(waitTime)); } - else - { - Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); - } hitButton = !hitButton; } From 07e7e1187c980f9e2962c013203869d3b4c774bc Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 15 Aug 2019 05:30:35 +0300 Subject: [PATCH 276/645] Add adjustment function in SkinnableSound --- osu.Game/Skinning/SkinnableSound.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8e2b5cec98..205f25bf9d 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -37,6 +37,8 @@ namespace osu.Game.Skinning public void Play() => channels?.ForEach(c => c.Play()); + public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) => channels?.ForEach(c => c.AddAdjustment(type, adjustBindable)); + public override bool IsPresent => false; // We don't need to receive updates. protected override void SkinChanged(ISkinSource skin, bool allowFallback) From cfa569b226ab742f9527615852a64373a5fd7cb6 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 15 Aug 2019 05:35:47 +0300 Subject: [PATCH 277/645] Add looping field and fix build --- osu.Game/Skinning/SkinnableSound.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 205f25bf9d..f9dd39d04d 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Audio; @@ -35,6 +36,8 @@ namespace osu.Game.Skinning this.audio = audio; } + public bool Looping; + public void Play() => channels?.ForEach(c => c.Play()); public void AddAdjustment(AdjustableProperty type, BindableDouble adjustBindable) => channels?.ForEach(c => c.AddAdjustment(type, adjustBindable)); @@ -60,6 +63,7 @@ namespace osu.Game.Skinning if (ch == null) continue; + ch.Looping = Looping; ch.Volume.Value = info.Volume / 100.0; return ch; } From f355cff8bcc9c048f793d2032ebb719be89a6358 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 12:11:54 +0900 Subject: [PATCH 278/645] Apply reviews --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 167 +++++++++--------- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 2 +- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- .../Screens/Multi/Components/ModeTypeInfo.cs | 2 +- .../Carousel/DrawableCarouselBeatmap.cs | 2 +- .../Carousel/DrawableCarouselBeatmapSet.cs | 2 +- 6 files changed, 88 insertions(+), 89 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index f5c8d0d029..b29303ad1e 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables { private readonly RulesetInfo ruleset; - public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, Boolean shouldShowTooltip = false) + public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null, bool shouldShowTooltip = true) : base(beatmap) { if (beatmap == null) @@ -39,89 +39,6 @@ namespace osu.Game.Beatmaps.Drawables public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(AccentColour); - public class DifficultyIconTooltip : VisibilityContainer, ITooltip - { - private readonly OsuSpriteText difficultyName, starRating; - private readonly Box background; - - public string TooltipText { get; set; } - - public DifficultyIconTooltip(Color4 accentColour) - { - AutoSizeAxes = Axes.Both; - Masking = true; - CornerRadius = 5; - - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Padding = new MarginPadding(10), - Children = new Drawable[] - { - difficultyName = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Direction = FillDirection.Horizontal, - Children = new Drawable[] - { - starRating = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), - Colour = accentColour - }, - new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Margin = new MarginPadding { Left = 4 }, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(12), - Colour = accentColour, - }, - } - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.GreyCarmineDark; - } - - public void Refresh() - { - var info = TooltipText.Split('$'); - difficultyName.Text = info[0]; - starRating.Text = info[1]; - } - - public void Move(Vector2 pos) => Position = pos; - - protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); - - protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); - } - [BackgroundDependencyLoader] private void load() { @@ -156,5 +73,87 @@ namespace osu.Game.Beatmaps.Drawables } }; } + + private class DifficultyIconTooltip : VisibilityContainer, ITooltip + { + private readonly OsuSpriteText difficultyName, starRating; + private readonly Box background; + + public string TooltipText { get; set; } + + public DifficultyIconTooltip(Color4 difficultyColour) + { + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 5; + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Padding = new MarginPadding(10), + Children = new Drawable[] + { + difficultyName = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Direction = FillDirection.Horizontal, + Colour = difficultyColour, + Children = new Drawable[] + { + starRating = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular), + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Left = 4 }, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }, + } + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreyCarmineDark; + } + + public void Refresh() + { + var info = TooltipText.Split('$'); + difficultyName.Text = info[0]; + starRating.Text = info[1]; + } + + public void Move(Vector2 pos) => Position = pos; + + protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); + } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index baf702eebc..104315f1c2 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -234,7 +234,7 @@ namespace osu.Game.Overlays.BeatmapSet Colour = Color4.Black.Opacity(0.5f), }, }, - icon = new DifficultyIcon(beatmap) + icon = new DifficultyIcon(beatmap, shouldShowTooltip: false) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 41c565090f..8199d80528 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -143,7 +143,7 @@ namespace osu.Game.Overlays.Direct var icons = new List(); foreach (var b in SetInfo.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty)) - icons.Add(new DifficultyIcon(b, null, true)); + icons.Add(new DifficultyIcon(b)); return icons; } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 434c5c443b..6080458aec 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Components if (item?.Beatmap != null) { drawableRuleset.FadeIn(transition_duration); - drawableRuleset.Child = new DifficultyIcon(item.Beatmap, item.Ruleset, true) { Size = new Vector2(height) }; + drawableRuleset.Child = new DifficultyIcon(item.Beatmap, item.Ruleset) { Size = new Vector2(height) }; } else drawableRuleset.FadeOut(transition_duration); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 0a20f2aa6d..fba7a328c1 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -82,7 +82,7 @@ namespace osu.Game.Screens.Select.Carousel Origin = Anchor.CentreLeft, Children = new Drawable[] { - new DifficultyIcon(beatmap) + new DifficultyIcon(beatmap, shouldShowTooltip: false) { Scale = new Vector2(1.8f), }, diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 86ae6a2e58..4ceb82d4cc 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -197,7 +197,7 @@ namespace osu.Game.Screens.Select.Carousel private readonly BindableBool filtered = new BindableBool(); public FilterableDifficultyIcon(CarouselBeatmap item) - : base(item.Beatmap, shouldShowTooltip: true) + : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); From e73a9c2748ad4e0c8b7c5ef263f7ccad14f4268e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 14:00:12 +0900 Subject: [PATCH 279/645] Fix song select context menus displaying off-screen --- osu.Game/Screens/Select/BeatmapCarousel.cs | 26 +++++++++++++--------- osu.Game/Screens/Select/SongSelect.cs | 1 - 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 7366fa8c17..6fda81e47d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -24,7 +24,7 @@ using osu.Game.Screens.Select.Carousel; namespace osu.Game.Screens.Select { - public class BeatmapCarousel : OsuScrollContainer + public class BeatmapCarousel : CompositeDrawable { private const float bleed_top = FilterControl.HEIGHT; private const float bleed_bottom = Footer.HEIGHT; @@ -61,6 +61,8 @@ namespace osu.Game.Screens.Select /// public bool BeatmapSetsLoaded { get; private set; } + private readonly OsuScrollContainer scroll; + private IEnumerable beatmapSets => root.Children.OfType(); public IEnumerable BeatmapSets @@ -110,13 +112,17 @@ namespace osu.Game.Screens.Select public BeatmapCarousel() { root = new CarouselRoot(this); - Child = new OsuContextMenuContainer + InternalChild = new OsuContextMenuContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = scrollableContent = new Container + RelativeSizeAxes = Axes.Both, + Child = scroll = new OsuScrollContainer { - RelativeSizeAxes = Axes.X, + Masking = false, + RelativeSizeAxes = Axes.Both, + Child = scrollableContent = new Container + { + RelativeSizeAxes = Axes.X, + } } }; } @@ -127,7 +133,7 @@ namespace osu.Game.Screens.Select config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm); config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled); - RightClickScrollingEnabled.ValueChanged += enabled => RightMouseScrollbar = enabled.NewValue; + RightClickScrollingEnabled.ValueChanged += enabled => scroll.RightMouseScrollbar = enabled.NewValue; RightClickScrollingEnabled.TriggerChange(); loadBeatmapSets(beatmaps.GetAllUsableBeatmapSetsEnumerable()); @@ -351,12 +357,12 @@ namespace osu.Game.Screens.Select /// /// The position of the lower visible bound with respect to the current scroll position. /// - private float visibleBottomBound => Current + DrawHeight + bleed_bottom; + private float visibleBottomBound => scroll.Current + DrawHeight + bleed_bottom; /// /// The position of the upper visible bound with respect to the current scroll position. /// - private float visibleUpperBound => Current - bleed_top; + private float visibleUpperBound => scroll.Current - bleed_top; public void FlushPendingFilterOperations() { @@ -628,7 +634,7 @@ namespace osu.Game.Screens.Select private void updateScrollPosition() { - if (scrollTarget != null) ScrollTo(scrollTarget.Value); + if (scrollTarget != null) scroll.ScrollTo(scrollTarget.Value); scrollPositionCache.Validate(); } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 7dd934f91a..8340814db9 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -157,7 +157,6 @@ namespace osu.Game.Screens.Select }, Child = Carousel = new BeatmapCarousel { - Masking = false, RelativeSizeAxes = Axes.Both, Size = new Vector2(1 - wedged_container_size.X, 1), Anchor = Anchor.CentreRight, From f7a92487ef548c060b8af695efe9d49fe76a9b6b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 14:09:30 +0900 Subject: [PATCH 280/645] Fix checkbox sounds playing too often --- .../Graphics/UserInterface/OsuCheckbox.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs index 47324ee646..6593531099 100644 --- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs @@ -72,17 +72,11 @@ namespace osu.Game.Graphics.UserInterface Current.DisabledChanged += disabled => labelText.Alpha = Nub.Alpha = disabled ? 0.3f : 1; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load(AudioManager audio) { - base.LoadComplete(); - - Current.ValueChanged += enabled => - { - if (enabled.NewValue) - sampleChecked?.Play(); - else - sampleUnchecked?.Play(); - }; + sampleChecked = audio.Samples.Get(@"UI/check-on"); + sampleUnchecked = audio.Samples.Get(@"UI/check-off"); } protected override bool OnHover(HoverEvent e) @@ -99,11 +93,13 @@ namespace osu.Game.Graphics.UserInterface base.OnHoverLost(e); } - [BackgroundDependencyLoader] - private void load(AudioManager audio) + protected override void OnUserChange(bool value) { - sampleChecked = audio.Samples.Get(@"UI/check-on"); - sampleUnchecked = audio.Samples.Get(@"UI/check-off"); + base.OnUserChange(value); + if (value) + sampleChecked?.Play(); + else + sampleUnchecked?.Play(); } } } From 9e13a6aeae1a2a0259f926cf3c0d4db284d04315 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 14:32:31 +0900 Subject: [PATCH 281/645] Fix newlines being considered in user profile content --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index e7f7c2f490..691e18e6bf 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -138,6 +138,9 @@ namespace osu.Game.Overlays.Profile.Header private void tryAddInfo(IconUsage icon, string content, string link = null) { + // newlines could be contained in API returned user content. + content = content?.Replace("\n", " "); + if (string.IsNullOrEmpty(content)) return; bottomLinkContainer.AddIcon(icon, text => From 8f638879728bff8c8812253ba24476d7721e176d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 14:38:49 +0900 Subject: [PATCH 282/645] Make use of existing null check --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 691e18e6bf..158641d816 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -138,11 +138,11 @@ namespace osu.Game.Overlays.Profile.Header private void tryAddInfo(IconUsage icon, string content, string link = null) { - // newlines could be contained in API returned user content. - content = content?.Replace("\n", " "); - if (string.IsNullOrEmpty(content)) return; + // newlines could be contained in API returned user content. + content = content.Replace("\n", " "); + bottomLinkContainer.AddIcon(icon, text => { text.Font = text.Font.With(size: 10); From ef5ed915e5b51781117bcb514ffe8a2751a3ac86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Aug 2019 17:14:00 +0900 Subject: [PATCH 283/645] Reduce delay for hold-to-confirm controls --- .../Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs | 7 ++++++- osu.Game/Graphics/Containers/HoldToConfirmContainer.cs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs index 7e6cf1285e..a017418e3a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Screens.Menu; @@ -12,7 +13,11 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneHoldToConfirmOverlay : OsuTestScene { - public override IReadOnlyList RequiredTypes => new[] { typeof(ExitConfirmOverlay) }; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ExitConfirmOverlay), + typeof(HoldToConfirmContainer), + }; public TestSceneHoldToConfirmOverlay() { diff --git a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs index cda5e150de..18a4241a79 100644 --- a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs +++ b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs @@ -12,7 +12,7 @@ namespace osu.Game.Graphics.Containers { public Action Action; - private const int activate_delay = 400; + private const int activate_delay = 200; private const int fadeout_delay = 200; private bool fired; From 8c67f58e2d1179f5403e94933dea70df65d90e75 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 15 Aug 2019 18:25:31 +0900 Subject: [PATCH 284/645] Disable frame-stable playback in the editor --- osu.Game/Rulesets/Edit/DrawableEditRuleset.cs | 6 ++++++ osu.Game/Rulesets/UI/DrawableRuleset.cs | 9 +++++++++ osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs index 2200caeb20..e85ebb5f3a 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditRuleset.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -57,7 +58,12 @@ namespace osu.Game.Rulesets.Edit this.drawableRuleset = drawableRuleset; InternalChild = drawableRuleset; + } + [BackgroundDependencyLoader] + private void load() + { + drawableRuleset.FrameStablePlayback = false; Playfield.DisplayJudgements.Value = false; } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index ac81fdc719..eb14bd1f24 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -62,6 +62,15 @@ namespace osu.Game.Rulesets.UI public override GameplayClock FrameStableClock => frameStabilityContainer.GameplayClock; + /// + /// Whether to enable frame-stable playback. + /// + internal bool FrameStablePlayback + { + get => frameStabilityContainer.FrameStablePlayback; + set => frameStabilityContainer.FrameStablePlayback = value; + } + /// /// Invoked when a has been applied by a . /// diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 1cc56fff8b..7c143aa158 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -24,6 +24,11 @@ namespace osu.Game.Rulesets.UI ///

public List Scores { get; set; } + public DifficultyRating DifficultyRating + { + get + { + var rating = StarDifficulty; + + if (rating < 2.0) return DifficultyRating.Easy; + if (rating < 2.7) return DifficultyRating.Normal; + if (rating < 4.0) return DifficultyRating.Hard; + if (rating < 5.3) return DifficultyRating.Insane; + if (rating < 6.5) return DifficultyRating.Expert; + + return DifficultyRating.ExpertPlus; + } + } + public override string ToString() => $"{Metadata} [{Version}]".Trim(); public bool Equals(BeatmapInfo other) diff --git a/osu.Game/Beatmaps/DifficultyRating.cs b/osu.Game/Beatmaps/DifficultyRating.cs new file mode 100644 index 0000000000..f0ee0ad705 --- /dev/null +++ b/osu.Game/Beatmaps/DifficultyRating.cs @@ -0,0 +1,15 @@ +// 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.Beatmaps +{ + public enum DifficultyRating + { + Easy, + Normal, + Hard, + Insane, + Expert, + ExpertPlus + } +} diff --git a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs deleted file mode 100644 index 26ffcca1ec..0000000000 --- a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osuTK.Graphics; - -namespace osu.Game.Beatmaps.Drawables -{ - public abstract class DifficultyColouredContainer : Container, IHasAccentColour - { - public Color4 AccentColour { get; set; } - - private readonly BeatmapInfo beatmap; - private OsuColour palette; - - protected DifficultyColouredContainer(BeatmapInfo beatmap) - { - this.beatmap = beatmap; - } - - [BackgroundDependencyLoader] - private void load(OsuColour palette) - { - if (palette == null) - throw new ArgumentNullException(nameof(palette)); - - this.palette = palette; - AccentColour = getColour(beatmap); - } - - private enum DifficultyRating - { - Easy, - Normal, - Hard, - Insane, - Expert, - ExpertPlus - } - - private DifficultyRating getDifficultyRating(BeatmapInfo beatmap) - { - if (beatmap == null) - throw new ArgumentNullException(nameof(beatmap)); - - var rating = beatmap.StarDifficulty; - - if (rating < 2.0) return DifficultyRating.Easy; - if (rating < 2.7) return DifficultyRating.Normal; - if (rating < 4.0) return DifficultyRating.Hard; - if (rating < 5.3) return DifficultyRating.Insane; - if (rating < 6.5) return DifficultyRating.Expert; - - return DifficultyRating.ExpertPlus; - } - - private Color4 getColour(BeatmapInfo beatmap) - { - switch (getDifficultyRating(beatmap)) - { - case DifficultyRating.Easy: - return palette.Green; - - default: - case DifficultyRating.Normal: - return palette.Blue; - - case DifficultyRating.Hard: - return palette.Yellow; - - case DifficultyRating.Insane: - return palette.Pink; - - case DifficultyRating.Expert: - return palette.Purple; - - case DifficultyRating.ExpertPlus: - return palette.Gray0; - } - } - } -} diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 0a0ad28fdf..2b0a0a5ac1 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Rulesets; using osuTK; @@ -16,23 +17,25 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class DifficultyIcon : DifficultyColouredContainer + public class DifficultyIcon : Container { + private readonly BeatmapInfo beatmap; private readonly RulesetInfo ruleset; public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null) - : base(beatmap) { if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); + this.beatmap = beatmap; + this.ruleset = ruleset ?? beatmap.Ruleset; Size = new Vector2(20); } [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colours) { Children = new Drawable[] { @@ -52,7 +55,7 @@ namespace osu.Game.Beatmaps.Drawables Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = AccentColour, + Colour = colours.ForDifficultyRating(beatmap.DifficultyRating), }, }, new ConstrainedIconContainer diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 63ec24f84f..af66f57f14 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Game.Beatmaps; using osuTK.Graphics; namespace osu.Game.Graphics @@ -37,6 +38,31 @@ namespace osu.Game.Graphics } } + public Color4 ForDifficultyRating(DifficultyRating difficulty) + { + switch (difficulty) + { + case DifficultyRating.Easy: + return Green; + + default: + case DifficultyRating.Normal: + return Blue; + + case DifficultyRating.Hard: + return Yellow; + + case DifficultyRating.Insane: + return Pink; + + case DifficultyRating.Expert: + return Purple; + + case DifficultyRating.ExpertPlus: + return Gray0; + } + } + // 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"); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index a9e4eaa9b3..5f6307e3b4 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -402,31 +402,35 @@ namespace osu.Game.Screens.Select } } - private class DifficultyColourBar : DifficultyColouredContainer + private class DifficultyColourBar : Container { + private readonly BeatmapInfo beatmap; + public DifficultyColourBar(BeatmapInfo beatmap) - : base(beatmap) { + this.beatmap = beatmap; } [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colours) { const float full_opacity_ratio = 0.7f; + var difficultyColour = colours.ForDifficultyRating(beatmap.DifficultyRating); + Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = AccentColour, + Colour = difficultyColour, Width = full_opacity_ratio, }, new Box { RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Both, - Colour = AccentColour, + Colour = difficultyColour, Alpha = 0.5f, X = full_opacity_ratio, Width = 1 - full_opacity_ratio, From 50046d5f69bd206f0480271758b0488b3c97f61a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 17 Aug 2019 15:20:27 +0900 Subject: [PATCH 304/645] Use new tooltip style --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 9b265de45b..37fbc617cc 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -32,14 +32,17 @@ namespace osu.Game.Beatmaps.Drawables this.beatmap = beatmap; this.ruleset = ruleset ?? beatmap.Ruleset; - TooltipText = shouldShowTooltip ? $"{beatmap.Version}${beatmap.StarDifficulty:0.##}" : String.Empty; + if (shouldShowTooltip) + TooltipContent = beatmap; Size = new Vector2(20); } public string TooltipText { get; set; } - public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(AccentColour); + public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(); + + public object TooltipContent { get; set; } [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -81,9 +84,14 @@ namespace osu.Game.Beatmaps.Drawables private readonly OsuSpriteText difficultyName, starRating; private readonly Box background; - public string TooltipText { get; set; } + private readonly FillFlowContainer difficultyFlow; - public DifficultyIconTooltip(Color4 difficultyColour) + public string TooltipText + { + set { } + } + + public DifficultyIconTooltip() { AutoSizeAxes = Axes.Both; Masking = true; @@ -108,13 +116,12 @@ namespace osu.Game.Beatmaps.Drawables Origin = Anchor.Centre, Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), }, - new FillFlowContainer + difficultyFlow = new FillFlowContainer { AutoSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, Direction = FillDirection.Horizontal, - Colour = difficultyColour, Children = new Drawable[] { starRating = new OsuSpriteText @@ -138,17 +145,29 @@ namespace osu.Game.Beatmaps.Drawables }; } + private OsuColour colours; + [BackgroundDependencyLoader] private void load(OsuColour colours) { + this.colours = colours; background.Colour = colours.GreyCarmineDark; } + public bool SetContent(object content) + { + if (!(content is BeatmapInfo beatmap)) + return false; + + difficultyName.Text = beatmap.Version; + starRating.Text = $"{beatmap.StarDifficulty:0.##}"; + difficultyFlow.Colour = colours.ForDifficultyRating(beatmap.DifficultyRating); + + return true; + } + public void Refresh() { - var info = TooltipText.Split('$'); - difficultyName.Text = info[0]; - starRating.Text = info[1]; } public void Move(Vector2 pos) => Position = pos; From 097763bb1ca9d7215b9ad7ba9bbe14554f9f24df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 17 Aug 2019 15:29:39 +0900 Subject: [PATCH 305/645] Add auto size duration --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 37fbc617cc..962cb33a83 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -106,6 +106,8 @@ namespace osu.Game.Beatmaps.Drawables new FillFlowContainer { AutoSizeAxes = Axes.Both, + AutoSizeDuration = 200, + AutoSizeEasing = Easing.OutQuint, Direction = FillDirection.Vertical, Padding = new MarginPadding(10), Children = new Drawable[] From 87dc6499faabccc71e3062a2365446d31945a281 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 17 Aug 2019 15:34:02 +0900 Subject: [PATCH 306/645] Fix json decoding being a bit too eager to consume --- osu.Game/Beatmaps/BeatmapInfo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 700f981088..198046df4f 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -129,6 +129,7 @@ namespace osu.Game.Beatmaps ///
public List Scores { get; set; } + [JsonIgnore] public DifficultyRating DifficultyRating { get From f7024b513efeabd0a19b97716725770ab86138bd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 01:43:43 +0300 Subject: [PATCH 307/645] Visual improvements --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 83 +++++++++++--------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 4cac73c975..ad72063313 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -14,14 +14,15 @@ using osu.Game.Beatmaps; using osu.Framework.Bindables; using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; +using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; namespace osu.Game.Screens.Play.HUD { public class HitErrorDisplay : Container { - private const int bar_width = 4; - private const int bar_height = 250; + private const int bar_width = 3; + private const int bar_height = 200; private const int spacing = 3; public HitWindows HitWindows { get; set; } @@ -31,6 +32,7 @@ namespace osu.Game.Screens.Play.HUD private readonly bool mirrored; private readonly SpriteIcon arrow; + private readonly FillFlowContainer bar; private readonly List judgementOffsets = new List(); public HitErrorDisplay(bool mirrored = false) @@ -41,43 +43,10 @@ namespace osu.Game.Screens.Play.HUD Children = new Drawable[] { - new FillFlowContainer + bar = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Color4.Orange), - Height = 0.3f - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Green, - Height = 0.15f - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Blue, - Height = 0.1f - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Green, - Height = 0.15f - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Orange, Color4.Black.Opacity(0)), - Height = 0.3f - } - } }, arrow = new SpriteIcon { @@ -86,11 +55,49 @@ namespace osu.Game.Screens.Play.HUD X = mirrored ? -spacing : spacing, RelativePositionAxes = Axes.Y, Icon = mirrored ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, - Size = new Vector2(10), + Size = new Vector2(8), } }; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + bar.AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), + Height = 0.3f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Green, + Height = 0.15f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.BlueLight, + Height = 0.1f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Green, + Height = 0.15f + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), + Height = 0.3f + } + }); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -117,7 +124,7 @@ namespace osu.Game.Screens.Play.HUD Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, Origin = mirrored ? Anchor.CentreLeft : Anchor.CentreRight, Masking = true, - Size = new Vector2(10, 2), + Size = new Vector2(8, 2), RelativePositionAxes = Axes.Y, Y = getRelativeJudgementPosition(judgement.TimeOffset), X = mirrored ? spacing : -spacing, From 906984ad952f5df2b3c6becf66c30339af2cef36 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 02:49:07 +0300 Subject: [PATCH 308/645] Fix the math --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 35 +++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index ad72063313..6ef102e575 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -16,6 +16,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; +using System.Linq; namespace osu.Game.Screens.Play.HUD { @@ -30,6 +31,9 @@ namespace osu.Game.Screens.Play.HUD [Resolved] private Bindable beatmap { get; set; } + [Resolved] + private OsuColour colours { get; set; } + private readonly bool mirrored; private readonly SpriteIcon arrow; private readonly FillFlowContainer bar; @@ -60,50 +64,46 @@ namespace osu.Game.Screens.Play.HUD }; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override void LoadComplete() { + base.LoadComplete(); + HitWindows.SetDifficulty(beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); + bar.AddRange(new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - Height = 0.3f + Height = (float)((HitWindows.Meh - HitWindows.Good) / (HitWindows.Meh * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = 0.15f + Height = (float)((HitWindows.Good - HitWindows.Great) / (HitWindows.Meh * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.BlueLight, - Height = 0.1f + Height = (float)(HitWindows.Great / HitWindows.Meh) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = 0.15f + Height = (float)((HitWindows.Good - HitWindows.Great) / (HitWindows.Meh * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - Height = 0.3f + Height = (float)((HitWindows.Meh - HitWindows.Good) / (HitWindows.Meh * 2)) } }); } - protected override void LoadComplete() - { - base.LoadComplete(); - HitWindows.SetDifficulty(beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); - } - public void OnNewJudgement(JudgementResult judgement) { if (!judgement.IsHit) @@ -135,7 +135,7 @@ namespace osu.Game.Screens.Play.HUD } }; - private float getRelativeJudgementPosition(double value) => (float)(value / HitWindows.Miss); + private float getRelativeJudgementPosition(double value) => (float)(value / HitWindows.Meh); private double calculateArrowPosition(JudgementResult judgement) { @@ -144,12 +144,7 @@ namespace osu.Game.Screens.Play.HUD judgementOffsets.Add(judgement.TimeOffset); - double offsets = 0; - - foreach (var offset in judgementOffsets) - offsets += offset; - - return offsets / judgementOffsets.Count; + return judgementOffsets.Average(); } } } From 50133ba8636159d4b3d79eda20ced928a4fdbf68 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 02:57:12 +0300 Subject: [PATCH 309/645] naming adjustments --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 6ef102e575..1dd77469ca 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -22,6 +22,7 @@ namespace osu.Game.Screens.Play.HUD { public class HitErrorDisplay : Container { + private const int stored_judgements_amount = 5; private const int bar_width = 3; private const int bar_height = 200; private const int spacing = 3; @@ -104,19 +105,19 @@ namespace osu.Game.Screens.Play.HUD }); } - public void OnNewJudgement(JudgementResult judgement) + public void OnNewJudgement(JudgementResult newJudgement) { - if (!judgement.IsHit) + if (!newJudgement.IsHit) return; Container judgementLine; - Add(judgementLine = CreateJudgementLine(judgement)); + Add(judgementLine = CreateJudgementLine(newJudgement)); judgementLine.FadeOut(10000, Easing.OutQuint); judgementLine.Expire(); - arrow.MoveToY(getRelativeJudgementPosition(calculateArrowPosition(judgement)), 500, Easing.OutQuint); + arrow.MoveToY(getRelativeJudgementPosition(calculateArrowPosition(newJudgement)), 500, Easing.OutQuint); } protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer @@ -137,12 +138,12 @@ namespace osu.Game.Screens.Play.HUD private float getRelativeJudgementPosition(double value) => (float)(value / HitWindows.Meh); - private double calculateArrowPosition(JudgementResult judgement) + private double calculateArrowPosition(JudgementResult newJudgement) { - if (judgementOffsets.Count > 5) + if (judgementOffsets.Count > stored_judgements_amount) judgementOffsets.RemoveAt(0); - judgementOffsets.Add(judgement.TimeOffset); + judgementOffsets.Add(newJudgement.TimeOffset); return judgementOffsets.Average(); } From ee5568e5968489b8dbce42023f4db425f28fff2c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 14:43:34 +0300 Subject: [PATCH 310/645] Use Queue instead of List for stored Judgements --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 1dd77469ca..7bb1d30f22 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play.HUD private readonly bool mirrored; private readonly SpriteIcon arrow; private readonly FillFlowContainer bar; - private readonly List judgementOffsets = new List(); + private readonly Queue judgementOffsets = new Queue(); public HitErrorDisplay(bool mirrored = false) { @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Play.HUD judgementLine.FadeOut(10000, Easing.OutQuint); judgementLine.Expire(); - arrow.MoveToY(getRelativeJudgementPosition(calculateArrowPosition(newJudgement)), 500, Easing.OutQuint); + arrow.MoveToY(calculateArrowPosition(newJudgement), 500, Easing.OutQuint); } protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer @@ -138,14 +138,14 @@ namespace osu.Game.Screens.Play.HUD private float getRelativeJudgementPosition(double value) => (float)(value / HitWindows.Meh); - private double calculateArrowPosition(JudgementResult newJudgement) + private float calculateArrowPosition(JudgementResult newJudgement) { if (judgementOffsets.Count > stored_judgements_amount) - judgementOffsets.RemoveAt(0); + judgementOffsets.Dequeue(); - judgementOffsets.Add(newJudgement.TimeOffset); + judgementOffsets.Enqueue(newJudgement.TimeOffset); - return judgementOffsets.Average(); + return getRelativeJudgementPosition(judgementOffsets.Average()); } } } From a59a14c9e6f518ab3c99871c5ddae5617dfefc75 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 15:01:04 +0300 Subject: [PATCH 311/645] Add setting to enable/disable hit error visibility --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ osu.Game/Configuration/ScoreMeterType.cs | 8 +++++-- .../Sections/Gameplay/GeneralSettings.cs | 5 ++++ osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 24 +++++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 19f46c1d6a..bffbce2a52 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -79,6 +79,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ShowInterface, true); Set(OsuSetting.ShowHealthDisplayWhenCantFail, true); Set(OsuSetting.KeyOverlay, false); + Set(OsuSetting.ScoreMeter, ScoreMeterType.HitError); Set(OsuSetting.FloatingComments, false); @@ -132,6 +133,7 @@ namespace osu.Game.Configuration BlurLevel, ShowStoryboard, KeyOverlay, + ScoreMeter, FloatingComments, ShowInterface, ShowHealthDisplayWhenCantFail, diff --git a/osu.Game/Configuration/ScoreMeterType.cs b/osu.Game/Configuration/ScoreMeterType.cs index 21a63fb3ed..e78220c9c9 100644 --- a/osu.Game/Configuration/ScoreMeterType.cs +++ b/osu.Game/Configuration/ScoreMeterType.cs @@ -1,12 +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 System.ComponentModel; + namespace osu.Game.Configuration { public enum ScoreMeterType { + [Description("None")] None, - Colour, - Error + + [Description("Hit Error")] + HitError } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 9142492610..520a8852b3 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -44,6 +44,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Always show key overlay", Bindable = config.GetBindable(OsuSetting.KeyOverlay) }, + new SettingsEnumDropdown + { + LabelText = "Score meter type", + Bindable = config.GetBindable(OsuSetting.ScoreMeter) + }, new SettingsEnumDropdown { LabelText = "Score display mode", diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 7bb1d30f22..9a5198b7cc 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; using System.Linq; +using osu.Game.Configuration; namespace osu.Game.Screens.Play.HUD { @@ -40,6 +41,8 @@ namespace osu.Game.Screens.Play.HUD private readonly FillFlowContainer bar; private readonly Queue judgementOffsets = new Queue(); + private readonly Bindable type = new Bindable(); + public HitErrorDisplay(bool mirrored = false) { this.mirrored = mirrored; @@ -65,6 +68,12 @@ namespace osu.Game.Screens.Play.HUD }; } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.ScoreMeter, type); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -103,6 +112,21 @@ namespace osu.Game.Screens.Play.HUD Height = (float)((HitWindows.Meh - HitWindows.Good) / (HitWindows.Meh * 2)) } }); + + type.BindValueChanged(onTypeChanged, true); + } + + private void onTypeChanged(ValueChangedEvent type) + { + switch (type.NewValue) + { + case ScoreMeterType.None: + this.FadeOut(200, Easing.OutQuint); + break; + case ScoreMeterType.HitError: + this.FadeIn(200, Easing.OutQuint); + break; + } } public void OnNewJudgement(JudgementResult newJudgement) From 8740ebd13f2fcac9a46151cf0991031e3edbdf32 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 15:45:18 +0300 Subject: [PATCH 312/645] Simplify layout --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 72 +++++++++++++------- osu.Game/Screens/Play/HUDOverlay.cs | 12 ++-- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 9a5198b7cc..1a4d2a45c5 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -21,10 +21,11 @@ using osu.Game.Configuration; namespace osu.Game.Screens.Play.HUD { - public class HitErrorDisplay : Container + public class HitErrorDisplay : CompositeDrawable { private const int stored_judgements_amount = 5; private const int bar_width = 3; + private const int judgement_line_width = 8; private const int bar_height = 200; private const int spacing = 3; @@ -36,36 +37,57 @@ namespace osu.Game.Screens.Play.HUD [Resolved] private OsuColour colours { get; set; } - private readonly bool mirrored; private readonly SpriteIcon arrow; private readonly FillFlowContainer bar; + private readonly Container judgementsContainer; private readonly Queue judgementOffsets = new Queue(); private readonly Bindable type = new Bindable(); - public HitErrorDisplay(bool mirrored = false) + public HitErrorDisplay(bool reversed = false) { - this.mirrored = mirrored; + AutoSizeAxes = Axes.Both; - Size = new Vector2(bar_width, bar_height); - - Children = new Drawable[] + AddInternal(new FillFlowContainer { - bar = new FillFlowContainer + AutoSizeAxes = Axes.X, + Height = bar_height, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - }, - arrow = new SpriteIcon - { - Anchor = mirrored ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, - X = mirrored ? -spacing : spacing, - RelativePositionAxes = Axes.Y, - Icon = mirrored ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, - Size = new Vector2(8), + judgementsContainer = new Container + { + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Width = judgement_line_width, + RelativeSizeAxes = Axes.Y, + }, + bar = new FillFlowContainer + { + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Width = bar_width, + RelativeSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }, + new Container + { + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Child = arrow = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.Y, + Icon = reversed ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, + Size = new Vector2(8), + } + }, } - }; + }); } [BackgroundDependencyLoader] @@ -136,7 +158,7 @@ namespace osu.Game.Screens.Play.HUD Container judgementLine; - Add(judgementLine = CreateJudgementLine(newJudgement)); + judgementsContainer.Add(judgementLine = CreateJudgementLine(newJudgement)); judgementLine.FadeOut(10000, Easing.OutQuint); judgementLine.Expire(); @@ -146,13 +168,13 @@ namespace osu.Game.Screens.Play.HUD protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer { - Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = mirrored ? Anchor.CentreLeft : Anchor.CentreRight, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Masking = true, - Size = new Vector2(8, 2), + RelativeSizeAxes = Axes.X, + Height = 2, RelativePositionAxes = Axes.Y, Y = getRelativeJudgementPosition(judgement.TimeOffset), - X = mirrored ? spacing : -spacing, Child = new Box { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index a9a469486e..50480c001c 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -86,8 +86,8 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), - LeftHitErrorDisplay = CreateAccuracyBar(false), - RightHitErrorDisplay = CreateAccuracyBar(), + LeftHitErrorDisplay = CreateHitErrorDisplay(false), + RightHitErrorDisplay = CreateHitErrorDisplay(), } }, PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), @@ -260,11 +260,11 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay CreateAccuracyBar(bool mirrored = true) => new HitErrorDisplay(mirrored) + protected virtual HitErrorDisplay CreateHitErrorDisplay(bool reversed = true) => new HitErrorDisplay(reversed) { - Anchor = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = mirrored ? Anchor.CentreRight : Anchor.CentreLeft, - Margin = new MarginPadding { Horizontal = 30 } + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Margin = new MarginPadding { Horizontal = 20 } }; protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); From 55cd1cecdfb57c6ba8794ce66946b24be2d8fe4d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 15:53:42 +0300 Subject: [PATCH 313/645] Add missing blank line --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 1a4d2a45c5..2959a9aca7 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -145,6 +145,7 @@ namespace osu.Game.Screens.Play.HUD case ScoreMeterType.None: this.FadeOut(200, Easing.OutQuint); break; + case ScoreMeterType.HitError: this.FadeIn(200, Easing.OutQuint); break; From 6c60db550ff9c3e76abdc89add98d6f26e415b28 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 16:24:13 +0300 Subject: [PATCH 314/645] Fix crash if ruleset has no Meh hit windows --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 2959a9aca7..2ed06209de 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -107,37 +107,46 @@ namespace osu.Game.Screens.Play.HUD { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - Height = (float)((HitWindows.Meh - HitWindows.Good) / (HitWindows.Meh * 2)) + Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (HitWindows.Meh * 2)) + Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.BlueLight, - Height = (float)(HitWindows.Great / HitWindows.Meh) + Height = (float)(HitWindows.Great / getMehHitWindows()) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (HitWindows.Meh * 2)) + Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - Height = (float)((HitWindows.Meh - HitWindows.Good) / (HitWindows.Meh * 2)) + Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) } }); type.BindValueChanged(onTypeChanged, true); } + private double getMehHitWindows() + { + // In case if ruleset has no Meh hit windows (like Taiko) + if (HitWindows.Meh == 0) + return HitWindows.Good + 40; + + return HitWindows.Meh; + } + private void onTypeChanged(ValueChangedEvent type) { switch (type.NewValue) @@ -183,7 +192,7 @@ namespace osu.Game.Screens.Play.HUD } }; - private float getRelativeJudgementPosition(double value) => (float)(value / HitWindows.Meh); + private float getRelativeJudgementPosition(double value) => (float)(value / getMehHitWindows()); private float calculateArrowPosition(JudgementResult newJudgement) { From dd6351b8caa83e917152a74220ed1a04fe56f3f3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 16:51:16 +0300 Subject: [PATCH 315/645] Apply suggested changes --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 16 +++++++++------- osu.Game/Screens/Play/HUDOverlay.cs | 18 +++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 2ed06209de..1a3682351b 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -27,6 +27,9 @@ namespace osu.Game.Screens.Play.HUD private const int bar_width = 3; private const int judgement_line_width = 8; private const int bar_height = 200; + private const int fade_duration = 200; + private const int arrow_move_duration = 500; + private const int judgement_life_time = 10000; private const int spacing = 3; public HitWindows HitWindows { get; set; } @@ -152,11 +155,11 @@ namespace osu.Game.Screens.Play.HUD switch (type.NewValue) { case ScoreMeterType.None: - this.FadeOut(200, Easing.OutQuint); + this.FadeOut(fade_duration, Easing.OutQuint); break; case ScoreMeterType.HitError: - this.FadeIn(200, Easing.OutQuint); + this.FadeIn(fade_duration, Easing.OutQuint); break; } } @@ -166,14 +169,13 @@ namespace osu.Game.Screens.Play.HUD if (!newJudgement.IsHit) return; - Container judgementLine; + var judgementLine = CreateJudgementLine(newJudgement); - judgementsContainer.Add(judgementLine = CreateJudgementLine(newJudgement)); + judgementsContainer.Add(judgementLine); - judgementLine.FadeOut(10000, Easing.OutQuint); - judgementLine.Expire(); + judgementLine.FadeOut(judgement_life_time, Easing.OutQuint).Expire(); - arrow.MoveToY(calculateArrowPosition(newJudgement), 500, Easing.OutQuint); + arrow.MoveToY(calculateArrowPosition(newJudgement), arrow_move_duration, Easing.OutQuint); } protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 50480c001c..114dc86757 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; @@ -276,17 +277,16 @@ namespace osu.Game.Screens.Play ComboCounter?.Current.BindTo(processor.Combo); HealthDisplay?.Current.BindTo(processor.Health); - if (LeftHitErrorDisplay != null) - { - processor.NewJudgement += LeftHitErrorDisplay.OnNewJudgement; - LeftHitErrorDisplay.HitWindows = processor.CreateHitWindows(); - } + var hitWindows = processor.CreateHitWindows(); - if (RightHitErrorDisplay != null) + visibilityContainer.ForEach(drawable => { - processor.NewJudgement += RightHitErrorDisplay.OnNewJudgement; - RightHitErrorDisplay.HitWindows = processor.CreateHitWindows(); - } + if (drawable is HitErrorDisplay) + { + processor.NewJudgement += (drawable as HitErrorDisplay).OnNewJudgement; + (drawable as HitErrorDisplay).HitWindows = hitWindows; + } + }); if (HealthDisplay is StandardHealthDisplay shd) processor.NewJudgement += shd.Flash; From 4c817b18b7f217ef9c95c01c867d8e4442c7ad18 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 17:03:11 +0300 Subject: [PATCH 316/645] Use direct cast --- osu.Game/Screens/Play/HUDOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 114dc86757..be291003b5 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -283,8 +283,8 @@ namespace osu.Game.Screens.Play { if (drawable is HitErrorDisplay) { - processor.NewJudgement += (drawable as HitErrorDisplay).OnNewJudgement; - (drawable as HitErrorDisplay).HitWindows = hitWindows; + processor.NewJudgement += ((HitErrorDisplay)drawable).OnNewJudgement; + ((HitErrorDisplay)drawable).HitWindows = hitWindows; } }); From 3fcd786198a60b61cd6179f56294b0b12d209808 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 18 Aug 2019 19:32:56 +0200 Subject: [PATCH 317/645] Take lease on WorkingBeatmap during intro screens to prevent weird interactions with Playback control. --- osu.Game/Screens/Menu/IntroScreen.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index 27f3c9a45b..a621e29cf8 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -28,11 +28,18 @@ namespace osu.Game.Screens.Menu private Bindable menuVoice; + private LeasedBindable beatmap; + + public new Bindable Beatmap { get => beatmap; } + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack(); [BackgroundDependencyLoader] private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) { + //we take a lease on the beatmap bindable to prevent music playback from changing / pausing music during intros, as it is causing weird interactions with certains intros + beatmap = base.Beatmap.BeginLease(false); + menuVoice = config.GetBindable(OsuSetting.MenuVoice); seeya = audio.Samples.Get(@"seeya"); } @@ -108,6 +115,8 @@ namespace osu.Game.Screens.Menu protected void LoadMenu() { DidLoadMenu = true; + beatmap.Return(); //we return the lease to the beatmap bindable as we're pushing the main menu. + this.Push(mainMenu); } } From 2393bbc69b15e1f3421f3d4b140393bbaa8462ac Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 21:27:53 +0300 Subject: [PATCH 318/645] Expand APIKudosuHistory --- .../Requests/GetUserKudosuHistoryRequest.cs | 10 ++++ .../Requests/Responses/APIKudosuHistory.cs | 46 +++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs index e90e297672..af37bd4b51 100644 --- a/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs @@ -18,4 +18,14 @@ namespace osu.Game.Online.API.Requests protected override string Target => $"users/{userId}/kudosu"; } + + public enum KudosuAction + { + Give, + VoteGive, + Reset, + VoteReset, + DenyKudosuReset, + Revoke, + } } diff --git a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs index 271dcc320e..d02f71c339 100644 --- a/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs +++ b/osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs @@ -2,19 +2,59 @@ // See the LICENCE file in the repository root for full licence text. using System; +using Humanizer; using Newtonsoft.Json; namespace osu.Game.Online.API.Requests.Responses { public class APIKudosuHistory { - [JsonProperty("id")] - public int ID; - [JsonProperty("created_at")] public DateTimeOffset CreatedAt; [JsonProperty("amount")] + private int amount + { + set => Amount = Math.Abs(value); + } + public int Amount; + + [JsonProperty("post")] + public ModdingPost Post; + + public class ModdingPost + { + [JsonProperty("url")] + public string Url; + + [JsonProperty("title")] + public string Title; + } + + [JsonProperty("giver")] + public KudosuGiver Giver; + + public class KudosuGiver + { + [JsonProperty("url")] + public string Url; + + [JsonProperty("username")] + public string Username; + } + + [JsonProperty("action")] + private string action + { + set + { + string parsed = value.Contains(".") ? value.Split('.')[0].Pascalize() + value.Split('.')[1].Pascalize() : value.Pascalize(); + + Action = (KudosuAction)Enum.Parse(typeof(KudosuAction), parsed); + } + } + + public KudosuAction Action; } } From be97804180f00c93818ea91b9afd58037e27c7dd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 21:28:07 +0300 Subject: [PATCH 319/645] Implement text formatting --- .../Kudosu/DrawableKudosuHistoryItem.cs | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 1671073242..9b68131515 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; namespace osu.Game.Overlays.Profile.Sections.Kudosu @@ -51,6 +52,45 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu AutoSizeAxes = Axes.X, }; - private MessageFormatter.MessageFormatterResult createMessage() => MessageFormatter.FormatText($@"{historyItem.Amount}"); + private MessageFormatter.MessageFormatterResult createMessage() + { + string postLinkTemplate() => $"[{historyItem.Post.Url} {historyItem.Post.Title}]"; + string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; + + string message; + + switch (historyItem.Action) + { + case KudosuAction.Give: + message = $"Received {historyItem.Amount} kudosu from {userLinkTemplate()} for a post at {postLinkTemplate()}"; + break; + + case KudosuAction.VoteGive: + message = $"Received {historyItem.Amount} kudosu from obtaining votes in modding post of {postLinkTemplate()}"; + break; + + case KudosuAction.Reset: + message = $"Kudosu reset by {userLinkTemplate()} for the post {postLinkTemplate()}"; + break; + + case KudosuAction.VoteReset: + message = $"Lost {historyItem.Amount} kudosu from losing votes in modding post of {postLinkTemplate()}"; + break; + + case KudosuAction.DenyKudosuReset: + message = $"Denied {historyItem.Amount} kudosu from modding post {postLinkTemplate()}"; + break; + + case KudosuAction.Revoke: + message = $"Denied kudosu by {userLinkTemplate()} for the post {postLinkTemplate()}"; + break; + + default: + message = string.Empty; + break; + } + + return MessageFormatter.FormatText(message); + } } } From 4c9b621f43d9a702be1bd3149758a9e030f781bf Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 22:01:36 +0300 Subject: [PATCH 320/645] Fix some user links can't be opened inside the game --- osu.Game/Online/Chat/MessageFormatter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 4aaffdd161..db26945ef3 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -122,6 +122,7 @@ namespace osu.Game.Online.Chat return new LinkDetails(LinkAction.OpenBeatmapSet, args[3]); case "u": + case "users": return new LinkDetails(LinkAction.OpenUserProfile, args[3]); } } From 015406f4d2b7256ee0f7c0c9d2e0bb5445ab86ea Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 18 Aug 2019 22:02:59 +0300 Subject: [PATCH 321/645] Fix link parser --- osu.Game/Online/Chat/MessageFormatter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 4aaffdd161..db26945ef3 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -122,6 +122,7 @@ namespace osu.Game.Online.Chat return new LinkDetails(LinkAction.OpenBeatmapSet, args[3]); case "u": + case "users": return new LinkDetails(LinkAction.OpenUserProfile, args[3]); } } From a51fbfa31b52aefb18a8ec9d78f93f475b724de5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 10:46:28 +0900 Subject: [PATCH 322/645] Fix osu! default tooltips not displaying --- .../Graphics/Cursor/OsuTooltipContainer.cs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index cfcda892fd..57f39bb8c7 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -30,22 +30,24 @@ namespace osu.Game.Graphics.Cursor private readonly OsuSpriteText text; private bool instantMovement = true; - public override string TooltipText + public override bool SetContent(object content) { - set + if (!(content is string contentString)) + return false; + + if (contentString == text.Text) return true; + + text.Text = contentString; + + if (IsPresent) { - if (value == text.Text) return; - - text.Text = value; - - if (IsPresent) - { - AutoSizeDuration = 250; - background.FlashColour(OsuColour.Gray(0.4f), 1000, Easing.OutQuint); - } - else - AutoSizeDuration = 0; + AutoSizeDuration = 250; + background.FlashColour(OsuColour.Gray(0.4f), 1000, Easing.OutQuint); } + else + AutoSizeDuration = 0; + + return true; } public OsuTooltip() From 1f00793891e1488151e7817edd99cbd9a362dfd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 11:30:04 +0900 Subject: [PATCH 323/645] Unpause music when changing selection at song select --- osu.Game/Overlays/MusicController.cs | 9 +++++++++ osu.Game/Screens/Select/SongSelect.cs | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f6208c46cb..6ad147735b 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -92,6 +92,15 @@ namespace osu.Game.Overlays }); } + /// + /// Start playing the current track (if not already playing). + /// + public void Play() + { + if (!IsPlaying) + TogglePause(); + } + /// /// Toggle pause / play. /// diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8340814db9..edb0e6deb8 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -359,6 +359,7 @@ namespace osu.Game.Screens.Select return; beatmapNoDebounce = beatmap; + performUpdateSelected(); } @@ -586,10 +587,18 @@ namespace osu.Game.Screens.Select { Track track = Beatmap.Value.Track; - if ((!track.IsRunning || restart) && music?.IsUserPaused != true) + if (!track.IsRunning || restart) { track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; - track.Restart(); + + if (music != null) + { + // use the global music controller (when available) to cancel a potential local user paused state. + music.SeekTo(track.RestartPoint); + music.Play(); + } + else + track.Restart(); } } From 7143497441a95db5f98d81797ed2966058671cf4 Mon Sep 17 00:00:00 2001 From: Ganendra Afrasya Date: Mon, 19 Aug 2019 10:32:01 +0700 Subject: [PATCH 324/645] Match up tooltip background color with OsuTooltipContainer --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 962cb33a83..3c3a7c056e 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -153,7 +153,7 @@ namespace osu.Game.Beatmaps.Drawables private void load(OsuColour colours) { this.colours = colours; - background.Colour = colours.GreyCarmineDark; + background.Colour = colours.Gray3; } public bool SetContent(object content) From be51fde2925a674d0fd31b6b24bb9e8aeca015ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 13:22:32 +0900 Subject: [PATCH 325/645] Centre beatmap panels in profile overlay --- .../Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 1b6c1c99a6..8a6b52b7ee 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -46,8 +46,11 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps if (!s.OnlineBeatmapSetID.HasValue) continue; - var panel = new DirectGridPanel(s.ToBeatmapSet(Rulesets)); - ItemsContainer.Add(panel); + ItemsContainer.Add(new DirectGridPanel(s.ToBeatmapSet(Rulesets)) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }); } }); From 4356f2ef9fdf072fbacdc7e196edff4659bd9582 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 17:45:54 +0900 Subject: [PATCH 326/645] Add sample usage of looping skinnable --- osu.Game/Skinning/LegacySkin.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index b560fd4f84..a41812bad0 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -102,6 +102,10 @@ namespace osu.Game.Skinning return null; + case "Play/osu/sliderfollowcircle": + animatable = true; + break; + case "Play/Miss": componentName = "hit0"; animatable = true; @@ -149,8 +153,6 @@ namespace osu.Game.Skinning texture = GetTexture($"{componentName}-{i}"); } - // This comment can be removed once we have components which are looping - // ReSharper disable once ConditionIsAlwaysTrueOrFalse animation.Repeat = looping; return animation; From d224405bc611aa7f1c4be3df83b7b51136a74716 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 17:46:05 +0900 Subject: [PATCH 327/645] Rename const and make more available --- osu.Game/Skinning/LegacySkin.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index a41812bad0..2b9ed2aa8b 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -76,11 +76,12 @@ namespace osu.Game.Skinning Samples?.Dispose(); } + private const double default_frame_time = 1000 / 60d; + public override Drawable GetDrawableComponent(string componentName) { bool animatable = false; bool looping = true; - const double frametime = 1000 / 60d; switch (componentName) { @@ -145,7 +146,7 @@ namespace osu.Game.Skinning if (texture != null && animatable) { - var animation = new TextureAnimation { DefaultFrameLength = frametime }; + var animation = new TextureAnimation { DefaultFrameLength = default_frame_time }; for (int i = 1; texture != null; i++) { From d02b8d14f7e18ebc7292cf30e2243e4268d498e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 17:47:59 +0900 Subject: [PATCH 328/645] Avoid unnecessary texture retrieval for non-animated sprites --- osu.Game/Skinning/LegacySkin.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 2b9ed2aa8b..d47e100d0e 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -142,9 +142,9 @@ namespace osu.Game.Skinning }; } - var texture = GetTexture($"{componentName}-0"); + Texture texture; - if (texture != null && animatable) + if (animatable && (texture = GetTexture($"{componentName}-0")) != null) { var animation = new TextureAnimation { DefaultFrameLength = default_frame_time }; From 539a27a557738923c4805b5dadfc89bc2be4853f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 19:23:54 +0900 Subject: [PATCH 329/645] Refactor texture lookup code --- osu.Game/Skinning/LegacySkin.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index d47e100d0e..94421b1251 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -142,28 +142,31 @@ namespace osu.Game.Skinning }; } + return getAnimation(componentName, animatable, looping); + } + + private Drawable getAnimation(string componentName, bool animatable, bool looping, string animationSeparator = "-") + { Texture texture; - if (animatable && (texture = GetTexture($"{componentName}-0")) != null) + Texture getFrameTexture(int frame) => GetTexture($"{componentName}{animationSeparator}{frame}"); + + if (animatable && (texture = getFrameTexture(0)) != null) { var animation = new TextureAnimation { DefaultFrameLength = default_frame_time }; for (int i = 1; texture != null; i++) { animation.AddFrame(texture); - texture = GetTexture($"{componentName}-{i}"); + texture = getFrameTexture(i); } animation.Repeat = looping; return animation; } - else - { - texture = GetTexture(componentName); - return texture == null ? null : new Sprite { Texture = texture }; - } + return (texture = GetTexture(componentName)) == null ? null : new Sprite { Texture = texture }; } public class LegacySliderBall : Sprite From d0766fa1cdaa15c1a35a096e1364de4455dcefb5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Aug 2019 19:52:53 +0900 Subject: [PATCH 330/645] Add slider ball animation support --- .../Objects/Drawables/Pieces/SliderBall.cs | 12 +++++- osu.Game/Skinning/LegacySkin.cs | 42 +++++++++++++------ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 8b72b23ca3..332e25750f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -55,7 +55,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Child = new Container { RelativeSizeAxes = Axes.Both, - // TODO: support skin filename animation (sliderb0, sliderb1...) Child = new SkinnableDrawable("Play/osu/sliderball", _ => new DefaultSliderBall()), } } @@ -168,9 +167,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces return action == OsuAction.LeftButton || action == OsuAction.RightButton; } + private Vector2? lastPosition; + public void UpdateProgress(double completionProgress) { - Position = slider.CurvePositionAt(completionProgress); + var newPos = slider.CurvePositionAt(completionProgress); + + var diff = lastPosition.HasValue ? lastPosition.Value - newPos : newPos - slider.CurvePositionAt(completionProgress + 0.01f); + + Position = newPos; + Rotation = 90 + (float)(-Math.Atan2(diff.X, diff.Y) * 180 / Math.PI); + + lastPosition = newPos; } private class FollowCircleContainer : Container diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 94421b1251..883e0ce3fc 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -92,8 +92,20 @@ namespace osu.Game.Skinning return null; case "Play/osu/sliderball": - if (GetTexture("sliderb") != null) - return new LegacySliderBall(); + var sliderBallContent = getAnimation("sliderb", true, true, ""); + + if (sliderBallContent != null) + { + var size = sliderBallContent.Size; + + sliderBallContent.RelativeSizeAxes = Axes.Both; + sliderBallContent.Size = Vector2.One; + + return new LegacySliderBall(sliderBallContent) + { + Size = size + }; + } return null; @@ -169,16 +181,6 @@ namespace osu.Game.Skinning return (texture = GetTexture(componentName)) == null ? null : new Sprite { Texture = texture }; } - public class LegacySliderBall : Sprite - { - [BackgroundDependencyLoader] - private void load(ISkinSource skin) - { - Texture = skin.GetTexture("sliderb"); - Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; - } - } - public override Texture GetTexture(string componentName) { float ratio = 2; @@ -333,6 +335,20 @@ namespace osu.Game.Skinning } } + public class LegacySliderBall : CompositeDrawable + { + public LegacySliderBall(Drawable content) + { + InternalChild = content; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin) + { + Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; + } + } + public class LegacyMainCirclePiece : CompositeDrawable { public LegacyMainCirclePiece() From b3556403aac6af43614e429054a4b6672583b700 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Mon, 19 Aug 2019 16:18:25 +0200 Subject: [PATCH 331/645] Make GetNextObject() a virtual method --- .../Replays/ManiaAutoGenerator.cs | 24 ++++++++--------- .../Replays/TaikoAutoGenerator.cs | 26 +++++++++++++++---- osu.Game/Rulesets/Replays/AutoGenerator.cs | 9 +++++++ 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 43150958d0..b9dd32208e 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Replays; using osu.Game.Rulesets.Mania.Beatmaps; -using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Mania.Replays for (int i = 0; i < Beatmap.HitObjects.Count; i++) { var currentObject = Beatmap.HitObjects[i]; - var nextObjectInTheSameColumn = getNextObjectInTheSameColumn(i); + var nextObjectInTheSameColumn = GetNextObject(i); double endTime = (currentObject as IHasEndTime)?.EndTime ?? currentObject.StartTime; @@ -94,19 +94,19 @@ namespace osu.Game.Rulesets.Mania.Replays yield return new ReleasePoint { Time = endTime + calculatedDelay, Column = currentObject.Column }; } + } - ManiaHitObject getNextObjectInTheSameColumn(int currentIndex) + protected override HitObject GetNextObject(int currentIndex) + { + int desiredColumn = Beatmap.HitObjects[currentIndex++].Column; + + for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) { - int desiredColumn = Beatmap.HitObjects[currentIndex++].Column; - - for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) - { - if (Beatmap.HitObjects[currentIndex].Column == desiredColumn) - return Beatmap.HitObjects[currentIndex]; - } - - return null; + if (Beatmap.HitObjects[currentIndex].Column == desiredColumn) + return Beatmap.HitObjects[currentIndex]; } + + return null; } private interface IActionPoint diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 1d35393de0..67f93a0259 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Taiko.Beatmaps; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Taiko.Replays { @@ -113,16 +114,17 @@ namespace osu.Game.Rulesets.Taiko.Replays else throw new InvalidOperationException("Unknown hit object type."); - TaikoHitObject nextHitObject = i < Beatmap.HitObjects.Count - 1 ? Beatmap.HitObjects[i + 1] : null; + var nextHitObject = GetNextObject(i); bool canDelayKeyUp = nextHitObject == null || nextHitObject.StartTime > endTime + KEY_UP_DELAY; - if (canDelayKeyUp) - Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY)); + double calculatedDelay = canDelayKeyUp ? KEY_UP_DELAY : nextHitObject.StartTime - endTime; - if (nextHitObject != null) + Frames.Add(new TaikoReplayFrame(endTime + calculatedDelay)); + + if (i < Beatmap.HitObjects.Count - 1) { - double waitTime = nextHitObject.StartTime - 1000; + double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000; if (waitTime > endTime) Frames.Add(new TaikoReplayFrame(waitTime)); } @@ -132,5 +134,19 @@ namespace osu.Game.Rulesets.Taiko.Replays return Replay; } + + protected override HitObject GetNextObject(int currentIndex) + { + Type desiredType = Beatmap.HitObjects[currentIndex++].GetType(); + + for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) + { + var currentObj = Beatmap.HitObjects[currentIndex]; + if (currentObj.GetType().Equals(desiredType) || currentObj is DrumRoll) + return Beatmap.HitObjects[currentIndex]; + } + + return null; + } } } diff --git a/osu.Game/Rulesets/Replays/AutoGenerator.cs b/osu.Game/Rulesets/Replays/AutoGenerator.cs index 1d4cdbf04c..3319f30a6f 100644 --- a/osu.Game/Rulesets/Replays/AutoGenerator.cs +++ b/osu.Game/Rulesets/Replays/AutoGenerator.cs @@ -3,6 +3,7 @@ using osu.Game.Beatmaps; using osu.Game.Replays; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Replays { @@ -34,5 +35,13 @@ namespace osu.Game.Rulesets.Replays protected const double KEY_UP_DELAY = 50; #endregion + + protected virtual HitObject GetNextObject(int currentIndex) + { + if (currentIndex >= Beatmap.HitObjects.Count - 1) + return null; + + return Beatmap.HitObjects[currentIndex + 1]; + } } } From daeefc449c30785ba9db860ddaaf7f7fc7c92c18 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 17:49:53 +0300 Subject: [PATCH 332/645] Use another link format to avoid representation issues --- .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 9b68131515..ac5801f989 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu private MessageFormatter.MessageFormatterResult createMessage() { - string postLinkTemplate() => $"[{historyItem.Post.Url} {historyItem.Post.Title}]"; + string postLinkTemplate() => $"({historyItem.Post.Title})[{historyItem.Post.Url}]"; string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; string message; From 6b8fbf0eb1ead2c25e04b8a62ca70aaaf8e42b2c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 17:59:55 +0300 Subject: [PATCH 333/645] Change link format back Due to unavaliability to handle round brackets --- .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index ac5801f989..9b68131515 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu private MessageFormatter.MessageFormatterResult createMessage() { - string postLinkTemplate() => $"({historyItem.Post.Title})[{historyItem.Post.Url}]"; + string postLinkTemplate() => $"[{historyItem.Post.Url} {historyItem.Post.Title}]"; string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; string message; From eb83e36e0f85dc3b0ca6f4f6ce1c138b6ecc938c Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Mon, 19 Aug 2019 17:05:25 +0200 Subject: [PATCH 334/645] Make TaikoAutoGenerator unpress sooner --- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 67f93a0259..463bb84d07 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko.Replays bool canDelayKeyUp = nextHitObject == null || nextHitObject.StartTime > endTime + KEY_UP_DELAY; - double calculatedDelay = canDelayKeyUp ? KEY_UP_DELAY : nextHitObject.StartTime - endTime; + double calculatedDelay = canDelayKeyUp ? KEY_UP_DELAY : (nextHitObject.StartTime - endTime) * 0.9; Frames.Add(new TaikoReplayFrame(endTime + calculatedDelay)); From 9732f5d6226f739c51e6cae81b706581d5c0291d Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Mon, 19 Aug 2019 17:28:32 +0200 Subject: [PATCH 335/645] Add Swell to GetNextObject() check --- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 463bb84d07..fbc7b75854 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -142,7 +142,8 @@ namespace osu.Game.Rulesets.Taiko.Replays for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) { var currentObj = Beatmap.HitObjects[currentIndex]; - if (currentObj.GetType().Equals(desiredType) || currentObj is DrumRoll) + if (currentObj.GetType().Equals(desiredType) || + currentObj is DrumRoll || currentObj is Swell) // It's best to unpress any remaining keys before DrumRoll or Swell return Beatmap.HitObjects[currentIndex]; } From 70084b5553102e93fb5d592fb7d24d4672c070b4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 20:28:03 +0300 Subject: [PATCH 336/645] Move HitErrorDisplay outside of the HUD --- osu.Game/Screens/Play/HUDOverlay.cs | 22 ------ .../HitErrorDisplay.cs | 66 +++++------------- .../HitErrorDisplay/HitErrorDisplayOverlay.cs | 69 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 4 ++ 4 files changed, 90 insertions(+), 71 deletions(-) rename osu.Game/Screens/Play/{HUD => HitErrorDisplay}/HitErrorDisplay.cs (77%) create mode 100644 osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index be291003b5..1124c8f5f0 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -36,8 +36,6 @@ namespace osu.Game.Screens.Play public readonly ModDisplay ModDisplay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; - public readonly HitErrorDisplay LeftHitErrorDisplay; - public readonly HitErrorDisplay RightHitErrorDisplay; public Bindable ShowHealthbar = new Bindable(true); @@ -87,8 +85,6 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), - LeftHitErrorDisplay = CreateHitErrorDisplay(false), - RightHitErrorDisplay = CreateHitErrorDisplay(), } }, PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), @@ -261,13 +257,6 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; - protected virtual HitErrorDisplay CreateHitErrorDisplay(bool reversed = true) => new HitErrorDisplay(reversed) - { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Margin = new MarginPadding { Horizontal = 20 } - }; - protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); protected virtual void BindProcessor(ScoreProcessor processor) @@ -277,17 +266,6 @@ namespace osu.Game.Screens.Play ComboCounter?.Current.BindTo(processor.Combo); HealthDisplay?.Current.BindTo(processor.Health); - var hitWindows = processor.CreateHitWindows(); - - visibilityContainer.ForEach(drawable => - { - if (drawable is HitErrorDisplay) - { - processor.NewJudgement += ((HitErrorDisplay)drawable).OnNewJudgement; - ((HitErrorDisplay)drawable).HitWindows = hitWindows; - } - }); - if (HealthDisplay is StandardHealthDisplay shd) processor.NewJudgement += shd.Flash; } diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs similarity index 77% rename from osu.Game/Screens/Play/HUD/HitErrorDisplay.cs rename to osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs index 1a3682351b..1a776bc78d 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs @@ -10,16 +10,13 @@ using osuTK; using osu.Framework.Graphics.Sprites; using System.Collections.Generic; using osu.Game.Rulesets.Objects; -using osu.Game.Beatmaps; -using osu.Framework.Bindables; using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; using System.Linq; -using osu.Game.Configuration; -namespace osu.Game.Screens.Play.HUD +namespace osu.Game.Screens.Play.HitErrorDisplay { public class HitErrorDisplay : CompositeDrawable { @@ -27,29 +24,24 @@ namespace osu.Game.Screens.Play.HUD private const int bar_width = 3; private const int judgement_line_width = 8; private const int bar_height = 200; - private const int fade_duration = 200; private const int arrow_move_duration = 500; private const int judgement_life_time = 10000; private const int spacing = 3; - public HitWindows HitWindows { get; set; } - - [Resolved] - private Bindable beatmap { get; set; } - - [Resolved] - private OsuColour colours { get; set; } - + private readonly HitWindows hitWindows; private readonly SpriteIcon arrow; private readonly FillFlowContainer bar; private readonly Container judgementsContainer; private readonly Queue judgementOffsets = new Queue(); - private readonly Bindable type = new Bindable(); - - public HitErrorDisplay(bool reversed = false) + public HitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) { + this.hitWindows = hitWindows; + hitWindows.SetDifficulty(overallDifficulty); + AutoSizeAxes = Axes.Both; + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft; + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft; AddInternal(new FillFlowContainer { @@ -94,74 +86,50 @@ namespace osu.Game.Screens.Play.HUD } [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuColour colours) { - config.BindWith(OsuSetting.ScoreMeter, type); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - HitWindows.SetDifficulty(beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); - bar.AddRange(new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) + Height = (float)((getMehHitWindows() - hitWindows.Good) / (getMehHitWindows() * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) + Height = (float)((hitWindows.Good - hitWindows.Great) / (getMehHitWindows() * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.BlueLight, - Height = (float)(HitWindows.Great / getMehHitWindows()) + Height = (float)(hitWindows.Great / getMehHitWindows()) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) + Height = (float)((hitWindows.Good - hitWindows.Great) / (getMehHitWindows() * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) + Height = (float)((getMehHitWindows() - hitWindows.Good) / (getMehHitWindows() * 2)) } }); - - type.BindValueChanged(onTypeChanged, true); } private double getMehHitWindows() { // In case if ruleset has no Meh hit windows (like Taiko) - if (HitWindows.Meh == 0) - return HitWindows.Good + 40; + if (hitWindows.Meh == 0) + return hitWindows.Good + 40; - return HitWindows.Meh; - } - - private void onTypeChanged(ValueChangedEvent type) - { - switch (type.NewValue) - { - case ScoreMeterType.None: - this.FadeOut(fade_duration, Easing.OutQuint); - break; - - case ScoreMeterType.HitError: - this.FadeIn(fade_duration, Easing.OutQuint); - break; - } + return hitWindows.Meh; } public void OnNewJudgement(JudgementResult newJudgement) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs new file mode 100644 index 0000000000..09ecbdfc66 --- /dev/null +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -0,0 +1,69 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Rulesets.Scoring; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; +using System.Linq; + +namespace osu.Game.Screens.Play.HitErrorDisplay +{ + public class HitErrorDisplayOverlay : Container + { + private const int fade_duration = 200; + private const int margin = 10; + + private readonly Bindable type = new Bindable(); + + public HitErrorDisplayOverlay(ScoreProcessor processor, WorkingBeatmap workingBeatmap) + { + float overallDifficulty = workingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty; + + RelativeSizeAxes = Axes.Both; + Children = new[] + { + new HitErrorDisplay(overallDifficulty, processor.CreateHitWindows()) + { + Margin = new MarginPadding { Left = margin } + }, + new HitErrorDisplay(overallDifficulty, processor.CreateHitWindows(), true) + { + Margin = new MarginPadding { Right = margin } + }, + }; + + Children.ForEach(t => processor.NewJudgement += t.OnNewJudgement); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.ScoreMeter, type); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + type.BindValueChanged(onTypeChanged, true); + } + + private void onTypeChanged(ValueChangedEvent type) + { + switch (type.NewValue) + { + case ScoreMeterType.None: + InternalChildren.ForEach(t => t.FadeOut(fade_duration, Easing.OutQuint)); + break; + + default: + InternalChildren.ForEach(t => t.FadeIn(fade_duration, Easing.OutQuint)); + break; + } + } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e7398be176..9ef8cc4509 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,6 +24,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using osu.Game.Screens.Play.HitErrorDisplay; using osu.Game.Screens.Ranking; using osu.Game.Skinning; using osu.Game.Users; @@ -73,6 +74,8 @@ namespace osu.Game.Screens.Play protected HUDOverlay HUDOverlay { get; private set; } + protected HitErrorDisplayOverlay HitErrorDisplayOverlay { get; private set; } + public bool LoadedBeatmapSuccessfully => DrawableRuleset?.Objects.Any() == true; protected GameplayClockContainer GameplayClockContainer { get; private set; } @@ -157,6 +160,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, + HitErrorDisplayOverlay = new HitErrorDisplayOverlay(ScoreProcessor, working), new SkipOverlay(DrawableRuleset.GameplayStartTime) { RequestSeek = GameplayClockContainer.Seek From 6d3aa0520b6cc6bc999809b123b600414314260f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 20:44:06 +0300 Subject: [PATCH 337/645] Make HitErrorDisplay an abstract class --- .../HitErrorDisplay/DefaultHitErrorDisplay.cs | 174 ++++++++++++++++++ .../Play/HitErrorDisplay/HitErrorDisplay.cs | 167 +---------------- .../HitErrorDisplay/HitErrorDisplayOverlay.cs | 4 +- 3 files changed, 182 insertions(+), 163 deletions(-) create mode 100644 osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs diff --git a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs new file mode 100644 index 0000000000..6cf80b209a --- /dev/null +++ b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs @@ -0,0 +1,174 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Judgements; +using osuTK.Graphics; +using osuTK; +using osu.Framework.Graphics.Sprites; +using System.Collections.Generic; +using osu.Game.Rulesets.Objects; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Colour; +using osu.Game.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using System.Linq; + +namespace osu.Game.Screens.Play.HitErrorDisplay +{ + public class DefaultHitErrorDisplay : HitErrorDisplay + { + private const int stored_judgements_amount = 5; + private const int bar_width = 3; + private const int judgement_line_width = 8; + private const int bar_height = 200; + private const int arrow_move_duration = 500; + private const int judgement_life_time = 10000; + private const int spacing = 3; + + private readonly SpriteIcon arrow; + private readonly FillFlowContainer bar; + private readonly Container judgementsContainer; + private readonly Queue judgementOffsets = new Queue(); + + public DefaultHitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) + : base(overallDifficulty, hitWindows) + { + AutoSizeAxes = Axes.Both; + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft; + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft; + + AddInternal(new FillFlowContainer + { + AutoSizeAxes = Axes.X, + Height = bar_height, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Children = new Drawable[] + { + judgementsContainer = new Container + { + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Width = judgement_line_width, + RelativeSizeAxes = Axes.Y, + }, + bar = new FillFlowContainer + { + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Width = bar_width, + RelativeSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }, + new Container + { + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Child = arrow = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.Y, + Icon = reversed ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, + Size = new Vector2(8), + } + }, + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + bar.AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), + Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Green, + Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.BlueLight, + Height = (float)(HitWindows.Great / getMehHitWindows()) + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Green, + Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), + Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) + } + }); + } + + private double getMehHitWindows() + { + // In case if ruleset has no Meh hit windows (like Taiko) + if (HitWindows.Meh == 0) + return HitWindows.Good + 40; + + return HitWindows.Meh; + } + + public override void OnNewJudgement(JudgementResult newJudgement) + { + if (!newJudgement.IsHit) + return; + + var judgementLine = CreateJudgementLine(newJudgement); + + judgementsContainer.Add(judgementLine); + + judgementLine.FadeOut(judgement_life_time, Easing.OutQuint).Expire(); + + arrow.MoveToY(calculateArrowPosition(newJudgement), arrow_move_duration, Easing.OutQuint); + } + + protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + RelativeSizeAxes = Axes.X, + Height = 2, + RelativePositionAxes = Axes.Y, + Y = getRelativeJudgementPosition(judgement.TimeOffset), + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + } + }; + + private float getRelativeJudgementPosition(double value) => (float)(value / getMehHitWindows()); + + private float calculateArrowPosition(JudgementResult newJudgement) + { + if (judgementOffsets.Count > stored_judgements_amount) + judgementOffsets.Dequeue(); + + judgementOffsets.Enqueue(newJudgement.TimeOffset); + + return getRelativeJudgementPosition(judgementOffsets.Average()); + } + } +} diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs index 1a776bc78d..fb22b35736 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs @@ -1,177 +1,22 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Judgements; -using osuTK.Graphics; -using osuTK; -using osu.Framework.Graphics.Sprites; -using System.Collections.Generic; using osu.Game.Rulesets.Objects; -using osu.Framework.Allocation; -using osu.Framework.Graphics.Colour; -using osu.Game.Graphics; -using osu.Framework.Extensions.Color4Extensions; -using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { - public class HitErrorDisplay : CompositeDrawable + public abstract class HitErrorDisplay : CompositeDrawable { - private const int stored_judgements_amount = 5; - private const int bar_width = 3; - private const int judgement_line_width = 8; - private const int bar_height = 200; - private const int arrow_move_duration = 500; - private const int judgement_life_time = 10000; - private const int spacing = 3; + protected readonly HitWindows HitWindows; - private readonly HitWindows hitWindows; - private readonly SpriteIcon arrow; - private readonly FillFlowContainer bar; - private readonly Container judgementsContainer; - private readonly Queue judgementOffsets = new Queue(); - - public HitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) + public HitErrorDisplay(float overallDifficulty, HitWindows hitWindows) { - this.hitWindows = hitWindows; - hitWindows.SetDifficulty(overallDifficulty); - - AutoSizeAxes = Axes.Both; - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft; - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft; - - AddInternal(new FillFlowContainer - { - AutoSizeAxes = Axes.X, - Height = bar_height, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(spacing, 0), - Children = new Drawable[] - { - judgementsContainer = new Container - { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Width = judgement_line_width, - RelativeSizeAxes = Axes.Y, - }, - bar = new FillFlowContainer - { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Width = bar_width, - RelativeSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - }, - new Container - { - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Child = arrow = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativePositionAxes = Axes.Y, - Icon = reversed ? FontAwesome.Solid.ChevronRight : FontAwesome.Solid.ChevronLeft, - Size = new Vector2(8), - } - }, - } - }); + HitWindows = hitWindows; + HitWindows.SetDifficulty(overallDifficulty); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - bar.AddRange(new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - Height = (float)((getMehHitWindows() - hitWindows.Good) / (getMehHitWindows() * 2)) - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Green, - Height = (float)((hitWindows.Good - hitWindows.Great) / (getMehHitWindows() * 2)) - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.BlueLight, - Height = (float)(hitWindows.Great / getMehHitWindows()) - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Green, - Height = (float)((hitWindows.Good - hitWindows.Great) / (getMehHitWindows() * 2)) - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - Height = (float)((getMehHitWindows() - hitWindows.Good) / (getMehHitWindows() * 2)) - } - }); - } - - private double getMehHitWindows() - { - // In case if ruleset has no Meh hit windows (like Taiko) - if (hitWindows.Meh == 0) - return hitWindows.Good + 40; - - return hitWindows.Meh; - } - - public void OnNewJudgement(JudgementResult newJudgement) - { - if (!newJudgement.IsHit) - return; - - var judgementLine = CreateJudgementLine(newJudgement); - - judgementsContainer.Add(judgementLine); - - judgementLine.FadeOut(judgement_life_time, Easing.OutQuint).Expire(); - - arrow.MoveToY(calculateArrowPosition(newJudgement), arrow_move_duration, Easing.OutQuint); - } - - protected virtual Container CreateJudgementLine(JudgementResult judgement) => new CircularContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Masking = true, - RelativeSizeAxes = Axes.X, - Height = 2, - RelativePositionAxes = Axes.Y, - Y = getRelativeJudgementPosition(judgement.TimeOffset), - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - } - }; - - private float getRelativeJudgementPosition(double value) => (float)(value / getMehHitWindows()); - - private float calculateArrowPosition(JudgementResult newJudgement) - { - if (judgementOffsets.Count > stored_judgements_amount) - judgementOffsets.Dequeue(); - - judgementOffsets.Enqueue(newJudgement.TimeOffset); - - return getRelativeJudgementPosition(judgementOffsets.Average()); - } + public abstract void OnNewJudgement(JudgementResult newJudgement); } } diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index 09ecbdfc66..35b883ff27 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -27,11 +27,11 @@ namespace osu.Game.Screens.Play.HitErrorDisplay RelativeSizeAxes = Axes.Both; Children = new[] { - new HitErrorDisplay(overallDifficulty, processor.CreateHitWindows()) + new DefaultHitErrorDisplay(overallDifficulty, processor.CreateHitWindows()) { Margin = new MarginPadding { Left = margin } }, - new HitErrorDisplay(overallDifficulty, processor.CreateHitWindows(), true) + new DefaultHitErrorDisplay(overallDifficulty, processor.CreateHitWindows(), true) { Margin = new MarginPadding { Right = margin } }, From 9bd844bf4d41c6dd9b82aa7cbc27079b738b35d2 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Mon, 19 Aug 2019 19:54:22 +0200 Subject: [PATCH 338/645] Make comment more informative --- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index fbc7b75854..4d6730c0e6 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Replays { var currentObj = Beatmap.HitObjects[currentIndex]; if (currentObj.GetType().Equals(desiredType) || - currentObj is DrumRoll || currentObj is Swell) // It's best to unpress any remaining keys before DrumRoll or Swell + currentObj is DrumRoll || currentObj is Swell) // Unpress all keys before DrumRoll or Swell return Beatmap.HitObjects[currentIndex]; } From 6d84523bc0d87ba814ddddf1edcdff53812a48be Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 21:10:12 +0300 Subject: [PATCH 339/645] Add testing --- .../Gameplay/TestSceneHitErrorDisplay.cs | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs new file mode 100644 index 0000000000..c5e5e96ad9 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs @@ -0,0 +1,110 @@ +// 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.Osu.Objects; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Screens.Play.HitErrorDisplay; +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osu.Framework.MathUtils; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public class TestSceneHitErrorDisplay : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(HitErrorDisplay), + }; + + private HitErrorDisplay display; + + public TestSceneHitErrorDisplay() + { + recreateDisplay(new OsuHitWindows(), 5); + AddStep("New random judgement", () => newJudgement()); + AddStep("New fixed judgement (50ms)", () => newJudgement(50)); + } + + [Test] + public void TestOsu() + { + AddStep("OD 1", () => recreateDisplay(new OsuHitWindows(), 1)); + AddStep("OD 2", () => recreateDisplay(new OsuHitWindows(), 2)); + AddStep("OD 3", () => recreateDisplay(new OsuHitWindows(), 3)); + AddStep("OD 4", () => recreateDisplay(new OsuHitWindows(), 4)); + AddStep("OD 5", () => recreateDisplay(new OsuHitWindows(), 5)); + AddStep("OD 6", () => recreateDisplay(new OsuHitWindows(), 6)); + AddStep("OD 7", () => recreateDisplay(new OsuHitWindows(), 7)); + AddStep("OD 8", () => recreateDisplay(new OsuHitWindows(), 8)); + AddStep("OD 9", () => recreateDisplay(new OsuHitWindows(), 9)); + AddStep("OD 10", () => recreateDisplay(new OsuHitWindows(), 10)); + } + + [Test] + public void TestTaiko() + { + AddStep("OD 1", () => recreateDisplay(new TaikoHitWindows(), 1)); + AddStep("OD 2", () => recreateDisplay(new TaikoHitWindows(), 2)); + AddStep("OD 3", () => recreateDisplay(new TaikoHitWindows(), 3)); + AddStep("OD 4", () => recreateDisplay(new TaikoHitWindows(), 4)); + AddStep("OD 5", () => recreateDisplay(new TaikoHitWindows(), 5)); + AddStep("OD 6", () => recreateDisplay(new TaikoHitWindows(), 6)); + AddStep("OD 7", () => recreateDisplay(new TaikoHitWindows(), 7)); + AddStep("OD 8", () => recreateDisplay(new TaikoHitWindows(), 8)); + AddStep("OD 9", () => recreateDisplay(new TaikoHitWindows(), 9)); + AddStep("OD 10", () => recreateDisplay(new TaikoHitWindows(), 10)); + } + + [Test] + public void TestMania() + { + AddStep("OD 1", () => recreateDisplay(new ManiaHitWindows(), 1)); + AddStep("OD 2", () => recreateDisplay(new ManiaHitWindows(), 2)); + AddStep("OD 3", () => recreateDisplay(new ManiaHitWindows(), 3)); + AddStep("OD 4", () => recreateDisplay(new ManiaHitWindows(), 4)); + AddStep("OD 5", () => recreateDisplay(new ManiaHitWindows(), 5)); + AddStep("OD 6", () => recreateDisplay(new ManiaHitWindows(), 6)); + AddStep("OD 7", () => recreateDisplay(new ManiaHitWindows(), 7)); + AddStep("OD 8", () => recreateDisplay(new ManiaHitWindows(), 8)); + AddStep("OD 9", () => recreateDisplay(new ManiaHitWindows(), 9)); + AddStep("OD 10", () => recreateDisplay(new ManiaHitWindows(), 10)); + } + + [Test] + public void TestCatch() + { + AddStep("OD 1", () => recreateDisplay(new CatchHitWindows(), 1)); + AddStep("OD 2", () => recreateDisplay(new CatchHitWindows(), 2)); + AddStep("OD 3", () => recreateDisplay(new CatchHitWindows(), 3)); + AddStep("OD 4", () => recreateDisplay(new CatchHitWindows(), 4)); + AddStep("OD 5", () => recreateDisplay(new CatchHitWindows(), 5)); + AddStep("OD 6", () => recreateDisplay(new CatchHitWindows(), 6)); + AddStep("OD 7", () => recreateDisplay(new CatchHitWindows(), 7)); + AddStep("OD 8", () => recreateDisplay(new CatchHitWindows(), 8)); + AddStep("OD 9", () => recreateDisplay(new CatchHitWindows(), 9)); + AddStep("OD 10", () => recreateDisplay(new CatchHitWindows(), 10)); + } + + private void recreateDisplay(HitWindows hitWindows, float overallDifficulty) + { + Clear(); + Add(display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows)); + } + + private void newJudgement(float offset = 0) + { + display?.OnNewJudgement(new JudgementResult(new Judgement()) + { + TimeOffset = offset == 0 ? RNG.Next(-70, 70) : offset, + Type = HitResult.Perfect, + }); + } + } +} From 1bff103d3244aff12c6faf83454cb43bbfd2d852 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 21:25:14 +0300 Subject: [PATCH 340/645] CI fixes --- .../Visual/Gameplay/TestSceneHitErrorDisplay.cs | 7 ++++++- osu.Game/Screens/Play/HUDOverlay.cs | 1 - .../Play/HitErrorDisplay/DefaultHitErrorDisplay.cs | 2 -- osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs | 2 +- .../Play/HitErrorDisplay/HitErrorDisplayOverlay.cs | 9 ++++++--- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs index c5e5e96ad9..e86606e4fc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Framework.MathUtils; +using osu.Framework.Graphics; namespace osu.Game.Tests.Visual.Gameplay { @@ -95,7 +96,11 @@ namespace osu.Game.Tests.Visual.Gameplay private void recreateDisplay(HitWindows hitWindows, float overallDifficulty) { Clear(); - Add(display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows)); + Add(display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); } private void newJudgement(float offset = 0) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 1124c8f5f0..43b9491750 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; diff --git a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs index 6cf80b209a..a0b9787c5f 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs @@ -37,8 +37,6 @@ namespace osu.Game.Screens.Play.HitErrorDisplay : base(overallDifficulty, hitWindows) { AutoSizeAxes = Axes.Both; - Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft; - Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft; AddInternal(new FillFlowContainer { diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs index fb22b35736..10b5e5b1cb 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { protected readonly HitWindows HitWindows; - public HitErrorDisplay(float overallDifficulty, HitWindows hitWindows) + protected HitErrorDisplay(float overallDifficulty, HitWindows hitWindows) { HitWindows = hitWindows; HitWindows.SetDifficulty(overallDifficulty); diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index 35b883ff27..fd118a26e5 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Framework.Extensions.IEnumerableExtensions; -using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { @@ -29,11 +28,15 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { new DefaultHitErrorDisplay(overallDifficulty, processor.CreateHitWindows()) { - Margin = new MarginPadding { Left = margin } + Margin = new MarginPadding { Left = margin }, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, }, new DefaultHitErrorDisplay(overallDifficulty, processor.CreateHitWindows(), true) { - Margin = new MarginPadding { Right = margin } + Margin = new MarginPadding { Right = margin }, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, }, }; From 77e9e89fecdcac72fd34e607fe4f909b2b83cbf0 Mon Sep 17 00:00:00 2001 From: Desconocidosmh Date: Mon, 19 Aug 2019 20:45:23 +0200 Subject: [PATCH 341/645] Refactoring --- osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs | 8 ++++---- osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index b9dd32208e..fd0a876775 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -81,14 +81,14 @@ namespace osu.Game.Rulesets.Mania.Replays for (int i = 0; i < Beatmap.HitObjects.Count; i++) { var currentObject = Beatmap.HitObjects[i]; - var nextObjectInTheSameColumn = GetNextObject(i); + var nextObjectInColumn = GetNextObject(i); // Get the next object that requires pressing the same button double endTime = (currentObject as IHasEndTime)?.EndTime ?? currentObject.StartTime; - bool canDelayKeyUp = nextObjectInTheSameColumn == null || - nextObjectInTheSameColumn.StartTime > endTime + RELEASE_DELAY; + bool canDelayKeyUp = nextObjectInColumn == null || + nextObjectInColumn.StartTime > endTime + RELEASE_DELAY; - double calculatedDelay = canDelayKeyUp ? RELEASE_DELAY : (nextObjectInTheSameColumn.StartTime - endTime) * 0.9; + double calculatedDelay = canDelayKeyUp ? RELEASE_DELAY : (nextObjectInColumn.StartTime - endTime) * 0.9; yield return new HitPoint { Time = currentObject.StartTime, Column = currentObject.Column }; diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index 4d6730c0e6..6720d8b8bf 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Taiko.Replays else throw new InvalidOperationException("Unknown hit object type."); - var nextHitObject = GetNextObject(i); + var nextHitObject = GetNextObject(i); // Get the next object that requires pressing the same button bool canDelayKeyUp = nextHitObject == null || nextHitObject.StartTime > endTime + KEY_UP_DELAY; @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Taiko.Replays for (; currentIndex < Beatmap.HitObjects.Count; currentIndex++) { var currentObj = Beatmap.HitObjects[currentIndex]; - if (currentObj.GetType().Equals(desiredType) || + if (currentObj.GetType() == desiredType || currentObj is DrumRoll || currentObj is Swell) // Unpress all keys before DrumRoll or Swell return Beatmap.HitObjects[currentIndex]; } From f1c3a60660d035128c8f3e938f88b216d4ab8669 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 22:04:27 +0300 Subject: [PATCH 342/645] Add ability to select side --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Configuration/ScoreMeterType.cs | 10 ++- .../HitErrorDisplay/HitErrorDisplayOverlay.cs | 66 +++++++++++++------ 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index bffbce2a52..fbb17fa7f9 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -79,7 +79,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ShowInterface, true); Set(OsuSetting.ShowHealthDisplayWhenCantFail, true); Set(OsuSetting.KeyOverlay, false); - Set(OsuSetting.ScoreMeter, ScoreMeterType.HitError); + Set(OsuSetting.ScoreMeter, ScoreMeterType.HitErrorBoth); Set(OsuSetting.FloatingComments, false); diff --git a/osu.Game/Configuration/ScoreMeterType.cs b/osu.Game/Configuration/ScoreMeterType.cs index e78220c9c9..b85ef9309d 100644 --- a/osu.Game/Configuration/ScoreMeterType.cs +++ b/osu.Game/Configuration/ScoreMeterType.cs @@ -10,7 +10,13 @@ namespace osu.Game.Configuration [Description("None")] None, - [Description("Hit Error")] - HitError + [Description("Hit Error (left)")] + HitErrorLeft, + + [Description("Hit Error (right)")] + HitErrorRight, + + [Description("Hit Error (both)")] + HitErrorBoth, } } diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index fd118a26e5..bbed2b1618 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Play.HitErrorDisplay { @@ -18,29 +19,18 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private const int margin = 10; private readonly Bindable type = new Bindable(); + private readonly HitWindows hitWindows; + private readonly ScoreProcessor processor; + private readonly float overallDifficulty; public HitErrorDisplayOverlay(ScoreProcessor processor, WorkingBeatmap workingBeatmap) { - float overallDifficulty = workingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty; + this.processor = processor; + + overallDifficulty = workingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty; + hitWindows = processor.CreateHitWindows(); RelativeSizeAxes = Axes.Both; - Children = new[] - { - new DefaultHitErrorDisplay(overallDifficulty, processor.CreateHitWindows()) - { - Margin = new MarginPadding { Left = margin }, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - }, - new DefaultHitErrorDisplay(overallDifficulty, processor.CreateHitWindows(), true) - { - Margin = new MarginPadding { Right = margin }, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - }, - }; - - Children.ForEach(t => processor.NewJudgement += t.OnNewJudgement); } [BackgroundDependencyLoader] @@ -57,16 +47,50 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private void onTypeChanged(ValueChangedEvent type) { + clear(); + switch (type.NewValue) { case ScoreMeterType.None: - InternalChildren.ForEach(t => t.FadeOut(fade_duration, Easing.OutQuint)); break; - default: - InternalChildren.ForEach(t => t.FadeIn(fade_duration, Easing.OutQuint)); + case ScoreMeterType.HitErrorBoth: + createNew(); + createNew(true); + break; + + case ScoreMeterType.HitErrorLeft: + createNew(); + break; + + case ScoreMeterType.HitErrorRight: + createNew(true); break; } } + + private void clear() + { + Children.ForEach(t => + { + processor.NewJudgement -= t.OnNewJudgement; + t.FadeOut(fade_duration, Easing.OutQuint).Expire(); + }); + } + + private void createNew(bool reversed = false) + { + var display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows, reversed) + { + Margin = new MarginPadding(margin), + Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, + Alpha = 0, + }; + + processor.NewJudgement += display.OnNewJudgement; + Add(display); + display.FadeInFromZero(fade_duration, Easing.OutQuint); + } } } From 50c47568e434f5a68002d40610d1618f221fbd39 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 22:45:27 +0300 Subject: [PATCH 343/645] Don't present Meh hit windows if it has no value --- .../Gameplay/TestSceneHitErrorDisplay.cs | 19 +++++++ .../HitErrorDisplay/DefaultHitErrorDisplay.cs | 54 ++++++++++--------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs index e86606e4fc..006773a091 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs @@ -14,6 +14,8 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Framework.MathUtils; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; namespace osu.Game.Tests.Visual.Gameplay { @@ -95,7 +97,24 @@ namespace osu.Game.Tests.Visual.Gameplay private void recreateDisplay(HitWindows hitWindows, float overallDifficulty) { + hitWindows.SetDifficulty(overallDifficulty); + Clear(); + + Add(new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Children = new[] + { + new SpriteText { Text = $@"Great: {hitWindows.Great}" }, + new SpriteText { Text = $@"Good: {hitWindows.Good}" }, + new SpriteText { Text = $@"Meh: {hitWindows.Meh}" }, + } + }); + Add(display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows) { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs index a0b9787c5f..11de0696d3 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs @@ -32,12 +32,14 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly FillFlowContainer bar; private readonly Container judgementsContainer; private readonly Queue judgementOffsets = new Queue(); + private readonly double maxHitWindows; public DefaultHitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) : base(overallDifficulty, hitWindows) { - AutoSizeAxes = Axes.Both; + maxHitWindows = HitWindows.Meh == 0 ? HitWindows.Good : HitWindows.Meh; + AutoSizeAxes = Axes.Both; AddInternal(new FillFlowContainer { AutoSizeAxes = Axes.X, @@ -83,48 +85,52 @@ namespace osu.Game.Screens.Play.HitErrorDisplay [BackgroundDependencyLoader] private void load(OsuColour colours) { - bar.AddRange(new Drawable[] - { - new Box + Box topGreenBox; + Box bottomGreenBox; + + if (HitWindows.Meh != 0) + bar.Add(new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) - }, - new Box + Height = (float)((maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)) + }); + + bar.AddRange(new Drawable[] + { + topGreenBox = new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) + Height = (float)((HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)) }, new Box { RelativeSizeAxes = Axes.Both, Colour = colours.BlueLight, - Height = (float)(HitWindows.Great / getMehHitWindows()) + Height = (float)(HitWindows.Great / maxHitWindows) }, - new Box + bottomGreenBox = new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (getMehHitWindows() * 2)) - }, - new Box + Height = (float)((HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)) + } + });; + + if (HitWindows.Meh != 0) + bar.Add(new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - Height = (float)((getMehHitWindows() - HitWindows.Good) / (getMehHitWindows() * 2)) - } - }); - } + Height = (float)((maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)) + }); - private double getMehHitWindows() - { - // In case if ruleset has no Meh hit windows (like Taiko) if (HitWindows.Meh == 0) - return HitWindows.Good + 40; - - return HitWindows.Meh; + { + topGreenBox.Colour = ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green); + bottomGreenBox.Colour = ColourInfo.GradientVertical(colours.Green, colours.Green.Opacity(0)); + } } public override void OnNewJudgement(JudgementResult newJudgement) @@ -157,7 +163,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay } }; - private float getRelativeJudgementPosition(double value) => (float)(value / getMehHitWindows()); + private float getRelativeJudgementPosition(double value) => (float)(value / maxHitWindows); private float calculateArrowPosition(JudgementResult newJudgement) { From 415f1802614dbcd96541746a02a8a61500ba07bb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 19 Aug 2019 22:53:28 +0300 Subject: [PATCH 344/645] Delete extra semicolon --- osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs index 11de0696d3..2d05dc8aba 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay Colour = colours.Green, Height = (float)((HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)) } - });; + }); if (HitWindows.Meh != 0) bar.Add(new Box From 62a24bf16d38ffbf9460a8025748c012b20d1939 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 13:18:34 +0900 Subject: [PATCH 345/645] Fix a couple of rotation-related issues --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 332e25750f..02505c3ec0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -174,9 +174,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var newPos = slider.CurvePositionAt(completionProgress); var diff = lastPosition.HasValue ? lastPosition.Value - newPos : newPos - slider.CurvePositionAt(completionProgress + 0.01f); + if (diff == Vector2.Zero) + return; Position = newPos; - Rotation = 90 + (float)(-Math.Atan2(diff.X, diff.Y) * 180 / Math.PI); + Rotation = -90 + (float)(-Math.Atan2(diff.X, diff.Y) * 180 / Math.PI); lastPosition = newPos; } From 550311698b74769f95f35f130f72ae84e17c775d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 13:18:59 +0900 Subject: [PATCH 346/645] Update slider test scene --- .../TestSceneSlider.cs | 160 ++++++++++-------- 1 file changed, 86 insertions(+), 74 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index c5a27205d6..29c71a8903 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -10,7 +10,6 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Tests.Visual; using osuTK; using osuTK.Graphics; using osu.Game.Rulesets.Mods; @@ -27,83 +26,96 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSlider : OsuTestScene + public class TestSceneSlider : SkinnableTestScene { public override IReadOnlyList RequiredTypes => new[] { + typeof(Slider), + typeof(SliderTick), + typeof(SliderTailCircle), typeof(SliderBall), typeof(SliderBody), - typeof(SliderTick), + typeof(SnakingSliderBody), typeof(DrawableSlider), typeof(DrawableSliderTick), + typeof(DrawableSliderTail), + typeof(DrawableSliderHead), typeof(DrawableRepeatPoint), typeof(DrawableOsuHitObject) }; - private readonly Container content; - protected override Container Content => content; + private Container content; + + protected override Container Content + { + get + { + if (content == null) + base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 })); + + return content; + } + } private int depthIndex; public TestSceneSlider() { - base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 })); + AddStep("Big Single", () => SetContents(() => testSimpleBig())); + AddStep("Medium Single", () => SetContents(() => testSimpleMedium())); + AddStep("Small Single", () => SetContents(() => testSimpleSmall())); + AddStep("Big 1 Repeat", () => SetContents(() => testSimpleBig(1))); + AddStep("Medium 1 Repeat", () => SetContents(() => testSimpleMedium(1))); + AddStep("Small 1 Repeat", () => SetContents(() => testSimpleSmall(1))); + AddStep("Big 2 Repeats", () => SetContents(() => testSimpleBig(2))); + AddStep("Medium 2 Repeats", () => SetContents(() => testSimpleMedium(2))); + AddStep("Small 2 Repeats", () => SetContents(() => testSimpleSmall(2))); - AddStep("Big Single", () => testSimpleBig()); - AddStep("Medium Single", () => testSimpleMedium()); - AddStep("Small Single", () => testSimpleSmall()); - AddStep("Big 1 Repeat", () => testSimpleBig(1)); - AddStep("Medium 1 Repeat", () => testSimpleMedium(1)); - AddStep("Small 1 Repeat", () => testSimpleSmall(1)); - AddStep("Big 2 Repeats", () => testSimpleBig(2)); - AddStep("Medium 2 Repeats", () => testSimpleMedium(2)); - AddStep("Small 2 Repeats", () => testSimpleSmall(2)); + AddStep("Slow Slider", () => SetContents(testSlowSpeed)); // slow long sliders take ages already so no repeat steps + AddStep("Slow Short Slider", () => SetContents(() => testShortSlowSpeed())); + AddStep("Slow Short Slider 1 Repeats", () => SetContents(() => testShortSlowSpeed(1))); + AddStep("Slow Short Slider 2 Repeats", () => SetContents(() => testShortSlowSpeed(2))); - AddStep("Slow Slider", testSlowSpeed); // slow long sliders take ages already so no repeat steps - AddStep("Slow Short Slider", () => testShortSlowSpeed()); - AddStep("Slow Short Slider 1 Repeats", () => testShortSlowSpeed(1)); - AddStep("Slow Short Slider 2 Repeats", () => testShortSlowSpeed(2)); + AddStep("Fast Slider", () => SetContents(() => testHighSpeed())); + AddStep("Fast Slider 1 Repeat", () => SetContents(() => testHighSpeed(1))); + AddStep("Fast Slider 2 Repeats", () => SetContents(() => testHighSpeed(2))); + AddStep("Fast Short Slider", () => SetContents(() => testShortHighSpeed())); + AddStep("Fast Short Slider 1 Repeat", () => SetContents(() => testShortHighSpeed(1))); + AddStep("Fast Short Slider 2 Repeats", () => SetContents(() => testShortHighSpeed(2))); + AddStep("Fast Short Slider 6 Repeats", () => SetContents(() => testShortHighSpeed(6))); - AddStep("Fast Slider", () => testHighSpeed()); - AddStep("Fast Slider 1 Repeat", () => testHighSpeed(1)); - AddStep("Fast Slider 2 Repeats", () => testHighSpeed(2)); - AddStep("Fast Short Slider", () => testShortHighSpeed()); - AddStep("Fast Short Slider 1 Repeat", () => testShortHighSpeed(1)); - AddStep("Fast Short Slider 2 Repeats", () => testShortHighSpeed(2)); - AddStep("Fast Short Slider 6 Repeats", () => testShortHighSpeed(6)); + AddStep("Perfect Curve", () => SetContents(() => testPerfect())); + AddStep("Perfect Curve 1 Repeat", () => SetContents(() => testPerfect(1))); + AddStep("Perfect Curve 2 Repeats", () => SetContents(() => testPerfect(2))); - AddStep("Perfect Curve", () => testPerfect()); - AddStep("Perfect Curve 1 Repeat", () => testPerfect(1)); - AddStep("Perfect Curve 2 Repeats", () => testPerfect(2)); + AddStep("Linear Slider", () => SetContents(() => testLinear())); + AddStep("Linear Slider 1 Repeat", () => SetContents(() => testLinear(1))); + AddStep("Linear Slider 2 Repeats", () => SetContents(() => testLinear(2))); - AddStep("Linear Slider", () => testLinear()); - AddStep("Linear Slider 1 Repeat", () => testLinear(1)); - AddStep("Linear Slider 2 Repeats", () => testLinear(2)); + AddStep("Bezier Slider", () => SetContents(() => testBezier())); + AddStep("Bezier Slider 1 Repeat", () => SetContents(() => testBezier(1))); + AddStep("Bezier Slider 2 Repeats", () => SetContents(() => testBezier(2))); - AddStep("Bezier Slider", () => testBezier()); - AddStep("Bezier Slider 1 Repeat", () => testBezier(1)); - AddStep("Bezier Slider 2 Repeats", () => testBezier(2)); + AddStep("Linear Overlapping", () => SetContents(() => testLinearOverlapping())); + AddStep("Linear Overlapping 1 Repeat", () => SetContents(() => testLinearOverlapping(1))); + AddStep("Linear Overlapping 2 Repeats", () => SetContents(() => testLinearOverlapping(2))); - AddStep("Linear Overlapping", () => testLinearOverlapping()); - AddStep("Linear Overlapping 1 Repeat", () => testLinearOverlapping(1)); - AddStep("Linear Overlapping 2 Repeats", () => testLinearOverlapping(2)); + AddStep("Catmull Slider", () => SetContents(() => testCatmull())); + AddStep("Catmull Slider 1 Repeat", () => SetContents(() => testCatmull(1))); + AddStep("Catmull Slider 2 Repeats", () => SetContents(() => testCatmull(2))); - AddStep("Catmull Slider", () => testCatmull()); - AddStep("Catmull Slider 1 Repeat", () => testCatmull(1)); - AddStep("Catmull Slider 2 Repeats", () => testCatmull(2)); + AddStep("Big Single, Large StackOffset", () => SetContents(() => testSimpleBigLargeStackOffset())); + AddStep("Big 1 Repeat, Large StackOffset", () => SetContents(() => testSimpleBigLargeStackOffset(1))); - AddStep("Big Single, Large StackOffset", () => testSimpleBigLargeStackOffset()); - AddStep("Big 1 Repeat, Large StackOffset", () => testSimpleBigLargeStackOffset(1)); - - AddStep("Distance Overflow", () => testDistanceOverflow()); - AddStep("Distance Overflow 1 Repeat", () => testDistanceOverflow(1)); + AddStep("Distance Overflow", () => SetContents(() => testDistanceOverflow())); + AddStep("Distance Overflow 1 Repeat", () => SetContents(() => testDistanceOverflow(1))); } - private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats); + private Drawable testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats); - private void testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10); + private Drawable testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10); - private void testDistanceOverflow(int repeats = 0) + private Drawable testDistanceOverflow(int repeats = 0) { var slider = new Slider { @@ -120,22 +132,22 @@ namespace osu.Game.Rulesets.Osu.Tests StackHeight = 10 }; - addSlider(slider, 2, 2); + return createDrawable(slider, 2, 2); } - private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats); + private Drawable testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats); - private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats); + private Drawable testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats); - private void testSlowSpeed() => createSlider(speedMultiplier: 0.5); + private Drawable testSlowSpeed() => createSlider(speedMultiplier: 0.5); - private void testShortSlowSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 0.5); + private Drawable testShortSlowSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 0.5); - private void testHighSpeed(int repeats = 0) => createSlider(repeats: repeats, speedMultiplier: 15); + private Drawable testHighSpeed(int repeats = 0) => createSlider(repeats: repeats, speedMultiplier: 15); - private void testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15); + private Drawable testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15); - private void createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2, int stackHeight = 0) + private Drawable createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2, int stackHeight = 0) { var slider = new Slider { @@ -151,10 +163,10 @@ namespace osu.Game.Rulesets.Osu.Tests StackHeight = stackHeight }; - addSlider(slider, circleSize, speedMultiplier); + return createDrawable(slider, circleSize, speedMultiplier); } - private void testPerfect(int repeats = 0) + private Drawable testPerfect(int repeats = 0) { var slider = new Slider { @@ -170,12 +182,12 @@ namespace osu.Game.Rulesets.Osu.Tests NodeSamples = createEmptySamples(repeats) }; - addSlider(slider, 2, 3); + return createDrawable(slider, 2, 3); } - private void testLinear(int repeats = 0) => createLinear(repeats); + private Drawable testLinear(int repeats = 0) => createLinear(repeats); - private void createLinear(int repeats) + private Drawable createLinear(int repeats) { var slider = new Slider { @@ -194,12 +206,12 @@ namespace osu.Game.Rulesets.Osu.Tests NodeSamples = createEmptySamples(repeats) }; - addSlider(slider, 2, 3); + return createDrawable(slider, 2, 3); } - private void testBezier(int repeats = 0) => createBezier(repeats); + private Drawable testBezier(int repeats = 0) => createBezier(repeats); - private void createBezier(int repeats) + private Drawable createBezier(int repeats) { var slider = new Slider { @@ -217,12 +229,12 @@ namespace osu.Game.Rulesets.Osu.Tests NodeSamples = createEmptySamples(repeats) }; - addSlider(slider, 2, 3); + return createDrawable(slider, 2, 3); } - private void testLinearOverlapping(int repeats = 0) => createOverlapping(repeats); + private Drawable testLinearOverlapping(int repeats = 0) => createOverlapping(repeats); - private void createOverlapping(int repeats) + private Drawable createOverlapping(int repeats) { var slider = new Slider { @@ -241,12 +253,12 @@ namespace osu.Game.Rulesets.Osu.Tests NodeSamples = createEmptySamples(repeats) }; - addSlider(slider, 2, 3); + return createDrawable(slider, 2, 3); } - private void testCatmull(int repeats = 0) => createCatmull(repeats); + private Drawable testCatmull(int repeats = 0) => createCatmull(repeats); - private void createCatmull(int repeats = 0) + private Drawable createCatmull(int repeats = 0) { var repeatSamples = new List>(); for (int i = 0; i < repeats; i++) @@ -267,7 +279,7 @@ namespace osu.Game.Rulesets.Osu.Tests NodeSamples = repeatSamples }; - addSlider(slider, 3, 1); + return createDrawable(slider, 3, 1); } private List> createEmptySamples(int repeats) @@ -278,7 +290,7 @@ namespace osu.Game.Rulesets.Osu.Tests return repeatSamples; } - private void addSlider(Slider slider, float circleSize, double speedMultiplier) + private Drawable createDrawable(Slider slider, float circleSize, double speedMultiplier) { var cpi = new ControlPointInfo(); cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier }); @@ -296,7 +308,7 @@ namespace osu.Game.Rulesets.Osu.Tests drawable.OnNewResult += onNewResult; - Add(drawable); + return drawable; } private float judgementOffsetDirection = 1; From b5cb59faf2a3f17602e7c2d81dc1c8970c705cb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 13:19:23 +0900 Subject: [PATCH 347/645] Add default skin sprites and specular/diffuse layer support --- .../Resources/default-skin/sliderb-nd@2x.png | Bin 0 -> 14258 bytes .../default-skin/sliderb-spec@2x.png | Bin 0 -> 13141 bytes .../Resources/default-skin/sliderb0@2x.png | Bin 0 -> 17053 bytes .../Resources/default-skin/sliderb1@2x.png | Bin 0 -> 17792 bytes .../Resources/default-skin/sliderb2@2x.png | Bin 0 -> 18268 bytes .../Resources/default-skin/sliderb3@2x.png | Bin 0 -> 18182 bytes .../Resources/default-skin/sliderb4@2x.png | Bin 0 -> 18062 bytes .../Resources/default-skin/sliderb5@2x.png | Bin 0 -> 16895 bytes .../Resources/default-skin/sliderb6@2x.png | Bin 0 -> 16702 bytes .../Resources/default-skin/sliderb7@2x.png | Bin 0 -> 17139 bytes .../Resources/default-skin/sliderb8@2x.png | Bin 0 -> 17084 bytes .../Resources/default-skin/sliderb9@2x.png | Bin 0 -> 17067 bytes osu.Game/Skinning/LegacySkin.cs | 23 +++++++++++++++--- 13 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-nd@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-spec@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb0@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb1@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb2@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb3@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb4@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb5@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb6@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb7@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb8@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb9@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-nd@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-nd@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..626fd91e386796be54e3ff952006082d90361319 GIT binary patch literal 14258 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-spec@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb-spec@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..76fd9ab16807c2ef61dd2aa0db47c78262db03b2 GIT binary patch literal 13141 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 O@*I3?M71L9&Hn(Rv4%VV literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb1@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e99f076947aa7ca1614fe825839dd3d7b8dcc303 GIT binary patch literal 17792 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb2@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb2@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..cd36a0ae169e1d876012402b2b7aa34a13a179d6 GIT binary patch literal 18268 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 SqgKcO0000l1{&5@md}*`-!Dp9 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 Y0Z!VEjc(%0RR91007*qoM6N<$f_m)to&W#< literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb4@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb4@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b19887d64f0040da387029545dea15d85669c9 GIT binary patch literal 18062 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 Hu0mjf{m45K literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb5@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb01f0e88229c6433c6363d7f7c725776372683 GIT binary patch literal 16895 zcmYMc2Q-}D7d8A4L<>fXkPxHy61|hrd+(j-C0az6D5FKx#Hdjdy^B$U@Iw&Mi4win zi0JRl|9!vpt%c#4@!UJ^z31$`&pu+bG!*aQQ{zJrbWd3cp#vUw|9#@(fUhscRLH>t zo~M$rHv|!o{rkj#P+3&qqN0zyk&l9tt3C8o%*<3#M^;No`RQXV9Tjsk(f3MMVaH6S}tc?)K3CzOK=mr-RF6|1Rr*DcO7d|ATPz^Cn|R zbVJZ%NEsok=RdpG7WiIoB7^%T*k#ZBUAyqTd--PMS}@pGj@ZZf2uw^&3oYAkBFeo_ zo+YbkFsH1p`X!5W@TELy9ujRfBvRl$pR@zcFxo~i^aDXNuzkpLg|HW~maksa(WyS>F3%XEB zoQ~@rE(9K6z%byY`rDCO4i&8*G_yo%@@r~pRHjbDX%kCi$LhbJitpLP-@^)1={4el zPr|ghY~wK?#UAr;nWgA2R=g-BMhJ!h`&3YH=Q>0hm;SdFYoVc@UQZ;6BUKb0l!HQ1 zGf*d}Kvo_d*Nu9EmLcEANmH@eJzDk}G0>HkYiE~=0c{I>sN(EFQEAJudNK7ecF~Qr zEN`BThr4%R;e39xCMG>t5R!;a>S6os^+8GU8wd(Hd`;Jr8+!9{B|&&0508ww`fMRk z^9`M}g;B>K6m};J3;Mhq%kkEG_jQSnC(Ec;(;YFkwRwvw;p4+@;ukwZ7SF#@ zEFJk%!TBL89hGe4W6HSx^mNLjewJLS?NoMxxf0KviY6klv!C8PKLqwD&8Jv)&>=CE zI~)FO7Ki>4ouYTu$27>snLnuy>%9^)8h_GGngl_|=Rxx!2Oe#wltz;Vn2=fU=>(2# zJPcMQPt-|Mk-!L}bOM|w^u93ky& zCDah=S#7x!ZVM$O^%U_1n}9Oahraz!LsiZC`nn06n!U)CG2fq&6fZ~Q`SRiZe2e%* zQ9kZm${_@O%NCysJ^FgzvUKNS9#uSa;xEyy!{sEFE09*$zsQpEBzpuERb3XdDGSG6 z2)W#oY!tb@8oAw#Qz&4#*ZtW-$%YEv^jJlwFiw--8FZQb3st)dgbMHNN#2p?7aD~UnzzmVNH%PTmIRM1~X z^)X5(lwU`&Q^DSU?%Tg6QN;{SDAq&c2=()qlCXJ8L&GV*uM~!eao=)^_He0KE0F&YJHI= zYIJ&Z6yulY-`AcZS3#<(gHLFL-GemE6Jo2K_?~^EB7(ebZ>|NrR+U78{_;Z5)zyad zSzz13gRB!C@8J?hR4>>{+{-(R!F4b}T~D^Shd7W?9P&&fON7sC-{oe<@)kY78;>oA z8MLjTN<_d(h@v%peS9S5W@j%}(Y`wiT81U?T_-{sq4)<;^e)cMB#n1G1a>VFTa zUM|P5^z!$%_ljB;I+;Z3-U!@3-_bkEOe7qZGs6s1NBGb|_3?Dl?NeDPeRQEgA4!(W z1GVQs~&sPE_&W&6BpEo$6 zZdr@2SjGfK_z3STABjv;3R4j_M#z1T77!M`bzbRBP$aj$LK81?UeiQ z-4%Y3L}C*JPYSbhp^5vNS64?iJ39*p0b(Rd?!#@H^F%2_Y;_xn@Phx!7A_;yX?b(} zuD;5=!C9ZncK1nqjUtt8fyjo5n6%&{WELS4Z}=>3%IYQKy; z5;%i409PoKGs*KL3M*=q%DB%DVKVKpG%B?E{A$vGs0&_R*-YzHuIk`j%NFMe_NA=b zRPT@vPN=tLbrnw3{t~o@=RpitA-6nIXU!w(lFyfWh=stE3}KD&d;z~5U7ehMf$)*c z$7~s}RTN)k+2U96&O1aL9+KcKH68OYLuq@mblt`HgpnhoG0vj;!iXX}-P z30E+{BBgpExe|4myplaKadBRc1YaHXEiTkM>E<4~8GGD9V+5Uj>fT96NVpK)$nw5L!Wb+vq(g6l z?5zW-ntpl_V1_B;!v3W_^V@}VE>mu+`0H1Eel)i64)~nDiZ~l4RHF$$U5>pmp+>S% zbA*rcQfGKDw?d8Y&ZNqiKnDXj#B4>RkEta^^~3I9Y_Q zt5|{?vJ!@Iz17KabadQ|doDkX_H`*pJ-)9qa4v^CFECW6En z`a;zM+&N%e-vzjgjE(VvDR|odE;k^46R@ob3K>U|yv@3(2{xUpx)&+;9R&7^{uGwm zv+aqpDfTYP2PrI?3T#Zf(=`kwB%6(Hb3s`r(IiKf6~FHd>eZxjxuv-6>wLh?jN@#S zL4M9a?qh}h+1_^E9GnKPHG^NIr5?B1ab!M>S7ENmu5)vDcPEIHBbL1WJ;o6@wy`JZ zl&ze?Y#kUVF7AJrClYeyzfY$(1_HWNAC-7qx%*Cd3qzzgy)*5Ex&tBxqcagH1vy4b z5heE3EeH(dGAs+jp359J53Fu`4(|XgMt7gv%zvfUez5%x1e2e}{Iwj%qmVnIh-6(1 zwjuR%87Cq$2pb6gS${EuC0i0V7!8QMR zdb|_9(TeiEnYc^qpZ6<8Q|kPx2My#1UUJ>i$|Sva#}OJdwj=?mJMW)3wVEqxzVE5*rJ{@>Ar;wE(FHw%-5t zi#G^WQ^IbuziZ*;s%jbh*y>{uAYXBL)b7vJ^?`^(2!GQQ$M92SX}{0|%@Nt6JU$jX zEp|asiQX<9mJIxJC5>pMgz>yEF}xlESxlmpb80C%PQ8L(6FI3n+zl0_!{H*ngLgAn56O~Ci$hflm>#aNMc@eJW=WL4~<9b5eMRm*p!-p-pl;* z3-WJEv-id_*tLcnUBzGAn&xp3SeZg@+m!-h#4zbZZjZAC{ffMg=34oOhn;(;+mIrW zeCvY~4nu-dCf}@5L#xJ$&p+DAV zh&jndzfd<{UqJyOAq%O1-Oe}U9*jI?afWVF}dD82y(BtHn_eo2(IOx(WkOT|T-YjL=Kl{9ztcp6@ zn>)jT&0|9PqFjY*gUobt$d)K#I$F%IDoh#0+@@-9GH}KOUWz;{mU}yaj+^A~UFYlF z_DbrSv2zzA$c*`G57iErRc;1cTucv8x!A-fnX0;&&gs20v$P}zsV20;aWwySW`pTy zwLc}CueYqUvcM<$Jk=Mr{&O{iV` zgu~8jpOxt1OVRlQ*5A||m+ZE#WVUL>M6KS`weN;YPA{(;iz>iWE)K-^KieAQGVX#H zrHzXL@&X5yG4Vr@CD|S)q)04Z)XX}6QC+_Kx`^m`ojoB@uoe6nJzx#*{SZN~_$d8Q zI$KfojYZ&wTKf9fAiF&r|Ni}OGnGv@>d&XVv45vaN9C;!Wqf()-)_1vJ|S|Lbcz|H z_9k~0KLKkqQyCQYIe*L8;131-A|>^>a-4c++@L3QIpzrwThXJiSF*2h%$bXVcK;r& zSW0*<$&8j5kY964c(1E{7r57E!L!Cc&r4IRmXS}tj6k#^`HDB58Z>QXTQG+*`N+ql zS!jOws9n$%U-LD-CTwhX)2H2SJNqvR4)G+yn3&U-_qakM{ZMvRQwL?jJJ0|4w0cUIZl7j|8ynWt3k+VXL~!Z zz5V7c&=W?=E!3xbdlh&I?@X4n1)0*@?lL2?`l-f#5?&7%$>iTZFV%RwIcplt5s;H` zG9rD81qazH&R*rLh*a1d-M4c(o3s)xC@7e?5OgxM@kfR356Y#|I$Q=)NTfAC#JW+W z3)V|Sp3T}?{(LJqrCrqako3a(P9Tx+z<4t>cFfP4SXBfu2 zdvsD)i_p>mM(3tFC8cJL#HY++ywIx^I)aPnv)!3H@ijH^HD$2T6~<6+dY1>Or0l6w z3<~ig5y%n#UNzy<)vch}ai2u}_RpI@jB2YhR9wu%t}%#q7^-Y-_f6^Id-cIOx*Q(6HEcI%yhxhTo-;EtW

{E0 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 E0O3MVi~s-t literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb6@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb6@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..859e0aa4c1f0d548eda3fe4c6c02f7fc4af1831f GIT binary patch literal 16702 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb8@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb8@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fcdf4ed4a4a76808dbfe41e54a45d4433dc1320b GIT binary patch literal 17084 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb9@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/default-skin/sliderb9@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c990cf0fe6784265e2419070a27459fa6f7b2fa0 GIT binary patch literal 17067 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 => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; + + InternalChildren = new[] + { + new Sprite + { + Texture = skin.GetTexture("sliderb-nd"), + Colour = new Color4(5, 5, 5, 255), + }, + animationContent, + new Sprite + { + Texture = skin.GetTexture("sliderb-spec"), + Blending = BlendingMode.Additive, + }, + }; } } From 3b7cee2d45ef027b93d71950ff4ccc24843323b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 13:50:16 +0900 Subject: [PATCH 348/645] Fix LegacySkin not checking for @2x hitcircle when deciding sizing --- osu.Game/Skinning/LegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 3eda76e40f..7c621ee87f 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -59,7 +59,7 @@ namespace osu.Game.Skinning Samples = audioManager.GetSampleStore(storage); Textures = new TextureStore(new TextureLoaderStore(storage)); - using (var testStream = storage.GetStream("hitcircle")) + using (var testStream = storage.GetStream("hitcircle@2x") ?? storage.GetStream("hitcircle")) hasHitCircle |= testStream != null; if (hasHitCircle) From c4251d512e069cfee758bafe8f85dd7113d360e3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 08:00:09 +0300 Subject: [PATCH 349/645] Simplify bar building --- .../HitErrorDisplay/DefaultHitErrorDisplay.cs | 69 ++++++++----------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs index 2d05dc8aba..a9dd7ffcca 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private const int spacing = 3; private readonly SpriteIcon arrow; - private readonly FillFlowContainer bar; + private readonly FillFlowContainer bar; private readonly Container judgementsContainer; private readonly Queue judgementOffsets = new Queue(); private readonly double maxHitWindows; @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay Width = judgement_line_width, RelativeSizeAxes = Axes.Y, }, - bar = new FillFlowContainer + bar = new FillFlowContainer { Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, Origin = reversed ? Anchor.CentreRight : Anchor.CentreLeft, @@ -85,54 +85,39 @@ namespace osu.Game.Screens.Play.HitErrorDisplay [BackgroundDependencyLoader] private void load(OsuColour colours) { - Box topGreenBox; - Box bottomGreenBox; - if (HitWindows.Meh != 0) - bar.Add(new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), - Height = (float)((maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)) - }); - - bar.AddRange(new Drawable[] { - topGreenBox = new Box + bar.AddRange(new[] { - RelativeSizeAxes = Axes.Both, - Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)) - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.BlueLight, - Height = (float)(HitWindows.Great / maxHitWindows) - }, - bottomGreenBox = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Green, - Height = (float)((HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)) - } - }); - - if (HitWindows.Meh != 0) - bar.Add(new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), - Height = (float)((maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)) + createColoredPiece(ColourInfo.GradientVertical(colours.Yellow.Opacity(0), colours.Yellow), + (maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)), + createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), + createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindows), + createColoredPiece(colours.Green, (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), + createColoredPiece(ColourInfo.GradientVertical(colours.Yellow, colours.Yellow.Opacity(0)), + (maxHitWindows - HitWindows.Good) / (maxHitWindows * 2)) }); - - if (HitWindows.Meh == 0) + } + else { - topGreenBox.Colour = ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green); - bottomGreenBox.Colour = ColourInfo.GradientVertical(colours.Green, colours.Green.Opacity(0)); + bar.AddRange(new[] + { + createColoredPiece(ColourInfo.GradientVertical(colours.Green.Opacity(0), colours.Green), + (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), + createColoredPiece(colours.BlueLight, HitWindows.Great / maxHitWindows), + createColoredPiece(ColourInfo.GradientVertical(colours.Green, colours.Green.Opacity(0)), + (HitWindows.Good - HitWindows.Great) / (maxHitWindows * 2)), + }); } } + private Box createColoredPiece(ColourInfo colour, double height) => new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colour, + Height = (float)height + }; + public override void OnNewJudgement(JudgementResult newJudgement) { if (!newJudgement.IsHit) From d337f9b482a9144d85d8d12682b0a0461a8f3bff Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 08:03:17 +0300 Subject: [PATCH 350/645] DefaultHitErrorDisplay -> BarHitErrorDisplay --- osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs | 2 +- .../{DefaultHitErrorDisplay.cs => BarHitErrorDisplay.cs} | 4 ++-- .../Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Screens/Play/HitErrorDisplay/{DefaultHitErrorDisplay.cs => BarHitErrorDisplay.cs} (97%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs index 006773a091..02773e0561 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Add(display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows) + Add(display = new BarHitErrorDisplay(overallDifficulty, hitWindows) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs similarity index 97% rename from osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs rename to osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index a9dd7ffcca..26f9e3a5e0 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/DefaultHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -18,7 +18,7 @@ using System.Linq; namespace osu.Game.Screens.Play.HitErrorDisplay { - public class DefaultHitErrorDisplay : HitErrorDisplay + public class BarHitErrorDisplay : HitErrorDisplay { private const int stored_judgements_amount = 5; private const int bar_width = 3; @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly Queue judgementOffsets = new Queue(); private readonly double maxHitWindows; - public DefaultHitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) + public BarHitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) : base(overallDifficulty, hitWindows) { maxHitWindows = HitWindows.Meh == 0 ? HitWindows.Good : HitWindows.Meh; diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index bbed2b1618..e4a630245d 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private void createNew(bool reversed = false) { - var display = new DefaultHitErrorDisplay(overallDifficulty, hitWindows, reversed) + var display = new BarHitErrorDisplay(overallDifficulty, hitWindows, reversed) { Margin = new MarginPadding(margin), Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, From 9f64e0962534b6a4aa149ad24d2d0d18c1815ee3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 08:45:51 +0300 Subject: [PATCH 351/645] Move HitErrorDisplayOverlay back to the HUD --- .../Visual/Gameplay/TestSceneHitErrorDisplay.cs | 2 +- osu.Game/Screens/Play/HUDOverlay.cs | 8 ++++++++ .../Play/HitErrorDisplay/BarHitErrorDisplay.cs | 4 ++-- .../Screens/Play/HitErrorDisplay/HitErrorDisplay.cs | 3 +-- .../Play/HitErrorDisplay/HitErrorDisplayOverlay.cs | 12 ++++-------- osu.Game/Screens/Play/Player.cs | 4 ---- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs index 02773e0561..a148bdad67 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorDisplay.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Add(display = new BarHitErrorDisplay(overallDifficulty, hitWindows) + Add(display = new BarHitErrorDisplay(hitWindows) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 43b9491750..02432cf64e 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -15,6 +15,7 @@ using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Play.HitErrorDisplay; using osu.Game.Screens.Play.HUD; using osuTK; using osuTK.Input; @@ -33,6 +34,7 @@ namespace osu.Game.Screens.Play public readonly HealthDisplay HealthDisplay; public readonly SongProgress Progress; public readonly ModDisplay ModDisplay; + public readonly HitErrorDisplayOverlay HitErrorDisplayOverlay; public readonly HoldForMenuButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; @@ -84,6 +86,7 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), + HitErrorDisplayOverlay = CreateHitErrorDisplayOverlay(), } }, PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), @@ -256,6 +259,11 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20, Right = 10 }, }; + protected virtual HitErrorDisplayOverlay CreateHitErrorDisplayOverlay() => new HitErrorDisplayOverlay(scoreProcessor) + { + RelativeSizeAxes = Axes.Both, + }; + protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); protected virtual void BindProcessor(ScoreProcessor processor) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index 26f9e3a5e0..6539ce38a8 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -34,8 +34,8 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly Queue judgementOffsets = new Queue(); private readonly double maxHitWindows; - public BarHitErrorDisplay(float overallDifficulty, HitWindows hitWindows, bool reversed = false) - : base(overallDifficulty, hitWindows) + public BarHitErrorDisplay(HitWindows hitWindows, bool reversed = false) + : base(hitWindows) { maxHitWindows = HitWindows.Meh == 0 ? HitWindows.Good : HitWindows.Meh; diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs index 10b5e5b1cb..422e151d8a 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplay.cs @@ -11,10 +11,9 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { protected readonly HitWindows HitWindows; - protected HitErrorDisplay(float overallDifficulty, HitWindows hitWindows) + protected HitErrorDisplay(HitWindows hitWindows) { HitWindows = hitWindows; - HitWindows.SetDifficulty(overallDifficulty); } public abstract void OnNewJudgement(JudgementResult newJudgement); diff --git a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs index e4a630245d..1c61904461 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/HitErrorDisplayOverlay.cs @@ -21,22 +21,18 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private readonly Bindable type = new Bindable(); private readonly HitWindows hitWindows; private readonly ScoreProcessor processor; - private readonly float overallDifficulty; - public HitErrorDisplayOverlay(ScoreProcessor processor, WorkingBeatmap workingBeatmap) + public HitErrorDisplayOverlay(ScoreProcessor processor) { this.processor = processor; - - overallDifficulty = workingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty; hitWindows = processor.CreateHitWindows(); - - RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuConfigManager config, Bindable workingBeatmap) { config.BindWith(OsuSetting.ScoreMeter, type); + hitWindows.SetDifficulty(workingBeatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty); } protected override void LoadComplete() @@ -80,7 +76,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay private void createNew(bool reversed = false) { - var display = new BarHitErrorDisplay(overallDifficulty, hitWindows, reversed) + var display = new BarHitErrorDisplay(hitWindows, reversed) { Margin = new MarginPadding(margin), Anchor = reversed ? Anchor.CentreRight : Anchor.CentreLeft, diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9ef8cc4509..e7398be176 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,7 +24,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; -using osu.Game.Screens.Play.HitErrorDisplay; using osu.Game.Screens.Ranking; using osu.Game.Skinning; using osu.Game.Users; @@ -74,8 +73,6 @@ namespace osu.Game.Screens.Play protected HUDOverlay HUDOverlay { get; private set; } - protected HitErrorDisplayOverlay HitErrorDisplayOverlay { get; private set; } - public bool LoadedBeatmapSuccessfully => DrawableRuleset?.Objects.Any() == true; protected GameplayClockContainer GameplayClockContainer { get; private set; } @@ -160,7 +157,6 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, - HitErrorDisplayOverlay = new HitErrorDisplayOverlay(ScoreProcessor, working), new SkipOverlay(DrawableRuleset.GameplayStartTime) { RequestSeek = GameplayClockContainer.Seek From 596ee150c6e2db6fc3963ca237afba868432543a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 08:51:41 +0300 Subject: [PATCH 352/645] Add xmldoc for not obvious const --- .../Play/HitErrorDisplay/BarHitErrorDisplay.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index 6539ce38a8..f68e17c908 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -20,12 +20,15 @@ namespace osu.Game.Screens.Play.HitErrorDisplay { public class BarHitErrorDisplay : HitErrorDisplay { + ///

+ /// The amount of which will be stored to calculate arrow position. + /// private const int stored_judgements_amount = 5; - private const int bar_width = 3; + private const int judgement_fade_duration = 10000; + private const int arrow_move_duration = 500; private const int judgement_line_width = 8; private const int bar_height = 200; - private const int arrow_move_duration = 500; - private const int judgement_life_time = 10000; + private const int bar_width = 3; private const int spacing = 3; private readonly SpriteIcon arrow; @@ -127,7 +130,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay judgementsContainer.Add(judgementLine); - judgementLine.FadeOut(judgement_life_time, Easing.OutQuint).Expire(); + judgementLine.FadeOut(judgement_fade_duration, Easing.OutQuint).Expire(); arrow.MoveToY(calculateArrowPosition(newJudgement), arrow_move_duration, Easing.OutQuint); } From 84530b7839dce1db5481ce52ca86a9803529444f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 15:02:07 +0900 Subject: [PATCH 353/645] Colour the correct layer --- osu.Game/Skinning/LegacySkin.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index d6446625a5..26ee434bb4 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -43,6 +43,7 @@ namespace osu.Game.Skinning public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : this(skin, new LegacySkinResourceStore(skin, storage), audioManager, "skin.ini") { + if (!Configuration.CustomColours.ContainsKey("SliderBall")) Configuration.CustomColours["SliderBall"] = new Color4(2, 170, 255, 255); } private readonly bool hasHitCircle; @@ -347,7 +348,7 @@ namespace osu.Game.Skinning [BackgroundDependencyLoader] private void load(ISkinSource skin, DrawableHitObject drawableObject) { - Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; + animationContent.Colour = skin.GetValue(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White; InternalChildren = new[] { From f72edb8bf8840139adf03a8a125a09373167a20f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 09:03:31 +0300 Subject: [PATCH 354/645] Add missing blank line --- osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs index f68e17c908..d8ae3dd9b0 100644 --- a/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HitErrorDisplay/BarHitErrorDisplay.cs @@ -24,6 +24,7 @@ namespace osu.Game.Screens.Play.HitErrorDisplay /// The amount of which will be stored to calculate arrow position. ///
private const int stored_judgements_amount = 5; + private const int judgement_fade_duration = 10000; private const int arrow_move_duration = 500; private const int judgement_line_width = 8; From 9fbc8440fc069ce732f6a7961366269062fdcd53 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 17:39:16 +0900 Subject: [PATCH 355/645] Add actual testing of animations --- .../Resources/special-skin/hit0-0@2x.png | Bin 4020 -> 3009 bytes .../Resources/special-skin/hit0-1@2x.png | Bin 0 -> 8378 bytes .../Resources/special-skin/hit100-0@2x.png | Bin 5653 -> 3461 bytes .../Resources/special-skin/hit100-1@2x.png | Bin 0 -> 9934 bytes .../Resources/special-skin/hit300-0@2x.png | Bin 5004 -> 3928 bytes .../Resources/special-skin/hit300-1@2x.png | Bin 0 -> 13096 bytes .../Resources/special-skin/hit50-0@2x.png | Bin 3861 -> 2966 bytes .../Resources/special-skin/hit50-1@2x.png | Bin 0 -> 9138 bytes .../SkinnableTestScene.cs | 45 +++++++++++------- 9 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-1@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-1@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-1@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-1@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-0@2x.png index 9d2ed3a7fa3d5bc0aa43098e9247fa3f6a7c6f80..37e7e9143f63e30bcfd3de38c46dac951451f43d 100644 GIT binary patch literal 3009 zcmb_eX;c$g7OpI^4Ja}_dKeWlp;b6-_5~7_u*o9BP9vy|#H4^INhKkW00Pl=T5a*r z9vwhI!*nA|;|Qp@MoHm5fMA2qd|^`~yVy7#;He&2od z>R?1zppDfZtpEV92@dj)0ss_Zq5umsyFeLk2be4ndE&>^ z8az(G_rz~zgpxzWeqf3qC`$@PXNAS^vUc%Ud_2bs=b>OD076j4#VLfTqBOR`6aNmE zjo7AT5+3)?MYhWm|GucW&1*a7LmfF(OIkwI4YUqMk2eBC^Q0v z$)=OpR4VSng-5bU`AO_3|9}sH)Gj; zQjjZyq%jbbx-bP1DUb|GOM%2VKR=V|ESz&FmnRUJ7F|q2z3feV(1Aw_M*xx5c(fLbHL1b6ZDwsR8&Sqv4Zmrwe zV!JYIHP#umNonV68E6@SJ|-sm3?42jJ!;=Fms~E_d(cjiblcE}&gDM+s!7^I4_&fB z>o|(G1-wlk11#{Vj8BKOSkZrjR4PwY9LzjZbzz-N-tDe3!?~*Z0*_O#R_G?H2HWc= z?#n$+m)OHK=09h_9NiW3bJzoC+kHxtoYcnns|H);la{P`^+okk)B%V9SipNR52s2R ze+Qszd*hV=4hXUK&V2!!;n1}Y?cw8UYm{?fJEn8W5#=l}dnj>=0Bn^vQ?bgmGkwID z8tdXLOl@`5{+)Rknvzn4THi?mP|hiqiE{-2_PlU*I+oyy?)s+hj-O37pv~^=A+np% z4uMq@w8xPN-=`@5_MBuV^A>{W+Xdsjc0e{nNq}ec6Z|F~J!-uUYuhDnrPceST z*E+y;P0C9lN=k+C8Romnhc#;o!*j}$pJXivGQ)tQR?BLyyy1to!h!RZJm4V5Bbpm z+ALAu@LA1E8~A#~=v-MCXYj%3;8`7{HX76A>Q&@pXYB5}0FzpfH<}9DB?h<759%TF z$QztPqe;{Epf5GH39DIa-A#FuvLI|m_te2TEAMvmN#0w|xhCVt0G9GCwWVXrb3O2= z?s|vueAnvcl2ck^_1}&kt*#uXue;LfI1w*P4yq0r!E`XjwB(qA8zbYhA_ zfX>d{b?eEG+6#!D7wQM(p4ItU>#{oFjiPn~A0xj1L>o*QdO&S^HZ{9%*K=ot&Z|RL zmtWau1E1^DPYN%X4>m(*j7!h&UtSm#c~@X*yL&~gSE=QOL^E-f;_OpZj{I`oiMPW0 zvr~}>J3pz0CP;b9S1B`ZP10VIpDwE#oN_Q!o5vkPXt!^bl~lbY&Ht!03|!zqiAR^! zcKP0O0UFw`ebq8$rAcabWK-`@2d*{!LH<1=$iOU47kf)*A2)1`yIT6vka43g%!D%z zdKX<3SngRZ6}^dADI~%6AVO6*FTDK_8|AEFdbKsQ&FwpB>SZDs2tVE9Guz8nC7wOG zwCc&iVgyGQMCuBVXQ@?(yq+epoEJby?{05P>4nz3g&?2?3juZ-SpbvbvN+qq9- zd%{XP0vsxV4Lq~)Sa^>LJ=5KksGnL6CjatJV zr#)3Kd)bh>(hfn07^Nm|9p0*(Y}Fs%{3KX6xV49J)8tOMUOF=tm=9kbo>F%UoJMx( ziUaH`0SoWj7Ul6R+tr-;_z|5u=dmoiMDtXow^%uqPi={RD=Mit$QqZqn6J}!sb4)( z6`W)n6t>OxTC;|Jq203|QCO`4V7rf=NsFh#r!zhs(&AbAKSL_DhRsS8aNZ)>X>IhT R0@F`*@WwFzYTv}Y{{lUSa}NLj literal 4020 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 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit0-1@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b75c71927c6671c72bc8ad92d25235067d5a2743 GIT binary patch literal 8378 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 FzW}dVh$;X8 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-0@2x.png index 777af3bd415263824913549c5c4c708c4d6e450a..79326674086568e677792fe57141e52e9944c33b 100644 GIT binary patch literal 3461 zcmb_fc|6qVAOFterbxXgM+RHAtugnBMg}>SY&X*b(Jj?!Ji z5`~tfQ;yP5iAI+~W|T6f5j)!2-@abEzy0I4`~34f&*%I3yg%>fb9}$gHz&Y<&0GTu z0{{T#dV9GC0sus_gaCRvnkk%jI$AR=7I=gTf;iCv5se1|s~Maq5a!LI#ejhzjggda z3v>p6IbvpTs36quTQZ%)a-_}bIEq^%-)IM8GF>|*x`m#kUOiV=3O zPbz{q7rWm`h57}+s2m;$!#U#NbQBf`Baj?Xcnp?AS_wlVQA7lih(KZBC_EX9B%{%= z&%;jRjmL;42fBNH_NCdm*u@G2TrvV75{Vo|7)K5-27w}xNC+evfkwkM8gPCRTR;=T z*?jvi2<{-C&SP=~Ob#11i%5&&2n8;78m7M;fyMRn`yH6g{~Rby$Pi*07lCp_B3P{1 zbA8h03j)Fa()delesB^OL3g7a7QShNSx zo#2LZbHkEQC=Zew!4vC&C!sMIq=y^U4gbZ~o6Q%{*mUrVZ>GlgXIt#w+LEa}kS5^p zf;pV{FI5l_%Moz+u^cXpN}bI*3HG%gjm~7x3YX6&>bG;dgFI#;$nfNGSg=o#CNuwn z1qO-5py*f>98Dn5;hI9C!HEnU79Nd>q7yM_9Fl}(*nPHV{J#-IXhv&6p)s{sK0Qg8Rw!Q$T6{oB^r6Bg;*S-M~6i0LKM)TOSv z+f4VGmS}}T9U-UYgu8_|U*5sjX9(>(iADqOed@hNl+n(Yzv50k=&J3yus-F@hY!8L z%OPV9L=SKU04QJrWB`B`0Q>Z6_{XAu3Fc3f{s+N~tsgh~*qWQ0Kb*eM7*U|!E}1JS z5>D25sC%zbIMbJ7d-8Ru;uNr1t#>K}>wOq4GXTZ!gA-~?J5-VLNQk%xtI3j?$2-J zJdOpgLg$#`wB7FS*3(62!-nOkQNv%x+1KyR)C*e>xJuHR)Lu{`e_ex9hxDl;@)PhR{nCPiRw86iuyS?43v7Yvg5>@;&yRz>3yd@TSofLF zy0Z!p>5Yoc5_Ua4#1vTGGQ$E3B|XPCkKTMSoo6d#32&4(9-UdN<;pr&?NisSN@x~Z zey~~B6*!Q0T<#3@3T?XE-4b)|fk8vJ>YF2*DTz5{HFeKoJ%C^=lxTit4?0{jJv~@6 z_(BiYyyz(FHZt8#RkqDsm~!#0Ho9nSNN3e~TEcq`6+ z>JRK2|5{Beb$+qz(B#E5ixs07MM?eJYqM<=*Q2$)CYu(pS()C}-JK`^+BrxCq!vKJ!x#QQlh`K(c@uxsKHHL7 zcb;rWd3Nk}g!m~2dRl@_diZVZVGb)O1NOpm*O^tvQhKUvCGSlx_0&1#)UGkiXbUVa zJJ1j`a_Hct=*4m8E9I!IWny%`)|+x>T#X7y*zh2TJe}q|J|i{aOIFLcP9UMkW{z|{y+7@g zBZXYOzu@HI>&;b9p|E?{NJ^@){kGytdZ$bULp+-?yq7h$@9NQF*uC0yTZH;mSF`W%UqTPtk>c1@Vx{;{ue>f~$@{=LEbw8)&idtelbUdWHaPqXO z0@3tdSEBIUU-RU2_V&a@+B-;nU*W?iBX{1r?`u`oCfglVlwW;g3&J5()Oz_ilBZIR zS$XQ^O}-mGw;XrfZVm8bF0{_syrfz-@~Cn_46diYXR0qx84uWJEbxTvf0$Z1aJT)Z z+Z)GyMz#>7i-F3!E?8k%`xe1NZGz4weNjmPEYHU@v~bW6lm7K@w>-Yqbe1Wo zBEHB^VhPu>3>8&I8JAi|E)1Ab?d$h$@+f|r0?&6o=%nrySd~e)DEDm=E3}%3wkE5t zWpvG@h3H3WSf&MO4k<$JcvnV?vdz>xn@hss;HF z6U)a6n$o}#S8VuK7QbfC}}ocX1LoO*M{$v6CIPT_W$ zgW$Z%!8&Ghmm+}LUwIvAAy(iAxLrvHop$>S@jbKwdKfXWw`NN-4`|sUO j{)ql>-g}6H6o?KWI_G)Bc-VCS&C9aPtiuX literal 5653 zcmd5=S5p%T6Ad76DS}E>>P3;RUMZmmQL6MRkO0za5Ftit055_lAWBCFy%zxqH58R9 z9ciHiDWQZUAcUHb&-*XFGqZE{VIR)JncXw{#>_v{i06_Prr33uM z^oPLD%RT-O%QJnuAOL{#>3>C64l45o0C@Th9zC#ni6Jbp%|WJe`}b+1IlwoM^j9rr zZNQb*vrG@JjPR6HmKg3CO-q&xm3#8Pk{Zgaa8QKJN+nxlw7tEhZ73F4rcmDY?(e?` za*V{UgvG8!cy3^AM*1xExgL=p;%0F}Ev>-nan>4djT*t8$nH^!1~l z8S|q){eGng4(sn=CsNgpVz*+zAx-G4D~V@$)9YMML?O&L5t%u~Nv{RJ=Ah8$*Al7v zs19wF2{f)WEU7d@hQY0cBl^OruIZ5-zV-8ojbi8V)lqrn4#D)o{0>Nt#)srJ5T3m8 z4ip*fI4gM%tR&trJ9w=;C^;MZg3 zv3-3nh>rDSao@r+FAN|*rX^c!on)=k>OiAdXe7mE|5bJe7#1GxxA0z33*hzMyxzYs zM%e)*ycku7ZTqpy!iao0AS?>_Io~pe`e~w3D$<4NUh+yta+?^=jgDMOyRlNDgqD4;)u}|L^hfMGb!I0)}q7-2vv;z9CEN7dl zQWxv4Xq5Gpmnpk3vVnXnT=hEA?zUyJl!HT6t?7RQj1&Fr#bdEq!t>{6?FS3Pou!E7 z%vIB~E!cF{KSj46h-hhABN|!SvPCjoro3wd@}G#;1>VB05AbdUf%UMUlDY8j?2Sc( zcSHf}W@KA~i!tt;QKG^*ij`0(+vS9Wo9{C7$6^dO5%Q=Wx9e8`_Ydpuh8Lht4kAX5 zY{=Aa>PJuQ-Dm}(&%&G=tuwNPbkphRM88#a)mHa2DamXp{#qVTeXe<>-)?2%F#(?p zMljAZU5a9t1*#baR52^HgQpKS50*13Qbwj1Vxvb;{H{tdehlb3Fzq@S zQ=-%;L!PmVY$lw$34BR-efiQ2cU11O5~rV%IpKhFr^)o=%^aW-O3iA3Q*w%Zu5~&3 z`KNhZALa-M7X4tC8F+bejFF1Oa|QNqDpF~0IdzYG8a-S739RpH&OM^ZU}!z)@X)jE zCgmgJ&pj`>?MTmZM62p2rU)a~)}U4iW?+(aG@8O!gmXDS=H)9LAl6z=6Y z{Yq|FCeDzEJNI)+*yrZivxYB|W;BHgXW^PGXUJXJ(C;Yx;kMa5vrr=3+x&L!I&?v) zW&GGCPl)R@sG;j9(D@DJz@SIki{_b)r8yi3k6YHfhIwtTsQY*FnhhbRkLu1XLyBA% zo-l7rYqfi?rw#~@7UZ*=^_{(mRGn~4Sj{xma%XXZp zVK>ii_hmw^q-E7uOB~!LEF8XLC=^HyjxG_%0~;jvU9QtKH?Gjz5qtze3~jvwVHB^9 zdIQg=iwDv-ayfuR*DR0(XkhCmcIs5wadWj)SO~CqOJp$ULVWv!qLDwQ%mK~Sx5R4w z5bm<>sXjENb8|Q{-PgaH*%WBwQh53z&=J@2uuPQVku;Ki8I}^-^13QgMZyPrmpC{^ z@5fX5n}=cm_4cu?Ez&(Jf=N<(jmns|VbIVfK{ndy**08-FVd4us4=VUy5Lw7|CD>GPxJm9UJuhp}S z4X`@7_CBcS-xKVN(MF`9t%Dh_ZT+ z3>Q!`J(Yl(JOXN9*nykTwI&BvL0%+ZROd4ACoOT7w6renTe2N9fu%VzpDx%LCu(B& zC|s6MA{4Sr3_V^LcCDUXXMgZ>5hE z^iy{UPU0Dh`)WU5Cc%EY=$B0EnMnRvoA{FAaAeKSflfhIaavMS8b|Y`xqm_<>c3V6 z;bHXBaVXe{fl_GNe1$7F;7&mAS5oP9%QL89pv$PR+Y6JDS5Lt_Hi&Zp>Iu5L^f8S7 zg&9+10p`oCk1ZW;7dwzq*949@lce2%G{=4DspAzlWvTFhoax zd#jT%R-VY*jOIoD_l9g;^70K`_>ORiBRri_VjFXmGK6!#(1so0bBx?ot)tJ$Eiytp zki)J)$*?n@O`&MxW-Gb1c553dL}H#LdIYyM)a6+tvsf7ck~*q-kmk#z6Dy4r2(;bg zHg3>SEe)&eI|Ma-;$z&J8lD{w^#g2Wxa6c)(cRJ@6(lv3F`qC0%5HtyovUd%#tEJ_ zsl;8~oP$%+sx-b!zXuKY{8h&~S`*qX_LIKS!#M7ulL4kBiuP3Jo_A`{e+)wGI_{*< z{#jg}A+?HQ-QBL_8!U#GvX9>hq|1N5ny&A6%6Z@yCBhtuaGhc7 z3+V=#Daw4dD~ZM3laaT=G`$GUGyS0|cPGC$dJJaF2z*}_zNO9QKxBc!RWh86srowFO=6mSuIHE>Shvbx-+IHP-RJ$< zq=>M<^||$%kW!N0bjN(VHCHKWr46D|BUN6x<#NG|@j;oBobi~=SpqtzWHC-zePye&16Ozp zu)ctMA*9B)5j<`Jq-FZrhcVs%C1;1C+S+*O_P=PS9|5I$XA{zI1H!9Wjjc4X!CQ@` zxbRSj+=`w%{SK5Td?qOxi=7^7vdjjM>mi~5b(^?|OraBMtzB_1#Ynl;>gjI*UHt|o+09SKL{U?hy05^QT&$A3q%hdIe+}}@x{Nq{v#T4 zmSPUo&0Uv#q`y5xPGLcB&568To6a($4UYf=6m-fsy3|Nkt{r?Nv2hec;NJ8wbN*hc2H8r_9qt;IOw&=PB%hTM_{)v2gEW6 zI_wo>wsG?Vd2*JSG8RhZAm?bQNv_kZk|Bd2pxBqobfTPUr^07&h8&@vtjsN@D+v|v z)D=bmpX_0o5%WXGEAUPvu@hd-^f@q>9zPRp?8p|OYkOj|`seNo-m021V&Q&=UgC;a zq5`T4RA&>K=N>z`3y&f=LT#P3OO&S9aA5EdT1xxGRN&nbG^3VJ@bLG zRUGbV0^l*X8I`=JSX4XOMOKQ}s&~I>qVZ;4ZVTNcOJnnrpx^pM4BcWP_kJupLh{4_ zM#sL_hGiNJ&b5Ddk_&`I0B2_gyxO_<^x95|4lBxIe{ol)gpjnjGjH8&2!0#a$NT9j zJZ{)l_$+){L*ZBd+o>Y%M#4!GuXf`-!XIltXi)x+U{qSLf}z*i&mVB`+@W5CL5KD_ zI%xud`zf>IHwP^z!)IQZ*CX>6hg+y@)}spGo_+S366MyIP8RZ?hbm~Lc~dnEB3{3VucxPw`iO8>VsH-gpg`J<#BzXR@(cjq$tkG<}^ zPN|HAY5@j%9;TqHx&CBldD~oyHC%H5YW^2`NzjYw)B9kk`%ukG*J!&xfh)qs9e?RH z?yg{kht{1Um4!tG+{OsOOh=rsDR$lFB{t01(Brb$&JWP5fW^w%6sPg~>*~4xa{XQwftzYdn`q|LNSO!HzXdVgCxzJA z0QGu%-)KIZO2G=)uRIr@7#dLsf9hOCQ2UC_&Bn9O?4LHJA$vSq#YU&Cxnq3kbE>bk zi!a^3kyopQg6EACLwNv#*7cE3rI?@tI;`~l8{|(>IX9uD^CBah*@J7&ap{yB<*tDN z7XEc_DpwwoBjC)V^#aM}(=pkv!aw2&-5z|mve3Bv#Ra~}U(xnIOQvO)6crn6!EY7z z=9!aF7~g`mwbh1SwiC>s>6>4G*Ta%BO6MpRx$$agJ@P^&8#8Tqk{bT#hfJ>JFtL75 z@W7!86X|sSse6;{1(~f^@xjp8@=aUN6&^izo8iQOt&NP1J7th8suCkX!$*q3I+XF` zrO^O$gmg~DX=BPBw@lYjJ{$dJQc_jjbW88!_VBW`&`VKcdcQp7+|$e@T%2-0tEgV@ zpS3Up8*9h9^SO_MwuZa-<2>VG%QFAkF3Z`$h==}jtE zUj7gG8L_SEK(a8zpEUDN4*%S+93#-W|6~`vI&?b>##T9e7^EtgQFwQ|>{u82J!sn4 z94PGUlF$J(KPBQ68ae9b!Y4vhlvsuyR=-hLy4gG=>1prI=GJEaEdmOS(3w5|NZvDa zH1^2!uYA-#dJ8Ty2+2a#thB3=HHu1gwwXp!3)v472RwHb`e~e@RGV0seZ@8^t>>(X zZ+7={k?d!t9@gzS$abbR{uHBvvSvEzQE(`oTTC2ne{>#Nb;M7apS{l1%PndO zdZLJ4%R&fLF}H1z3r{Tv!d5_5w|5MMw}T~S(CsK#lTi4N!&c_1(&u5k-d0zX6)XK} zUIH5k6U9d>m}P$hT?m$<&0m282UYEq?>S{npIX?X;=`FYv!!UoG6p~J2BC|VAx`>} zjcKuE!cG%66B5?A1v5NSkB^e5E~06RJx@M-;>t)LT?hMlD4O`sx-w{8OH9_UbfacF z!@)H!P7rqww@-b@%mC~RL0vLPq~Tsgs;Yqg2&0OR)i?^zd`(BX>ISY2YAA07Q)gSNmS!gEOx<3su!Tw_uOM9)JoW(i{ z&aGRj!I(@QM(+-IdoYWSeO%Y>-vQ#zt0i z{MgW55u5bAF3YA9-yzP~pKBeGLbg1VkdRxil7osMh=TBrjrD=C3Nx=5z&PRdvLN3A zrczUAMRi@48k7DvH0dj7XMM3ycNd9IX*IkqvTy~WgQz?t1av;EzG2#4^||oeI>ahP zre#sbm2!hEE~{?CY6`hlD%w7uNN?4HoQik51y5ciEEE+Ec~-wTkX^3%8rdd5KFiV+ z1>)9|bdTtQ@mcUCXHmviSBJJ1dM{q&wI`E^jkVQfU60@7@|}CvE#i5o>JH4OfjaAq z#@U?(hS*LFX&*Pszc`?YRYQN5yUTm7O?#KrTO0}@$Qb>Iis7Wk-bd7e@1A=0KWh;_ zJT)8(x}$-K#EC)TWv(wc#RZ4!oWF>7bR99}ZCG8(*uWgao3NxEb@hrMcv)m*`A;EM z;A)UvR#sy0Jr7S9yhxluOA6ZkhT~$VGKhTL8P(F|So3+HD6B;{<0IV<%KKj%RXK9I zsBH^^vk0RPfl?`Q-pa~n0{_9P@cGEv_(oqA87}{KRrlT8-RyuRZ`yy~)&Coq1<;tG Wr=9MwmK5XvL>cIqJgU`pj`<%3F8Egf diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit100-1@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0b0ae85972b22118b1d3116dfc4f2e0915076d73 GIT binary patch literal 9934 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�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 S;=}F{0ZMY}vT$jO@c#lO1J)@3 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit300-0@2x.png index 7ee45a7057ca5f1e11d9bea30375c92e139cf01e..441c3ec21f8a88762c00ea80eda09a7a32faa334 100644 GIT binary patch literal 3928 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 AIRF3v literal 5004 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 QCoF)HoVsi+&@%l00vK~Sa{vGU literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-0@2x.png index 7be5374a4679af322dd3d4c4b331afc8951a1bda..6f92db28d3c20066a8a74ec8c6d8d143945a450a 100644 GIT binary patch literal 2966 zcmdT`X;@Qd7XAX1%^=hk3o7Iqw73wm6A}y{n=FC|h@fB+k{gJS+?WItlqHIVQdFD~ z!O;jhwWxJm!y{0OpaaE%3swbW)u1A>DX1*6%tgh{52w#O^YqW$Ki~PzJ@0$Ycb5Cz ztl*$kW~TE@0RU!xzFr{!U{DbQj1AExN_J9+F4hX~2t_C&R492e7_1Z^F)-vO=EcGx zFi()Q6h#BD!c8UR@#A3y6a&YKBy9Y^>4Bs`sV5vK^4%tbL$?Km@wdhEnF73X4mBwT`Kok<$nMiUblBoo;6N^S- zQ7F)d2akG_352W=FP{&-&>b5er%*^)M50oubW~Cu5m_ve%w#f&Bnpv2A)pond6GoI zQxPO`yBP*ASk9M;qzVxtfuME)UBXv&Bxo|H&-BoW2p z>2tlamMcQw-^2K%wLC0I3KK(MIg%*jqxBHl&4AI|{jsBILo^!J8kqNz&igSmgOmfc?v`p zh9C(uT@W0HC=huZB85CXr>o9{mIU(nBFVIJ>2#sqpW6$TiMGN59~mNs-esC4`a~2| z5{*jc)5ru0gTW`Djl?533+Ob0kQ&2xrc&r6CQX30sCBx zb0HVYgLAx0LQIMbLOqu3X#IM*`7e28E!+FrQaZ3%><0ay-n7fhZHIe5CI{bo1yDv#cEY!S> zU#GU$9`ghl$YNkzxl2EIb=OyVYH;u~W1t6tin(cWuD%84;4>_@d*4FPxi-=L@T48! zAHsyS8h;54xPk`MI>K=LuV(HB+~alXyf?GlflsjkX<`*Hd>l5|Id?HbuP#IPu>NkQ za`si_CgGDpEzWTG%CW_j9d#rZBN4!?ioRW~cWBI_g}rfRMpiM`HgXSmr7u-C?X zvTJtElVw4tzOre(l$jArt1De(0Rq&UF}_WpSJ2$?^5K-kzin{XxMoZ~i=(8ziByBA zth+DyN5BnA3)rpHov<~JZ<4DLm_VG;W`sF!9!v*iV&HmfEG=SCcyxaJFj_aHU}1Y{ zXsi}v)i_b6skSvzaU%94Swp~WJJhHyc`~`hS$divMZOq_6H97 zwFNeF3CTIR+O$&JQ}ZJ(zYrdNbaU0Y;U(Aj6WMi{x*Vl8a&XeSMXT;xSA2K}{V-`Ua8IPy~-&Yr|xQARRCEV6HEVa4)o?WA?0F!X8&^O&0n9XjU?F7>Aak5AIc7S?aartQ_@Skvv zciW6PT5j!bzs4skhvS>o@Z&eJ-8^${)3xGqE2|TRMc1QUW6soWJi;+O*AO~psrasQ za6#5B@?>Q-Lznz>>8@eZ@#p=EfTsq7g~z7GdQ0!c5n>EnIhhc4+^~H^ zYk)jb4;$2`RpQS1XbbPRJTSjImU+56IocjW(znt$r<@z=spOkCCNb&;PF=*cq`J@y zpqfZ`&U_A&eR1H~Uo!Ma)j%`WJi1q_j@sH*((f^?c*QoG+IRIrOHzUwV56VA_rHE} zva|R5+ghZf1BZ!AfPP5e+E7dTd3|j){o9>44T#50DkF|-ZfYaaYlg>rD0&N%)52BN zn+&*$I(2A}dCH#8pT*cuS{PMiPMB7nT(Dts#1U`N(3y5g)pl)Gb}MtJ>$V-n-b!t? z<9u$JOWN4LozzEuo{5}U5cbWHjv@29@nqMWp^TedsXtj(+m9GLDg%e-<0kvoW`tV3 z`rgK#U(Qprf4^)j!2kE{^WWT>N3W!PW(AgCFFNzMzVQJ1qYV7KgS^gqaCiO-X=E-p literal 3861 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 F_J2M}_?iF! diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-1@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/hit50-1@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b28503e9f2eb683cac80a4b5853c6fa884d75964 GIT binary patch literal 9138 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, "Resources/metrics_skin"), audio, true); + defaultSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore(dllStore, "Resources/default_skin"), audio, false); + specialSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore(dllStore, "Resources/special_skin"), audio, true); } public void SetContents(Func creationFunction) @@ -43,23 +43,32 @@ namespace osu.Game.Rulesets.Osu.Tests Cell(3).Child = new LocalSkinOverrideContainer(specialSkin) { RelativeSizeAxes = Axes.Both }.WithChild(creationFunction()); } - private static Skin getSkinFromResources(SkinManager skins, string name) + private class TestLegacySkin : LegacySkin { - using (var storage = new DllResourceStore("osu.Game.Rulesets.Osu.Tests.dll")) + private readonly bool extrapolateAnimations; + + public TestLegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager, bool extrapolateAnimations) + : base(skin, storage, audioManager, "skin.ini") { - var tempName = Path.GetTempFileName(); + this.extrapolateAnimations = extrapolateAnimations; + } - File.Delete(tempName); - Directory.CreateDirectory(tempName); + public override Texture GetTexture(string componentName) + { + // extrapolate frames to test longer animations + if (extrapolateAnimations) + { + var match = Regex.Match(componentName, "-([0-9]*)"); - var files = storage.GetAvailableResources().Where(f => f.StartsWith($"Resources/{name}")); + if (match.Length > 0) + { + var number = int.Parse(match.Groups[1].Value); + if (number < 60) + return base.GetTexture(componentName.Replace($"-{number}", $"-{number % 2}")); + } + } - foreach (var file in files) - using (var stream = storage.GetStream(file)) - using (var newFile = File.Create(Path.Combine(tempName, Path.GetFileName(file)))) - stream.CopyTo(newFile); - - return skins.GetSkin(skins.Import(tempName).Result); + return base.GetTexture(componentName); } } } From 6dd638b32793acb6dd0d2db08f92ec00cae3db39 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 17:39:24 +0900 Subject: [PATCH 356/645] Further improve legibility of texture lookup --- osu.Game/Skinning/LegacySkin.cs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 94421b1251..6e983fe771 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -151,22 +151,33 @@ namespace osu.Game.Skinning Texture getFrameTexture(int frame) => GetTexture($"{componentName}{animationSeparator}{frame}"); - if (animatable && (texture = getFrameTexture(0)) != null) + TextureAnimation animation = null; + + if (animatable) { - var animation = new TextureAnimation { DefaultFrameLength = default_frame_time }; - - for (int i = 1; texture != null; i++) + for (int i = 0;; i++) { + if ((texture = getFrameTexture(i)) == null) + break; + + if (animation == null) + animation = new TextureAnimation + { + DefaultFrameLength = default_frame_time, + Repeat = looping + }; + animation.AddFrame(texture); - texture = getFrameTexture(i); } - - animation.Repeat = looping; - - return animation; } - return (texture = GetTexture(componentName)) == null ? null : new Sprite { Texture = texture }; + if (animation != null) + return animation; + + if ((texture = GetTexture(componentName)) != null) + return new Sprite { Texture = texture }; + + return null; } public class LegacySliderBall : Sprite From 9f0a0b2fcb0055ca5b4cc47334aef18fa0260402 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 17:42:33 +0900 Subject: [PATCH 357/645] Fix file extension case #1 --- .../Resources/metrics-skin/hit0@2x.PNG | Bin 9492 -> 0 bytes .../Resources/metrics-skin/hit100@2x.PNG | Bin 8371 -> 0 bytes .../Resources/metrics-skin/hit300@2x.PNG | Bin 9589 -> 0 bytes .../Resources/metrics-skin/hit50@2x.PNG | Bin 9299 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.PNG delete mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit100@2x.PNG delete mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit300@2x.PNG delete mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.PNG diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.PNG b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.PNG deleted file mode 100644 index a91072eb5b84a8204add39df625c54b703e0d873..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9492 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 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.PNG b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.PNG deleted file mode 100644 index f64feded0cc2fc38672c081da38fe214d2546df3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9299 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 Date: Tue, 20 Aug 2019 17:42:57 +0900 Subject: [PATCH 358/645] Fix file extension case #2 --- .../Resources/metrics-skin/hit0@2x.png | Bin 0 -> 9492 bytes .../Resources/metrics-skin/hit100@2x.png | Bin 0 -> 8371 bytes .../Resources/metrics-skin/hit300@2x.png | Bin 0 -> 9589 bytes .../Resources/metrics-skin/hit50@2x.png | Bin 0 -> 9299 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit100@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit300@2x.png create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit0@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a91072eb5b84a8204add39df625c54b703e0d873 GIT binary patch literal 9492 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 literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/metrics-skin/hit50@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f64feded0cc2fc38672c081da38fe214d2546df3 GIT binary patch literal 9299 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 Date: Tue, 20 Aug 2019 17:47:24 +0900 Subject: [PATCH 359/645] Don't show judgement type "none" --- .../TestSceneDrawableJudgement.cs | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs index 6f6520dafa..82a8d0e5e6 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; @@ -21,19 +22,13 @@ namespace osu.Game.Rulesets.Osu.Tests public TestSceneDrawableJudgement() { - foreach (HitResult result in Enum.GetValues(typeof(HitResult))) - { - JudgementResult judgement = new JudgementResult(null) - { - Type = result, - }; - - AddStep("Show " + result.GetDescription(), () => SetContents(() => new DrawableOsuJudgement(judgement, null) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - })); - } + foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1)) + AddStep("Show " + result.GetDescription(), () => SetContents(() => + new DrawableOsuJudgement(new JudgementResult(null) { Type = result }, null) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + })); } } } From 7d668c81fcbbeb1cd2ccd7dba538864c764d81a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Aug 2019 18:13:00 +0900 Subject: [PATCH 360/645] Avoid test failures This is a bit of a workaround (I'm pretty sure these tests are not running correctly on appveyor) but I think it will do for now. Cannot repro failures locally at all. --- osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs index 8b37ef5876..02716dc1d5 100644 --- a/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs +++ b/osu.Game.Rulesets.Osu.Tests/SkinnableTestScene.cs @@ -60,12 +60,8 @@ namespace osu.Game.Rulesets.Osu.Tests { var match = Regex.Match(componentName, "-([0-9]*)"); - if (match.Length > 0) - { - var number = int.Parse(match.Groups[1].Value); - if (number < 60) - return base.GetTexture(componentName.Replace($"-{number}", $"-{number % 2}")); - } + if (match.Length > 0 && int.TryParse(match.Groups[1].Value, out var number) && number < 60) + return base.GetTexture(componentName.Replace($"-{number}", $"-{number % 2}")); } return base.GetTexture(componentName); From 33946f045812e67b22681cdedf408008807ac739 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 20 Aug 2019 11:18:41 +0200 Subject: [PATCH 361/645] Fix CI issues and update comments. --- osu.Game/Screens/Menu/IntroScreen.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index a621e29cf8..6a98c78d5f 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -30,14 +30,14 @@ namespace osu.Game.Screens.Menu private LeasedBindable beatmap; - public new Bindable Beatmap { get => beatmap; } + public new Bindable Beatmap => beatmap; protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack(); [BackgroundDependencyLoader] private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) { - //we take a lease on the beatmap bindable to prevent music playback from changing / pausing music during intros, as it is causing weird interactions with certains intros + // we take a lease on the beatmap bindable to prevent music playback from changing / pausing during intros, as it is causing weird interactions with certains intros. beatmap = base.Beatmap.BeginLease(false); menuVoice = config.GetBindable(OsuSetting.MenuVoice); @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Menu protected void LoadMenu() { DidLoadMenu = true; - beatmap.Return(); //we return the lease to the beatmap bindable as we're pushing the main menu. + beatmap.Return(); this.Push(mainMenu); } From 0de219dda48cb8d7a370e0424ebba7a5e9025c0a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Jun 2019 20:47:43 +0900 Subject: [PATCH 362/645] Update with spritetext text builder changes --- osu.Game/Skinning/LegacySkin.cs | 50 +++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 3eda76e40f..ee88d3254e 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -15,6 +15,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; +using osu.Framework.Text; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -234,37 +235,50 @@ namespace osu.Game.Skinning private class LegacySpriteText : OsuSpriteText { - private readonly TextureStore textures; - private readonly string font; + private readonly LegacyGlyphStore glyphStore; public LegacySpriteText(TextureStore textures, string font) { - this.textures = textures; - this.font = font; - Shadow = false; UseFullGlyphHeight = false; + + Font = new FontUsage(font, 16); + glyphStore = new LegacyGlyphStore(textures); } - protected override Texture GetTextureForCharacter(char c) + protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore); + + private class LegacyGlyphStore : ITexturedGlyphLookupStore { - string textureName = $"{font}-{c}"; + private readonly TextureStore textures; - // Approximate value that brings character sizing roughly in-line with stable - float ratio = 36; - - var texture = textures.Get($"{textureName}@2x"); - - if (texture == null) + public LegacyGlyphStore(TextureStore textures) { - ratio = 18; - texture = textures.Get(textureName); + this.textures = textures; } - if (texture != null) - texture.ScaleAdjust = ratio; + public ITexturedCharacterGlyph Get(string fontName, char character) + { + string textureName = $"{fontName}-{character}"; - return texture; + // Approximate value that brings character sizing roughly in-line with stable + float ratio = 36; + + var texture = textures.Get($"{textureName}@2x"); + + if (texture == null) + { + ratio = 18; + texture = textures.Get(textureName); + } + + if (texture != null) + texture.ScaleAdjust = ratio; + + return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture?.Width ?? 0, null), texture, 1f / ratio); + } + + public Task GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character)); } } From f1d02d8169a6b38b6f8019c83a3fbaea8bae2d81 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 15:00:14 +0300 Subject: [PATCH 363/645] Update design in line with web --- .../Kudosu/DrawableKudosuHistoryItem.cs | 105 +++++++++++++----- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 9b68131515..7c120e60f3 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -12,49 +12,100 @@ using osu.Game.Online.Chat; namespace osu.Game.Overlays.Profile.Sections.Kudosu { - public class DrawableKudosuHistoryItem : DrawableProfileRow + public class DrawableKudosuHistoryItem : CompositeDrawable { + private const int height = 25; + + [Resolved] + private OsuColour colours { get; set; } + private readonly APIKudosuHistory historyItem; - private LinkFlowContainer content; + private readonly LinkFlowContainer linkFlowContainer; + private readonly DrawableDate date; public DrawableKudosuHistoryItem(APIKudosuHistory historyItem) { this.historyItem = historyItem; + + Height = height; + RelativeSizeAxes = Axes.X; + AddRangeInternal(new Drawable[] + { + linkFlowContainer = new LinkFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + }, + date = new DrawableDate(historyItem.CreatedAt) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + } + }); } [BackgroundDependencyLoader] private void load() { - LeftFlowContainer.Padding = new MarginPadding { Left = 10 }; + date.Colour = colours.GreySeafoamLighter; - LeftFlowContainer.Add(content = new LinkFlowContainer + switch (historyItem.Action) { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - }); + case KudosuAction.VoteGive: + case KudosuAction.Give: + linkFlowContainer.AddText($@"Received "); + addKudosuPart(); + addMainPart(); + addPostPart(); + break; - RightFlowContainer.Add(new DrawableDate(historyItem.CreatedAt) - { - Font = OsuFont.GetFont(size: 13), - Colour = OsuColour.Gray(0xAA), - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }); + case KudosuAction.Reset: + addMainPart(); + addPostPart(); + break; - var formatted = createMessage(); + case KudosuAction.VoteReset: + linkFlowContainer.AddText($@"Lost "); + addKudosuPart(); + addMainPart(); + addPostPart(); + break; - content.AddLinks(formatted.Text, formatted.Links); + case KudosuAction.DenyKudosuReset: + linkFlowContainer.AddText($@"Denied "); + addKudosuPart(); + addMainPart(); + addPostPart(); + break; + + case KudosuAction.Revoke: + addMainPart(); + addPostPart(); + break; + } } - protected override Drawable CreateLeftVisual() => new Container + private void addKudosuPart() { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - }; + linkFlowContainer.AddText($@"{historyItem.Amount} kudosu", t => + { + t.Font = t.Font.With(italics: true); + t.Colour = colours.Blue; + }); + } + + private void addMainPart() + { + var text = createMessage(); + + linkFlowContainer.AddLinks(text.Text, text.Links); + } + + private void addPostPart() => linkFlowContainer.AddLink(historyItem.Post.Title, historyItem.Post.Url); private MessageFormatter.MessageFormatterResult createMessage() { - string postLinkTemplate() => $"[{historyItem.Post.Url} {historyItem.Post.Title}]"; string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; string message; @@ -62,27 +113,27 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu switch (historyItem.Action) { case KudosuAction.Give: - message = $"Received {historyItem.Amount} kudosu from {userLinkTemplate()} for a post at {postLinkTemplate()}"; + message = $" from {userLinkTemplate()} for a post at "; break; case KudosuAction.VoteGive: - message = $"Received {historyItem.Amount} kudosu from obtaining votes in modding post of {postLinkTemplate()}"; + message = $" from obtaining votes in modding post of "; break; case KudosuAction.Reset: - message = $"Kudosu reset by {userLinkTemplate()} for the post {postLinkTemplate()}"; + message = $"Kudosu reset by {userLinkTemplate()} for the post "; break; case KudosuAction.VoteReset: - message = $"Lost {historyItem.Amount} kudosu from losing votes in modding post of {postLinkTemplate()}"; + message = $" from losing votes in modding post of "; break; case KudosuAction.DenyKudosuReset: - message = $"Denied {historyItem.Amount} kudosu from modding post {postLinkTemplate()}"; + message = $" from modding post "; break; case KudosuAction.Revoke: - message = $"Denied kudosu by {userLinkTemplate()} for the post {postLinkTemplate()}"; + message = $"Denied kudosu by {userLinkTemplate()} for the post "; break; default: From 832b365bd08ac76da29707aea9d2d466d745497c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 15:17:31 +0300 Subject: [PATCH 364/645] Add testing --- .../Visual/Online/TestSceneKudosuHistory.cs | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs new file mode 100644 index 0000000000..6424db89fa --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -0,0 +1,156 @@ +// 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.Overlays.Profile.Sections.Kudosu; +using System.Collections.Generic; +using System; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.API.Requests; +using osu.Framework.Extensions.IEnumerableExtensions; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneKudosuHistory : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DrawableKudosuHistoryItem), + }; + + private readonly Box background; + + public TestSceneKudosuHistory() + { + FillFlowContainer content; + + AddRange(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + content = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Width = 0.7f, + AutoSizeAxes = Axes.Y, + } + }); + + items.ForEach(t => content.Add(new DrawableKudosuHistoryItem(t))); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoam; + } + + private IEnumerable items = new[] + { + new APIKudosuHistory + { + Amount = 10, + CreatedAt = new DateTimeOffset(new DateTime(2011, 11, 11)), + Action = KudosuAction.DenyKudosuReset, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 1", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username1", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 5, + CreatedAt = new DateTimeOffset(new DateTime(2012, 10, 11)), + Action = KudosuAction.Give, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 2", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username2", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 8, + CreatedAt = new DateTimeOffset(new DateTime(2013, 9, 11)), + Action = KudosuAction.Reset, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 3", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username3", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 7, + CreatedAt = new DateTimeOffset(new DateTime(2014, 8, 11)), + Action = KudosuAction.Revoke, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 4", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username4", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 100, + CreatedAt = new DateTimeOffset(new DateTime(2015, 7, 11)), + Action = KudosuAction.VoteGive, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 5", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username5", + Url = @"https://osu.ppy.sh/u/1234" + } + }, + new APIKudosuHistory + { + Amount = 20, + CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)), + Action = KudosuAction.VoteReset, + Post = new APIKudosuHistory.ModdingPost + { + Title = @"Random post 6", + Url = @"https://osu.ppy.sh/b/1234", + }, + Giver = new APIKudosuHistory.KudosuGiver + { + Username = @"Username6", + Url = @"https://osu.ppy.sh/u/1234" + } + } + }; + } +} From c4344f3f7cc985b5f40ad4e1603c59ab910b3e2b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 15:29:32 +0300 Subject: [PATCH 365/645] CI fixes --- .../Visual/Online/TestSceneKudosuHistory.cs | 2 +- .../Kudosu/DrawableKudosuHistoryItem.cs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index 6424db89fa..dcf2bec239 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Online background.Colour = colours.GreySeafoam; } - private IEnumerable items = new[] + private readonly IEnumerable items = new[] { new APIKudosuHistory { diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 7c120e60f3..d6dfdc84ec 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { case KudosuAction.VoteGive: case KudosuAction.Give: - linkFlowContainer.AddText($@"Received "); + linkFlowContainer.AddText(@"Received "); addKudosuPart(); addMainPart(); addPostPart(); @@ -66,14 +66,14 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu break; case KudosuAction.VoteReset: - linkFlowContainer.AddText($@"Lost "); + linkFlowContainer.AddText(@"Lost "); addKudosuPart(); addMainPart(); addPostPart(); break; case KudosuAction.DenyKudosuReset: - linkFlowContainer.AddText($@"Denied "); + linkFlowContainer.AddText(@"Denied "); addKudosuPart(); addMainPart(); addPostPart(); @@ -113,27 +113,27 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu switch (historyItem.Action) { case KudosuAction.Give: - message = $" from {userLinkTemplate()} for a post at "; + message = $@" from {userLinkTemplate()} for a post at "; break; case KudosuAction.VoteGive: - message = $" from obtaining votes in modding post of "; + message = @" from obtaining votes in modding post of "; break; case KudosuAction.Reset: - message = $"Kudosu reset by {userLinkTemplate()} for the post "; + message = $@"Kudosu reset by {userLinkTemplate()} for the post "; break; case KudosuAction.VoteReset: - message = $" from losing votes in modding post of "; + message = @" from losing votes in modding post of "; break; case KudosuAction.DenyKudosuReset: - message = $" from modding post "; + message = @" from modding post "; break; case KudosuAction.Revoke: - message = $"Denied kudosu by {userLinkTemplate()} for the post "; + message = $@"Denied kudosu by {userLinkTemplate()} for the post "; break; default: From 5c7cb4dc21ecb4a3b5961a4bed7c7f4b1562aa1a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 16:11:59 +0300 Subject: [PATCH 366/645] Simplify text creation --- .../Kudosu/DrawableKudosuHistoryItem.cs | 64 +++++-------------- 1 file changed, 16 insertions(+), 48 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index d6dfdc84ec..1b0a501db2 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -50,37 +50,45 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { date.Colour = colours.GreySeafoamLighter; + string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; + switch (historyItem.Action) { case KudosuAction.VoteGive: + linkFlowContainer.AddText(@"Received "); + addKudosuPart(); + addMainPart($@" from {userLinkTemplate()} for a post at "); + addPostPart(); + break; + case KudosuAction.Give: linkFlowContainer.AddText(@"Received "); addKudosuPart(); - addMainPart(); + addMainPart(@" from obtaining votes in modding post of "); addPostPart(); break; case KudosuAction.Reset: - addMainPart(); + addMainPart($@"Kudosu reset by {userLinkTemplate()} for the post "); addPostPart(); break; case KudosuAction.VoteReset: linkFlowContainer.AddText(@"Lost "); addKudosuPart(); - addMainPart(); + addMainPart(@" from losing votes in modding post of "); addPostPart(); break; case KudosuAction.DenyKudosuReset: linkFlowContainer.AddText(@"Denied "); addKudosuPart(); - addMainPart(); + addMainPart(@" from modding post "); addPostPart(); break; case KudosuAction.Revoke: - addMainPart(); + addMainPart($@"Denied kudosu by {userLinkTemplate()} for the post "); addPostPart(); break; } @@ -95,53 +103,13 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu }); } - private void addMainPart() + private void addMainPart(string text) { - var text = createMessage(); + var formatted = MessageFormatter.FormatText(text); - linkFlowContainer.AddLinks(text.Text, text.Links); + linkFlowContainer.AddLinks(formatted.Text, formatted.Links); } private void addPostPart() => linkFlowContainer.AddLink(historyItem.Post.Title, historyItem.Post.Url); - - private MessageFormatter.MessageFormatterResult createMessage() - { - string userLinkTemplate() => $"[{historyItem.Giver?.Url} {historyItem.Giver?.Username}]"; - - string message; - - switch (historyItem.Action) - { - case KudosuAction.Give: - message = $@" from {userLinkTemplate()} for a post at "; - break; - - case KudosuAction.VoteGive: - message = @" from obtaining votes in modding post of "; - break; - - case KudosuAction.Reset: - message = $@"Kudosu reset by {userLinkTemplate()} for the post "; - break; - - case KudosuAction.VoteReset: - message = @" from losing votes in modding post of "; - break; - - case KudosuAction.DenyKudosuReset: - message = @" from modding post "; - break; - - case KudosuAction.Revoke: - message = $@"Denied kudosu by {userLinkTemplate()} for the post "; - break; - - default: - message = string.Empty; - break; - } - - return MessageFormatter.FormatText(message); - } } } From 426c7a48989302453ca7e05b8c91738e06d6ad7e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 20 Aug 2019 16:19:21 +0300 Subject: [PATCH 367/645] Fix incorrect templates --- .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 1b0a501db2..e5f5b720c2 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -57,14 +57,14 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu case KudosuAction.VoteGive: linkFlowContainer.AddText(@"Received "); addKudosuPart(); - addMainPart($@" from {userLinkTemplate()} for a post at "); + addMainPart(@" from obtaining votes in modding post of "); addPostPart(); break; case KudosuAction.Give: linkFlowContainer.AddText(@"Received "); addKudosuPart(); - addMainPart(@" from obtaining votes in modding post of "); + addMainPart($@" from {userLinkTemplate()} for a post at "); addPostPart(); break; From 439d825dd1beecf4a9c447974bcacdee82df3c6b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 20 Aug 2019 18:39:29 +0300 Subject: [PATCH 368/645] Disallow adding bonus judgements' result to statistics --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index c8858233aa..e47df6b473 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -325,9 +325,6 @@ namespace osu.Game.Rulesets.Scoring JudgedHits++; - if (result.Type != HitResult.None) - scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; - if (result.Judgement.AffectsCombo) { switch (result.Type) @@ -352,6 +349,9 @@ namespace osu.Game.Rulesets.Scoring } else { + if (result.HasResult) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1; + baseScore += result.Judgement.NumericResultFor(result); rollingMaxBaseScore += result.Judgement.MaxNumericResult; } @@ -371,9 +371,6 @@ namespace osu.Game.Rulesets.Scoring JudgedHits--; - if (result.Type != HitResult.None) - scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1; - if (result.Judgement.IsBonus) { if (result.IsHit) @@ -381,6 +378,9 @@ namespace osu.Game.Rulesets.Scoring } else { + if (result.HasResult) + scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1; + baseScore -= result.Judgement.NumericResultFor(result); rollingMaxBaseScore -= result.Judgement.MaxNumericResult; } From 48716f8f2b6c57639cf2a2223bb78610ecccf403 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Aug 2019 13:29:50 +0900 Subject: [PATCH 369/645] Update framework --- osu.Android.props | 2 +- .../Objects/Drawable/DrawableFruit.cs | 2 +- .../Objects/Drawable/Pieces/Pulp.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- .../Objects/Drawables/Pieces/BodyPiece.cs | 4 ++-- .../Objects/Drawables/Pieces/LaneGlowPiece.cs | 4 ++-- .../UI/Components/ColumnBackground.cs | 2 +- .../Objects/Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/DrawableRepeatPoint.cs | 2 +- .../Objects/Drawables/Pieces/CirclePiece.cs | 2 +- .../Objects/Drawables/Pieces/ExplodePiece.cs | 4 ++-- .../Objects/Drawables/Pieces/FlashPiece.cs | 2 +- .../Objects/Drawables/Pieces/GlowPiece.cs | 2 +- .../Objects/Drawables/Pieces/SliderBall.cs | 4 ++-- .../Objects/Drawables/DrawableSwell.cs | 4 ++-- .../Objects/Drawables/Pieces/CirclePiece.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 4 ++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 6 +++--- .../Visual/UserInterface/TestSceneCursors.cs | 2 +- .../Components/TournamentBeatmapPanel.cs | 2 +- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 9 --------- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- osu.Game/Graphics/Containers/OsuScrollContainer.cs | 2 +- osu.Game/Graphics/Cursor/MenuCursor.cs | 2 +- osu.Game/Graphics/Sprites/GlowingSpriteText.cs | 2 +- osu.Game/Graphics/UserInterface/DialogButton.cs | 2 +- osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs | 2 +- osu.Game/Graphics/UserInterface/OsuButton.cs | 2 +- .../Overlays/Profile/Header/Components/RankGraph.cs | 9 --------- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 2 +- .../Overlays/Toolbar/ToolbarOverlayToggleButton.cs | 2 +- .../Components/RadioButtons/DrawableRadioButton.cs | 2 +- .../Edit/Compose/Components/BeatDivisorControl.cs | 2 +- osu.Game/Screens/Menu/Button.cs | 2 +- osu.Game/Screens/Menu/IntroTriangles.cs | 6 +++--- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Menu/MenuSideFlashes.cs | 4 ++-- osu.Game/Screens/Menu/OsuLogo.cs | 4 ++-- .../Screens/Multi/Match/Components/HeaderButton.cs | 2 +- osu.Game/Screens/ScreenWhiteBox.cs | 2 +- .../Screens/Select/Carousel/DrawableCarouselItem.cs | 2 +- .../Screens/Select/Options/BeatmapOptionsButton.cs | 2 +- osu.Game/Storyboards/CommandTimelineGroup.cs | 4 ++-- osu.Game/Storyboards/Drawables/DrawablesExtensions.cs | 10 +++++----- osu.Game/Storyboards/StoryboardSprite.cs | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 47 files changed, 63 insertions(+), 81 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index bb283dc0c5..fe6420ead8 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -61,6 +61,6 @@ - + diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index ce2daebbf1..1af77b75fc 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Anchor = Anchor.Centre, Origin = Anchor.Centre, AccentColour = Color4.Red, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0.5f, Scale = new Vector2(1.333f) }); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index b9b6d5b924..1e9daf18db 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces Anchor = Anchor.Centre; Origin = Anchor.Centre; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Colour = Color4.White.Opacity(0.9f); } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 0b06e958e6..62abe53559 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -201,7 +201,7 @@ namespace osu.Game.Rulesets.Catch.UI additive.Scale = Scale; additive.Colour = HyperDashing ? Color4.Red : Color4.White; additive.RelativePositionAxes = RelativePositionAxes; - additive.Blending = BlendingMode.Additive; + additive.Blending = BlendingParameters.Additive; AdditiveTarget.Add(additive); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index a92e56d3c3..31a4857805 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -26,14 +26,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces public BodyPiece() { - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Children = new[] { Background = new Box { RelativeSizeAxes = Axes.Both }, Foreground = new BufferedContainer { - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, RelativeSizeAxes = Axes.Both, CacheDrawnFrameBuffer = true, Children = new Drawable[] diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs index 9e0307c5c2..48c7ea7b7f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces Name = "Top", RelativeSizeAxes = Axes.Both, Height = 0.5f, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = ColourInfo.GradientVertical(Color4.Transparent, Color4.White.Opacity(alpha)) }, new Box @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.Both, Height = 0.5f, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = ColourInfo.GradientVertical(Color4.White.Opacity(alpha), Color4.Transparent) } }; diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs index b4e29ae9f9..5ee78aa496 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components Name = "Background Gradient Overlay", RelativeSizeAxes = Axes.Both, Height = 0.5f, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0 } }; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index a2a23e9ff7..523e911434 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections Child = new Box { Size = new Vector2(width), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Origin = Anchor.Centre, Anchor = Anchor.Centre, Alpha = 0.5f, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index f75b62eecf..1db1eec33e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Origin = Anchor.Centre; InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs index c92937ef09..a59cfc1123 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces new TrianglesPiece { RelativeSizeAxes = Axes.Both, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0.5f, } }; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs index 8ff16f8b84..1d21347cba 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs @@ -17,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre; Origin = Anchor.Centre; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Alpha = 0; Child = new SkinnableDrawable("Play/osu/hitcircle-explode", _ => new TrianglesPiece { - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, RelativeSizeAxes = Axes.Both, Alpha = 0.2f, }, s => s.GetTexture("Play/osu/hitcircle") == null); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs index c22073f56c..1e3af567fe 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre; Origin = Anchor.Centre; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Alpha = 0; Child = new SkinnableDrawable("Play/osu/hitcircle-flash", name => new CircularContainer diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs index 917695c790..a36d9e96c8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre, Origin = Anchor.Centre, Texture = textures.Get(name), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0.5f }, s => s.GetTexture("Play/osu/hitcircle") == null); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 8b72b23ca3..dbab83d24a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces this.drawableSlider = drawableSlider; this.slider = slider; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Origin = Anchor.Centre; Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); @@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Masking = true, BorderThickness = 5, BorderColour = Color4.Orange, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Child = new Box { Colour = Color4.Orange, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 5ec9dc61e2..82448ec7d5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Origin = Anchor.Centre, Alpha = 0, RelativeSizeAxes = Axes.Both, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Masking = true, Children = new[] { @@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Both, Masking = true, BorderThickness = target_ring_thick_border, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Children = new Drawable[] { new Box diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs index b7db819717..d9c0664ecd 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Colour = Color4.White, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0, AlwaysPresent = true } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index aa37ff7008..d6866c7d25 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Taiko.UI Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Alpha = 0, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, centre = new Sprite { @@ -124,7 +124,7 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Size = new Vector2(0.7f), Alpha = 0, - Blending = BlendingMode.Additive + Blending = BlendingParameters.Additive } }; } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 7427a3235d..e62dc45cab 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, HitTarget = new HitTarget { @@ -127,14 +127,14 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, - Blending = BlendingMode.Additive + Blending = BlendingParameters.Additive }, judgementContainer = new JudgementContainer { Name = "Judgements", RelativeSizeAxes = Axes.Y, Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, - Blending = BlendingMode.Additive + Blending = BlendingParameters.Additive }, } }, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs index 23d9112b25..e95f4c09c6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs @@ -249,7 +249,7 @@ namespace osu.Game.Tests.Visual.UserInterface Size = new Vector2(50); Masking = true; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; Alpha = 0.5f; Child = new Box { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs index d5e28c1e3e..f6c1be0e36 100644 --- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs +++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs @@ -125,7 +125,7 @@ namespace osu.Game.Tournament.Components { RelativeSizeAxes = Axes.Both, Colour = Color4.Gray, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0, }, }); diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 3c3a7c056e..5cce29d609 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -86,11 +86,6 @@ namespace osu.Game.Beatmaps.Drawables private readonly FillFlowContainer difficultyFlow; - public string TooltipText - { - set { } - } - public DifficultyIconTooltip() { AutoSizeAxes = Axes.Both; @@ -168,10 +163,6 @@ namespace osu.Game.Beatmaps.Drawables return true; } - public void Refresh() - { - } - public void Move(Vector2 pos) => Position = pos; protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 3ae1c3ef12..17df9ccc7e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -246,7 +246,7 @@ namespace osu.Game.Beatmaps.Formats switch (type) { case "A": - timelineGroup?.BlendingMode.Add(easing, startTime, endTime, BlendingMode.Additive, startTime == endTime ? BlendingMode.Additive : BlendingMode.Inherit); + timelineGroup?.BlendingParameters.Add(easing, startTime, endTime, BlendingParameters.Additive, startTime == endTime ? BlendingParameters.Additive : BlendingParameters.Inherit); break; case "H": diff --git a/osu.Game/Graphics/Containers/OsuScrollContainer.cs b/osu.Game/Graphics/Containers/OsuScrollContainer.cs index 8fc8dec9fd..2721ce55dc 100644 --- a/osu.Game/Graphics/Containers/OsuScrollContainer.cs +++ b/osu.Game/Graphics/Containers/OsuScrollContainer.cs @@ -98,7 +98,7 @@ namespace osu.Game.Graphics.Containers public OsuScrollbar(Direction scrollDir) : base(scrollDir) { - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; CornerRadius = 5; diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 092a23e787..e103798355 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -150,7 +150,7 @@ namespace osu.Game.Graphics.Cursor }, AdditiveLayer = new Sprite { - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = colour.Pink, Alpha = 0, Texture = textures.Get(@"Cursor/menu-cursor-additive"), diff --git a/osu.Game/Graphics/Sprites/GlowingSpriteText.cs b/osu.Game/Graphics/Sprites/GlowingSpriteText.cs index 74e387d60e..24816deeb5 100644 --- a/osu.Game/Graphics/Sprites/GlowingSpriteText.cs +++ b/osu.Game/Graphics/Sprites/GlowingSpriteText.cs @@ -56,7 +56,7 @@ namespace osu.Game.Graphics.Sprites BlurSigma = new Vector2(4), CacheDrawnFrameBuffer = true, RelativeSizeAxes = Axes.Both, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Size = new Vector2(3f), Children = new[] { diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index b50bf14bab..927ad13829 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -254,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface colourContainer.Add(flash); flash.Colour = ButtonColour; - flash.Blending = BlendingMode.Additive; + flash.Blending = BlendingParameters.Additive; flash.Alpha = 0.3f; flash.FadeOutFromOne(click_duration); flash.Expire(); diff --git a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs index 1a8fea4ff9..660bd7979f 100644 --- a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.UserInterface { RelativeSizeAxes = Axes.Both, Colour = HoverColour, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0, }, } diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 7a27f825f6..c1810800a0 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -39,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface hover = new Box { RelativeSizeAxes = Axes.Both, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = Color4.White.Opacity(0.1f), Alpha = 0, Depth = -1 diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index de760eedfd..24ed0cc022 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -296,15 +296,6 @@ namespace osu.Game.Overlays.Profile.Header.Components this.MoveTo(pos, 200, Easing.OutQuint); } - public void Refresh() - { - } - - public string TooltipText - { - set => throw new InvalidOperationException(); - } - protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 2b2b19b73a..d6b810366d 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Toolbar { RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(80).Opacity(180), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0, }, Flow = new FillFlowContainer diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index b286cbfb1d..36387bb00d 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Toolbar { RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(150).Opacity(180), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Depth = 2, Alpha = 0, }); diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs index 70c0cf623e..5854d66aa8 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons Scale = new Vector2(0.5f), X = 10, Masking = true, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Child = new Box { RelativeSizeAxes = Axes.Both } }; } diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index c615656d60..0d16d8474b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -360,7 +360,7 @@ namespace osu.Game.Screens.Edit.Compose.Components Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.2f), Color4.White), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, new EquilateralTriangle { diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index badd1e0549..1bf25a2504 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Menu { EdgeSmoothness = new Vector2(1.5f, 0), RelativeSizeAxes = Axes.Both, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = Color4.White, Alpha = 0, }, diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index ba0d624959..f5a72c2c1d 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -296,7 +296,7 @@ namespace osu.Game.Screens.Menu { Colour = Color4.White; RelativeSizeAxes = Axes.Both; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; } protected override void LoadComplete() @@ -399,11 +399,11 @@ namespace osu.Game.Screens.Menu Origin = Anchor.Centre, Colour = Color4.Black, Size = new Vector2(size - 5), - Blending = BlendingMode.None, + Blending = BlendingParameters.None, }); } - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; CacheDrawnFrameBuffer = true; } } diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 39bda799b5..9d0a5cd05b 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Menu public LogoVisualisation() { texture = Texture.WhitePixel; - Blending = BlendingMode.Additive; + Blending = BlendingParameters.Additive; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 95d0bf04b4..393964561c 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -70,7 +70,7 @@ namespace osu.Game.Screens.Menu // align off-screen to make sure our edges don't become visible during parallax. X = -box_width, Alpha = 0, - Blending = BlendingMode.Additive + Blending = BlendingParameters.Additive }, rightBox = new Box { @@ -81,7 +81,7 @@ namespace osu.Game.Screens.Menu Height = 1.5f, X = box_width, Alpha = 0, - Blending = BlendingMode.Additive + Blending = BlendingParameters.Additive } }; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 479b3d80b6..0c5bf12bdb 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -124,7 +124,7 @@ namespace osu.Game.Screens.Menu { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Alpha = 0 } } @@ -185,7 +185,7 @@ namespace osu.Game.Screens.Menu flashLayer = new Box { RelativeSizeAxes = Axes.Both, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = Color4.White, Alpha = 0, }, diff --git a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs index f3412d0be7..de6ece6a05 100644 --- a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Multi.Match.Components { RelativeSizeAxes = Axes.Both, Alpha = 0.15f, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, }); } diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs index 5648dd997b..6c5854d17e 100644 --- a/osu.Game/Screens/ScreenWhiteBox.cs +++ b/osu.Game/Screens/ScreenWhiteBox.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens Colour = getColourFor(GetType()), Alpha = 0.2f, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, textContainer = new FillFlowContainer { diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index b906bd935c..6118191302 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Select.Carousel { RelativeSizeAxes = Axes.Both, Alpha = 0, - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, }, } }; diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index a8b5bbbd00..ff9beafb23 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -121,7 +121,7 @@ namespace osu.Game.Screens.Select.Options { RelativeSizeAxes = Axes.Both, EdgeSmoothness = new Vector2(1.5f, 0), - Blending = BlendingMode.Additive, + Blending = BlendingParameters.Additive, Colour = Color4.White, Alpha = 0, }, diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index b1cc0436de..461ee762e9 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -20,7 +20,7 @@ namespace osu.Game.Storyboards public CommandTimeline Rotation = new CommandTimeline(); public CommandTimeline Colour = new CommandTimeline(); public CommandTimeline Alpha = new CommandTimeline(); - public CommandTimeline BlendingMode = new CommandTimeline(); + public CommandTimeline BlendingParameters = new CommandTimeline(); public CommandTimeline FlipH = new CommandTimeline(); public CommandTimeline FlipV = new CommandTimeline(); @@ -35,7 +35,7 @@ namespace osu.Game.Storyboards yield return Rotation; yield return Colour; yield return Alpha; - yield return BlendingMode; + yield return BlendingParameters; yield return FlipH; yield return FlipV; } diff --git a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs index 7e31e1135e..bbc55a336d 100644 --- a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs +++ b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs @@ -12,19 +12,19 @@ namespace osu.Game.Storyboards.Drawables /// Adjusts after a delay. ///