From ffbe68bd26f8e4dbe154037ad47c15e972699676 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 22:08:48 +0100 Subject: [PATCH 01/65] Add judgementTally to HUD overlay --- .../HUD/JudgementCounter/JudgementTally.cs | 56 +++++++++++++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 5 ++ 2 files changed, 61 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs new file mode 100644 index 0000000000..2bc89aeea1 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.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 System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public partial class JudgementTally : CompositeDrawable + { + [Resolved] + private ScoreProcessor scoreProcessor { get; set; } = null!; + + public List Results = new List(); + + [BackgroundDependencyLoader] + private void load(DrawableRuleset ruleset) + { + foreach (var result in ruleset.Ruleset.GetHitResults()) + { + Results.Add(new JudgementCounterInfo + { + ResultInfo = (result.result, result.displayName), + ResultCount = new BindableInt(), + }); + } + } + + protected override void LoadComplete() + { + base.LoadComplete(); + scoreProcessor.NewJudgement += judgement => + { + foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + { + result.ResultCount.Value++; + } + }; + scoreProcessor.JudgementReverted += judgement => + { + foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + { + result.ResultCount.Value--; + } + }; + } + } +} diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 4c2483a0e6..816b8b2543 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osu.Game.Skinning; using osuTK; +using JudgementTally = osu.Game.Screens.Play.HUD.JudgementCounter.JudgementTally; namespace osu.Game.Screens.Play { @@ -58,6 +59,9 @@ namespace osu.Game.Screens.Play [Cached] private readonly ClicksPerSecondCalculator clicksPerSecondCalculator; + [Cached] + private readonly JudgementTally tally; + public Bindable ShowHealthBar = new Bindable(true); private readonly DrawableRuleset drawableRuleset; @@ -146,6 +150,7 @@ namespace osu.Game.Screens.Play Spacing = new Vector2(5) }, clicksPerSecondCalculator = new ClicksPerSecondCalculator(), + tally = new JudgementTally() }; hideTargets = new List { mainComponents, KeyCounter, topRightElements }; From f798951f0974b49592d10b1f7959d6e0e0a8ce46 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 22:09:14 +0100 Subject: [PATCH 02/65] Create Judgement Info struct --- .../HUD/JudgementCounter/JudgementCounterInfo.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs new file mode 100644 index 0000000000..45f89c30d2 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs @@ -0,0 +1,16 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Framework.Localisation; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public struct JudgementCounterInfo + { + public (HitResult Type, LocalisableString Displayname) ResultInfo { get; set; } + + public BindableInt ResultCount { get; set; } + } +} From 4c17b27273b638e2f271782be2cb50b8abf59f2b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 23:47:17 +0100 Subject: [PATCH 03/65] Add Display, Counter, Tests --- .../Gameplay/TestSceneJudgementCounter.cs | 136 ++++++++++++++++++ .../HUD/JudgementCounter/JudgementCounter.cs | 118 +++++++++++++++ .../JudgementCounterDisplay.cs | 133 +++++++++++++++++ .../HUD/JudgementCounter/JudgementTally.cs | 8 +- 4 files changed, 391 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs new file mode 100644 index 0000000000..27f2362047 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -0,0 +1,136 @@ +// 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.Diagnostics; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Judgements; +using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Play.HUD.JudgementCounter; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public partial class TestSceneJudgementCounter : OsuTestScene + { + private ScoreProcessor scoreProcessor = null!; + private JudgementTally judgementTally = null!; + private TestJudgementCounterDisplay counter = null!; + + private readonly Bindable lastJudgementResult = new Bindable(); + + private int iteration; + + [SetUpSteps] + public void SetupSteps() => AddStep("Create components", () => + { + var ruleset = CreateRuleset(); + + Debug.Assert(ruleset != null); + + scoreProcessor = new ScoreProcessor(ruleset); + Child = new DependencyProvidingContainer + { + RelativeSizeAxes = Axes.Both, + CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, + Children = new Drawable[] + { + judgementTally = new JudgementTally(), + new DependencyProvidingContainer + { + RelativeSizeAxes = Axes.Both, + CachedDependencies = new (Type, object)[] { (typeof(JudgementTally), judgementTally) }, + Child = counter = new TestJudgementCounterDisplay + { + Margin = new MarginPadding { Top = 100 }, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + } + }, + }; + }); + + protected override Ruleset CreateRuleset() => new ManiaRuleset(); + + private void applyOneJudgement(HitResult result) + { + lastJudgementResult.Value = new OsuJudgementResult(new HitObject + { + StartTime = iteration * 10000 + }, new OsuJudgement()) + { + Type = result, + }; + scoreProcessor.ApplyResult(lastJudgementResult.Value); + + iteration++; + } + + [Test] + public void TestAddJudgementsToCounters() + { + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Great), 2); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); + AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); + } + + [Test] + public void TestAddWhilstHidden() + { + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); + AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); + AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + } + + [Test] + public void TestChangeFlowDirection() + { + AddStep("Set direction vertical", () => counter.Direction.Value = FillDirection.Vertical); + AddStep("Set direction horizontal", () => counter.Direction.Value = FillDirection.Vertical); + } + + [Test] + public void TestHideJudgementNames() + { + AddStep("Hide judgement names", () => counter.ShowName.Value = false); + } + + [Test] + public void TestHideMaxValue() + { + AddStep("Hide max judgement", () => counter.ShowMax.Value = false); + AddStep("Show max judgement", () => counter.ShowMax.Value = true); + } + + [Test] + public void TestCycleDisplayModes() + { + AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddStep("Show normal judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); + AddStep("Show basic judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); + } + + private int hiddenCount() + { + var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.ResultInfo.Type == HitResult.LargeTickHit); + return num.Result.ResultCount.Value; + } + + private partial class TestJudgementCounterDisplay : JudgementCounterDisplay + { + public new FillFlowContainer JudgementContainer => base.JudgementContainer; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs new file mode 100644 index 0000000000..d9709eb88a --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -0,0 +1,118 @@ +// 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.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public partial class JudgementCounter : OverlayContainer + { + public BindableBool ShowName = new BindableBool(); + public Bindable Direction = new Bindable(); + + public readonly JudgementCounterInfo Result; + + public JudgementCounter(JudgementCounterInfo result) + { + Result = result; + } + + private OsuSpriteText resultName = null!; + private FillFlowContainer flowContainer = null!; + private JudgementRollingCounter counter = null!; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AutoSizeAxes = Axes.Both; + InternalChild = flowContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + counter = new JudgementRollingCounter + { + Current = Result.ResultCount + }, + resultName = new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: 8), + Text = Result.ResultInfo.Displayname + } + } + }; + + var result = Result.ResultInfo.Type; + + if (result.IsBasic()) + { + Colour = colours.ForHitResult(Result.ResultInfo.Type); + return; + } + + if (!result.IsBonus()) + { + Colour = colours.PurpleLight; + return; + } + + Colour = colours.PurpleLighter; + } + + protected override void LoadComplete() + { + ShowName.BindValueChanged(value => + { + if (value.NewValue) + { + resultName.Show(); + return; + } + + resultName.Hide(); + }, true); + + Direction.BindValueChanged(direction => + { + flowContainer.Direction = direction.NewValue; + + if (direction.NewValue == FillDirection.Vertical) + { + changeAnchor(Anchor.TopLeft); + return; + } + + changeAnchor(Anchor.BottomLeft); + + void changeAnchor(Anchor anchor) => counter.Anchor = resultName.Anchor = counter.Origin = resultName.Origin = anchor; + }, true); + + base.LoadComplete(); + } + + protected override void PopIn() + { + this.FadeInFromZero(500, Easing.OutQuint); + } + + protected override void PopOut() + { + this.FadeOut(100); + } + + private sealed partial class JudgementRollingCounter : RollingCounter + { + protected override OsuSpriteText CreateSpriteText() + => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true, size: 16)); + + protected override double RollingDuration => 750; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs new file mode 100644 index 0000000000..b392ce8e04 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -0,0 +1,133 @@ +// 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; +using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; +using osu.Game.Rulesets.Scoring; +using osu.Game.Skinning; +using osuTK; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable + { + public bool UsesFixedAnchor { get; set; } + + [SettingSource("Counter direction")] + public Bindable Direction { get; set; } = new Bindable(); + + [SettingSource("Show judgement names")] + public BindableBool ShowName { get; set; } = new BindableBool(true); + + [SettingSource("Show max judgement")] + public BindableBool ShowMax { get; set; } = new BindableBool(true); + + [SettingSource("Display mode")] + public Bindable Mode { get; set; } = new Bindable(); + + [Resolved] + private JudgementTally tally { get; set; } = null!; + + protected FillFlowContainer JudgementContainer = null!; + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = JudgementContainer = new FillFlowContainer + { + Direction = Direction.Value, + Spacing = new Vector2(10), + AutoSizeAxes = Axes.Both + }; + + foreach (var result in tally.Results) + { + JudgementContainer.Add(createCounter(result)); + } + } + + protected override void Update() + { + Size = JudgementContainer.Size; + base.Update(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Direction.BindValueChanged(direction => JudgementContainer.Direction = direction.NewValue); + Mode.BindValueChanged(_ => updateCounter(), true); + + ShowMax.BindValueChanged(value => + { + var firstChild = JudgementContainer.Children.FirstOrDefault(); + + if (value.NewValue) + { + firstChild?.Show(); + return; + } + + firstChild?.Hide(); + }, true); + } + + private void updateCounter() + { + var counters = JudgementContainer.Children.OfType().ToList(); + + switch (Mode.Value) + { + case DisplayMode.Simple: + foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBasic())) + counter.Show(); + + foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBasic())) + counter.Hide(); + + break; + + case DisplayMode.Normal: + foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBonus())) + counter.Show(); + + foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBonus())) + counter.Hide(); + + break; + + case DisplayMode.All: + foreach (JudgementCounter counter in counters.Where(counter => !counter.IsPresent)) + counter.Show(); + + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } + + public enum DisplayMode + { + Simple, + Normal, + All + } + + private JudgementCounter createCounter(JudgementCounterInfo info) + { + JudgementCounter counter = new JudgementCounter(info) + { + ShowName = { BindTarget = ShowName }, + Direction = { BindTarget = Direction } + }; + return counter; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index 2bc89aeea1..9cbeea7a2a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -9,8 +9,8 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.JudgementCounter { @@ -22,14 +22,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public List Results = new List(); [BackgroundDependencyLoader] - private void load(DrawableRuleset ruleset) + private void load(IBindable working) { - foreach (var result in ruleset.Ruleset.GetHitResults()) + foreach (var result in working.Value.BeatmapInfo.Ruleset.CreateInstance().GetHitResults()) { Results.Add(new JudgementCounterInfo { ResultInfo = (result.result, result.displayName), - ResultCount = new BindableInt(), + ResultCount = new BindableInt() }); } } From 161894da3ba0c26ff1fe7a4473351999c19ba77b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 23:58:10 +0100 Subject: [PATCH 04/65] Add more test checks and fix deserialisation test --- .../Archives/modified-default-20221211.osk | Bin 0 -> 1650 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 5 ++++- .../HUD/JudgementCounter/JudgementCounter.cs | 10 +++++----- 4 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221211.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk new file mode 100644 index 0000000000000000000000000000000000000000..07190db267cfcbf0abf44a5eb95b4e43bb0955d2 GIT binary patch literal 1650 zcmWIWW@Zs#U|`^2__41$)V#A{#{nQOh#4fpz)+l>nWvYTm-)2cFptSlz_ogQ(hG;C zH@8F=E%uturR8F1usI>|yvx0fVRLj{`=)5Kh%9yb!m&$#@A~!s>-O!N%@*d~<`;ZP z@f71Xtz$_B3H%Yh#!+{Yz0w_&)Nagm{B6aw>S`{J3j_M*Aq3^;H=}T|8F6)dAv(Ab<5aqY1+2Z>O|HRMo z=|^O*rEI>?cH!LLn%^>Fr~Wd|K|=s@#Vyw=@NZF-`xgcUZ^iK^V0J5 zvWoNbO8Yi)9WoGc{a$y}IG8)v!$>ro{pF)YewP#{EU~$@&tcLdg@3!*&fa)i^sco! zPLyHyi>sTI4dk~oU(sB!EOX<=#;UJuvQd{0EIx8BV)=H}QZEhFs+;}Rb47yQmU*3; zxb^2Bku`pHPySnM)8007O90!Ns(J=g zhwp#q^9Xfu&d)8#&r8iKDF*xC?R4Ml#|8pz?|+J_rMsWl zm~))lvSjXE-romjEqlB4%K|N7_mGKQD$Zv&{jYs`jPJ6-FWs`BcD?Mo z>hJ};;YEEHA3v|2DIJqF!&_tRvP0iLeF`i1#=MHVl)XsLTk+Vxd)4cBw&!h&K3He# zS6$HCz>?8rs8+W+%#T;OMgDgE?3d3^T}rEZTcy8FLbM=h!`nO`R$1@#Nx4(kSx<8N zxwi6P_UTOJ7%7AJpUi9clg&dUGWIrYjS*W`c1P;$wwN`hSKQX+yY+7V|8!rHmvj7` zLiXT}c7?hCHmAB{5i2!U|5{{M>HAWy?eL*^CegCp51!pC{W9-^?UU+Ts&-!(7pF|j z4$Uxlru&KS@nn&HcBOq!zI9*o`p;CpM&irNSISRyFYy;l|L6E~!T*?Flb5U8SDOAP zz97A{JjCdP==5tmp;wL=7M1Jv-49HhY?)Sm%r$}4=Va;jyU`1slUx=}XpwEm6nUVb zc%H|jBgu!ObJ62hD?{h+GUW5RfAHr^y#xbW`wc-olOm_69JfB)IpfIX@-4>uroUz? zQ^DtQ)=Hi-THF6kzeb!+_4#F^7J1$uPry5p|;f1 zQSkropj>mUWReY~TlDD8rhZwUB}upTn8nIe8{If2()ak$1dF(o?Juq^sB5Wxb@_m8!|%4ok*}6K zT=BL4fr+ohoJ~S9Uz}eBZ9jZ#L0o%@#wDL=&$irW@K=rA7M6(ANZGIP>R}+Y)!F-u0p5&E zA`H08T3}>BKqH8PmAvS>(915U9tMWSXHZ@6k_=rddg+1CIv diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 27f2362047..885b182a6f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -102,9 +102,12 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestHideJudgementNames() + public void TestToggleJudgementNames() { AddStep("Hide judgement names", () => counter.ShowName.Value = false); + AddAssert("Assert hidden", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); + AddStep("Hide judgement names", () => counter.ShowName.Value = true); + AddAssert("Assert shown", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index d9709eb88a..d7bb8939e1 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter Result = result; } - private OsuSpriteText resultName = null!; + public OsuSpriteText ResultName = null!; private FillFlowContainer flowContainer = null!; private JudgementRollingCounter counter = null!; @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { Current = Result.ResultCount }, - resultName = new OsuSpriteText + ResultName = new OsuSpriteText { Font = OsuFont.Numeric.With(size: 8), Text = Result.ResultInfo.Displayname @@ -72,11 +72,11 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { if (value.NewValue) { - resultName.Show(); + ResultName.Show(); return; } - resultName.Hide(); + ResultName.Hide(); }, true); Direction.BindValueChanged(direction => @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter changeAnchor(Anchor.BottomLeft); - void changeAnchor(Anchor anchor) => counter.Anchor = resultName.Anchor = counter.Origin = resultName.Origin = anchor; + void changeAnchor(Anchor anchor) => counter.Anchor = ResultName.Anchor = counter.Origin = ResultName.Origin = anchor; }, true); base.LoadComplete(); From a107fca5d0a774178d8bd3b0fd1ff2725dfeb61b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 00:33:28 +0100 Subject: [PATCH 05/65] Hide "Full" option from counter flow directions --- .../Gameplay/TestSceneJudgementCounter.cs | 4 +- .../JudgementCounterDisplay.cs | 39 ++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 885b182a6f..1cded54b3e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -97,8 +97,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestChangeFlowDirection() { - AddStep("Set direction vertical", () => counter.Direction.Value = FillDirection.Vertical); - AddStep("Set direction horizontal", () => counter.Direction.Value = FillDirection.Vertical); + AddStep("Set direction vertical", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); + AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizonal); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index b392ce8e04..3ac9e7fc55 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public bool UsesFixedAnchor { get; set; } [SettingSource("Counter direction")] - public Bindable Direction { get; set; } = new Bindable(); + public Bindable FlowDirection { get; set; } = new Bindable(); [SettingSource("Show judgement names")] public BindableBool ShowName { get; set; } = new BindableBool(true); @@ -40,7 +40,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { InternalChild = JudgementContainer = new FillFlowContainer { - Direction = Direction.Value, + Direction = getFlow(FlowDirection.Value), Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; @@ -61,9 +61,17 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { base.LoadComplete(); - Direction.BindValueChanged(direction => JudgementContainer.Direction = direction.NewValue); - Mode.BindValueChanged(_ => updateCounter(), true); + FlowDirection.BindValueChanged(direction => + { + JudgementContainer.Direction = getFlow(direction.NewValue); + //Can't pass directly due to Enum conversion + foreach (var counter in JudgementContainer.Children.OfType()) + { + counter.Direction.Value = getFlow(direction.NewValue); + } + }); + Mode.BindValueChanged(_ => updateCounter(), true); ShowMax.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); @@ -113,6 +121,28 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } + private FillDirection getFlow(Flow flow) + { + switch (flow) + { + case Flow.Horizonal: + return FillDirection.Horizontal; + + case Flow.Vertical: + return FillDirection.Vertical; + + default: + throw new ArgumentOutOfRangeException(nameof(flow), flow, @"Unsupported direction"); + } + } + + //Used to hide default full option in FillDirection + public enum Flow + { + Horizonal, + Vertical + } + public enum DisplayMode { Simple, @@ -125,7 +155,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter JudgementCounter counter = new JudgementCounter(info) { ShowName = { BindTarget = ShowName }, - Direction = { BindTarget = Direction } }; return counter; } From f0c780f1f648860c83584aabf28063f7386b856a Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 00:48:35 +0100 Subject: [PATCH 06/65] Fix tally header --- osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index 9cbeea7a2a..e11b09d5a7 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -1,6 +1,3 @@ - - - // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. From 58bf081096c0c7dbb1ee72cd4de8c7f022db7ca1 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 10:52:55 +0100 Subject: [PATCH 07/65] Fix judgement counter not loading after first attempt in gameplay, Fix typo in Display --- .../Gameplay/TestSceneJudgementCounter.cs | 2 +- .../JudgementCounterDisplay.cs | 28 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 1cded54b3e..b3e6fefb68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestChangeFlowDirection() { AddStep("Set direction vertical", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); - AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizonal); + AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 3ac9e7fc55..b8e3c97bb5 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -33,32 +33,28 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer = null!; + protected FillFlowContainer JudgementContainer; - [BackgroundDependencyLoader] - private void load() + public JudgementCounterDisplay() { + AutoSizeAxes = Axes.Both; InternalChild = JudgementContainer = new FillFlowContainer { Direction = getFlow(FlowDirection.Value), Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; - - foreach (var result in tally.Results) - { - JudgementContainer.Add(createCounter(result)); - } - } - - protected override void Update() - { - Size = JudgementContainer.Size; - base.Update(); } protected override void LoadComplete() { + //Adding this in "load" will cause it to not load in properly after the first beatmap attempt. Or after existing and reentering. + //this does not happen in tests, or in the skin editor component preview button. + foreach (var result in tally.Results) + { + JudgementContainer.Add(createCounter(result)); + } + base.LoadComplete(); FlowDirection.BindValueChanged(direction => @@ -125,7 +121,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { switch (flow) { - case Flow.Horizonal: + case Flow.Horizontal: return FillDirection.Horizontal; case Flow.Vertical: @@ -139,7 +135,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter //Used to hide default full option in FillDirection public enum Flow { - Horizonal, + Horizontal, Vertical } From 4d592184ca585119343806486573497d6c841aec Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 11:53:07 +0100 Subject: [PATCH 08/65] temp cmt --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 7 +++++-- .../Play/HUD/JudgementCounter/JudgementCounter.cs | 5 +++-- .../Play/HUD/JudgementCounter/JudgementTally.cs | 11 ++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index b3e6fefb68..2e35e012f7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -34,13 +34,16 @@ namespace osu.Game.Tests.Visual.Gameplay { var ruleset = CreateRuleset(); + var r = ruleset.CreateBeatmapConverter(Beatmap.Value.Beatmap); + + var n = r.Convert().BeatmapInfo.Ruleset.CreateInstance(); Debug.Assert(ruleset != null); - scoreProcessor = new ScoreProcessor(ruleset); + scoreProcessor = new ScoreProcessor(n); Child = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, - CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, + CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), n) }, Children = new Drawable[] { judgementTally = new JudgementTally(), diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index d7bb8939e1..16cbfd6c7a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.JudgementCounter { @@ -29,7 +30,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private JudgementRollingCounter counter = null!; [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, DrawableRuleset ruleset) { AutoSizeAxes = Axes.Both; InternalChild = flowContainer = new FillFlowContainer @@ -44,7 +45,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter ResultName = new OsuSpriteText { Font = OsuFont.Numeric.With(size: 8), - Text = Result.ResultInfo.Displayname + Text = ruleset.Ruleset.GetDisplayNameForHitResult(Result.ResultInfo.Type) } } }; diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index e11b09d5a7..b03f71a579 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter @@ -21,7 +22,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [BackgroundDependencyLoader] private void load(IBindable working) { - foreach (var result in working.Value.BeatmapInfo.Ruleset.CreateInstance().GetHitResults()) + foreach (var result in getRuleset(working).GetHitResults()) { Results.Add(new JudgementCounterInfo { @@ -31,6 +32,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } + private Ruleset getRuleset(IBindable working) + { + var ruleset = working.Value.BeatmapInfo.Ruleset.CreateInstance(); + var converter = ruleset.RulesetInfo.CreateInstance().CreateBeatmapConverter(working.Value.Beatmap); + + return converter.CanConvert() ? converter.Convert().BeatmapInfo.Ruleset.CreateInstance() : ruleset; + } + protected override void LoadComplete() { base.LoadComplete(); From 8efe7528e3266d08575cf2985ecfd76647e9949e Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 15:10:10 +0100 Subject: [PATCH 09/65] change ruleset source to avoid issues with converted beatmaps --- .../Gameplay/TestSceneJudgementCounter.cs | 9 +++------ .../HUD/JudgementCounter/JudgementCounter.cs | 10 +++++----- .../JudgementCounterDisplay.cs | 12 ++++++------ .../JudgementCounter/JudgementCounterInfo.cs | 3 +-- .../HUD/JudgementCounter/JudgementTally.cs | 19 +++++-------------- 5 files changed, 20 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 2e35e012f7..7a54f47c46 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -34,16 +34,13 @@ namespace osu.Game.Tests.Visual.Gameplay { var ruleset = CreateRuleset(); - var r = ruleset.CreateBeatmapConverter(Beatmap.Value.Beatmap); - - var n = r.Convert().BeatmapInfo.Ruleset.CreateInstance(); Debug.Assert(ruleset != null); - scoreProcessor = new ScoreProcessor(n); + scoreProcessor = new ScoreProcessor(ruleset); Child = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, - CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), n) }, + CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, Children = new Drawable[] { judgementTally = new JudgementTally(), @@ -130,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay private int hiddenCount() { - var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.ResultInfo.Type == HitResult.LargeTickHit); + var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 16cbfd6c7a..a4ebd80e9f 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -8,8 +8,8 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.JudgementCounter { @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private JudgementRollingCounter counter = null!; [BackgroundDependencyLoader] - private void load(OsuColour colours, DrawableRuleset ruleset) + private void load(OsuColour colours, IBindable ruleset) { AutoSizeAxes = Axes.Both; InternalChild = flowContainer = new FillFlowContainer @@ -45,16 +45,16 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter ResultName = new OsuSpriteText { Font = OsuFont.Numeric.With(size: 8), - Text = ruleset.Ruleset.GetDisplayNameForHitResult(Result.ResultInfo.Type) + Text = ruleset.Value.CreateInstance().GetDisplayNameForHitResult(Result.Type) } } }; - var result = Result.ResultInfo.Type; + var result = Result.Type; if (result.IsBasic()) { - Colour = colours.ForHitResult(Result.ResultInfo.Type); + Colour = colours.ForHitResult(Result.Type); return; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index b8e3c97bb5..bcbf8198fb 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter protected override void LoadComplete() { - //Adding this in "load" will cause it to not load in properly after the first beatmap attempt. Or after existing and reentering. + //Adding this in "load" will cause the component to not load in properly after the first beatmap attempt. Or after existing and reentering. //this does not happen in tests, or in the skin editor component preview button. foreach (var result in tally.Results) { @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { counter.Direction.Value = getFlow(direction.NewValue); } - }); + }, true); Mode.BindValueChanged(_ => updateCounter(), true); ShowMax.BindValueChanged(value => { @@ -89,19 +89,19 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter switch (Mode.Value) { case DisplayMode.Simple: - foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBasic())) + foreach (var counter in counters.Where(counter => counter.Result.Type.IsBasic())) counter.Show(); - foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBasic())) + foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBasic())) counter.Hide(); break; case DisplayMode.Normal: - foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBonus())) + foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBonus())) counter.Show(); - foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBonus())) + foreach (var counter in counters.Where(counter => counter.Result.Type.IsBonus())) counter.Hide(); break; diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs index 45f89c30d2..0237981db1 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs @@ -2,14 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; -using osu.Framework.Localisation; using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter { public struct JudgementCounterInfo { - public (HitResult Type, LocalisableString Displayname) ResultInfo { get; set; } + public HitResult Type { get; set; } public BindableInt ResultCount { get; set; } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index b03f71a579..a88b18ff6f 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; @@ -20,39 +19,31 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public List Results = new List(); [BackgroundDependencyLoader] - private void load(IBindable working) + private void load(IBindable ruleset) { - foreach (var result in getRuleset(working).GetHitResults()) + foreach (var result in ruleset.Value.CreateInstance().GetHitResults()) { Results.Add(new JudgementCounterInfo { - ResultInfo = (result.result, result.displayName), + Type = result.result, ResultCount = new BindableInt() }); } } - private Ruleset getRuleset(IBindable working) - { - var ruleset = working.Value.BeatmapInfo.Ruleset.CreateInstance(); - var converter = ruleset.RulesetInfo.CreateInstance().CreateBeatmapConverter(working.Value.Beatmap); - - return converter.CanConvert() ? converter.Convert().BeatmapInfo.Ruleset.CreateInstance() : ruleset; - } - protected override void LoadComplete() { base.LoadComplete(); scoreProcessor.NewJudgement += judgement => { - foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) { result.ResultCount.Value++; } }; scoreProcessor.JudgementReverted += judgement => { - foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) { result.ResultCount.Value--; } From 99d83315c11a946472f9dbeb001f55ad74970b2f Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 15:10:45 +0100 Subject: [PATCH 10/65] change settings order --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index bcbf8198fb..4880314f29 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -18,6 +18,9 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { public bool UsesFixedAnchor { get; set; } + [SettingSource("Display mode")] + public Bindable Mode { get; set; } = new Bindable(); + [SettingSource("Counter direction")] public Bindable FlowDirection { get; set; } = new Bindable(); @@ -27,9 +30,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [SettingSource("Show max judgement")] public BindableBool ShowMax { get; set; } = new BindableBool(true); - [SettingSource("Display mode")] - public Bindable Mode { get; set; } = new Bindable(); - [Resolved] private JudgementTally tally { get; set; } = null!; From edb46e422c20983ae9599a394244c01787282806 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 15:15:30 +0100 Subject: [PATCH 11/65] Fix "using" name in HUD overlay --- 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 816b8b2543..89d02e5fb0 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,7 +24,7 @@ using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osu.Game.Skinning; using osuTK; -using JudgementTally = osu.Game.Screens.Play.HUD.JudgementCounter.JudgementTally; +using osu.Game.Screens.Play.HUD.JudgementCounter; namespace osu.Game.Screens.Play { From 9a235b32133e45827f71533cd86e799ca66155bb Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Wed, 14 Dec 2022 23:00:34 +0100 Subject: [PATCH 12/65] remove rolling duration, fix issue with loading --- .../Play/HUD/JudgementCounter/JudgementCounter.cs | 2 -- .../HUD/JudgementCounter/JudgementCounterDisplay.cs | 13 ++++++------- .../Play/HUD/JudgementCounter/JudgementTally.cs | 6 ++---- osu.Game/Screens/Play/HUDOverlay.cs | 3 ++- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index a4ebd80e9f..3f7dbefcd1 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -112,8 +112,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true, size: 16)); - - protected override double RollingDuration => 750; } } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 4880314f29..36466fa8a9 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -33,9 +33,10 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer; + protected FillFlowContainer JudgementContainer = null!; - public JudgementCounterDisplay() + [BackgroundDependencyLoader] + private void load() { AutoSizeAxes = Axes.Both; InternalChild = JudgementContainer = new FillFlowContainer @@ -44,17 +45,15 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; - } - protected override void LoadComplete() - { - //Adding this in "load" will cause the component to not load in properly after the first beatmap attempt. Or after existing and reentering. - //this does not happen in tests, or in the skin editor component preview button. foreach (var result in tally.Results) { JudgementContainer.Add(createCounter(result)); } + } + protected override void LoadComplete() + { base.LoadComplete(); FlowDirection.BindValueChanged(direction => diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index a88b18ff6f..e6bc336b0b 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -34,19 +34,17 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter protected override void LoadComplete() { base.LoadComplete(); + scoreProcessor.NewJudgement += judgement => { foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) - { result.ResultCount.Value++; - } }; + scoreProcessor.JudgementReverted += judgement => { foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) - { result.ResultCount.Value--; - } }; } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 89d02e5fb0..728da22123 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -107,6 +107,8 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { CreateFailingLayer(), + //Needs to be initialized before skinnable drawables. + tally = new JudgementTally(), mainComponents = new MainComponentsContainer { AlwaysPresent = true, @@ -150,7 +152,6 @@ namespace osu.Game.Screens.Play Spacing = new Vector2(5) }, clicksPerSecondCalculator = new ClicksPerSecondCalculator(), - tally = new JudgementTally() }; hideTargets = new List { mainComponents, KeyCounter, topRightElements }; From 0c177aa7dedb51352da4de6f5fd1d239a51a8331 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 15 Dec 2022 16:12:34 +0100 Subject: [PATCH 13/65] Improve tests, simplify "updateDisplay" method --- .../Gameplay/TestSceneJudgementCounter.cs | 38 ++++++++------ .../HUD/JudgementCounter/JudgementCounter.cs | 2 +- .../JudgementCounterDisplay.cs | 50 +++++++++---------- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 7a54f47c46..1d79d8e408 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private ScoreProcessor scoreProcessor = null!; private JudgementTally judgementTally = null!; - private TestJudgementCounterDisplay counter = null!; + private TestJudgementCounterDisplay counterDisplay = null!; private readonly Bindable lastJudgementResult = new Bindable(); @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.Gameplay { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(JudgementTally), judgementTally) }, - Child = counter = new TestJudgementCounterDisplay + Child = counterDisplay = new TestJudgementCounterDisplay { Margin = new MarginPadding { Top = 100 }, Anchor = Anchor.TopCentre, @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); - AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); } @@ -91,43 +91,49 @@ namespace osu.Game.Tests.Visual.Gameplay { AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); - AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); } [Test] public void TestChangeFlowDirection() { - AddStep("Set direction vertical", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); - AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); + AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); + AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); } [Test] public void TestToggleJudgementNames() { - AddStep("Hide judgement names", () => counter.ShowName.Value = false); - AddAssert("Assert hidden", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); - AddStep("Hide judgement names", () => counter.ShowName.Value = true); - AddAssert("Assert shown", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); + AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = false); + AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); + AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = true); + AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } [Test] public void TestHideMaxValue() { - AddStep("Hide max judgement", () => counter.ShowMax.Value = false); - AddStep("Show max judgement", () => counter.ShowMax.Value = true); + AddStep("Hide max judgement", () => counterDisplay.ShowMax.Value = false); + AddWaitStep("wait some", 2); + AddAssert("Check max hidden", () => counterDisplay.JudgementContainer.ChildrenOfType().First().Alpha == 0); + AddStep("Show max judgement", () => counterDisplay.ShowMax.Value = true); } [Test] public void TestCycleDisplayModes() { - AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); - AddStep("Show normal judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); - AddStep("Show basic judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); + AddStep("Show basic judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); + AddWaitStep("wait some", 2); + AddAssert("Check only basic", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 0); + AddStep("Show normal judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddWaitStep("wait some", 2); + AddAssert("Check all visible", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 1); } private int hiddenCount() { - var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); + var num = counterDisplay.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 3f7dbefcd1..efb4c532f9 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter protected override void PopIn() { - this.FadeInFromZero(500, Easing.OutQuint); + this.FadeIn(500, Easing.OutQuint); } protected override void PopOut() diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 36466fa8a9..1842ba1eae 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter counter.Direction.Value = getFlow(direction.NewValue); } }, true); - Mode.BindValueChanged(_ => updateCounter(), true); + Mode.BindValueChanged(_ => updateMode(), true); ShowMax.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); @@ -81,38 +81,35 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }, true); } - private void updateCounter() + private void updateMode() { - var counters = JudgementContainer.Children.OfType().ToList(); - - switch (Mode.Value) + foreach (var counter in JudgementContainer.Children.OfType().Where(counter => !counter.Result.Type.IsBasic())) { - case DisplayMode.Simple: - foreach (var counter in counters.Where(counter => counter.Result.Type.IsBasic())) - counter.Show(); - - foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBasic())) + switch (Mode.Value) + { + case DisplayMode.Simple: counter.Hide(); - break; + break; - case DisplayMode.Normal: - foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBonus())) + case DisplayMode.Normal: + if (counter.Result.Type.IsBonus()) + { + counter.Hide(); + break; + } + + counter.Show(); + break; + + case DisplayMode.All: counter.Show(); - foreach (var counter in counters.Where(counter => counter.Result.Type.IsBonus())) - counter.Hide(); + break; - break; - - case DisplayMode.All: - foreach (JudgementCounter counter in counters.Where(counter => !counter.IsPresent)) - counter.Show(); - - break; - - default: - throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); + } } } @@ -149,7 +146,8 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { JudgementCounter counter = new JudgementCounter(info) { - ShowName = { BindTarget = ShowName }, + State = { Value = Visibility.Visible }, + ShowName = { BindTarget = ShowName } }; return counter; } From f3873b73e3290d338cc3e1348e3588a23d242c47 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 16 Dec 2022 17:40:39 +0100 Subject: [PATCH 14/65] Clean up syntax for readability --- .../Gameplay/TestSceneJudgementCounter.cs | 5 +- .../HUD/JudgementCounter/JudgementCounter.cs | 49 +++---------------- .../JudgementCounterDisplay.cs | 24 ++------- .../HUD/JudgementCounter/JudgementTally.cs | 18 +++---- 4 files changed, 19 insertions(+), 77 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 1d79d8e408..a8d9f203ae 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -81,9 +81,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Great), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); - AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); - AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); - AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); } [Test] @@ -105,8 +102,10 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestToggleJudgementNames() { AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = false); + AddWaitStep("wait some", 2); AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = true); + AddWaitStep("wait some", 2); AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index efb4c532f9..ea6e9997e3 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -20,10 +20,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public readonly JudgementCounterInfo Result; - public JudgementCounter(JudgementCounterInfo result) - { - Result = result; - } + public JudgementCounter(JudgementCounterInfo result) => Result = result; public OsuSpriteText ResultName = null!; private FillFlowContainer flowContainer = null!; @@ -52,45 +49,18 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter var result = Result.Type; - if (result.IsBasic()) - { - Colour = colours.ForHitResult(Result.Type); - return; - } - - if (!result.IsBonus()) - { - Colour = colours.PurpleLight; - return; - } - - Colour = colours.PurpleLighter; + Colour = result.IsBasic() ? colours.ForHitResult(Result.Type) : !result.IsBonus() ? colours.PurpleLight : colours.PurpleLighter; } protected override void LoadComplete() { ShowName.BindValueChanged(value => - { - if (value.NewValue) - { - ResultName.Show(); - return; - } - - ResultName.Hide(); - }, true); + ResultName.FadeTo(value.NewValue ? 1 : 0, JudgementCounterDisplay.TRANSFORM_DURATION, Easing.OutQuint), true); Direction.BindValueChanged(direction => { flowContainer.Direction = direction.NewValue; - - if (direction.NewValue == FillDirection.Vertical) - { - changeAnchor(Anchor.TopLeft); - return; - } - - changeAnchor(Anchor.BottomLeft); + changeAnchor(direction.NewValue == FillDirection.Vertical ? Anchor.TopLeft : Anchor.BottomLeft); void changeAnchor(Anchor anchor) => counter.Anchor = ResultName.Anchor = counter.Origin = ResultName.Origin = anchor; }, true); @@ -98,15 +68,8 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter base.LoadComplete(); } - protected override void PopIn() - { - this.FadeIn(500, Easing.OutQuint); - } - - protected override void PopOut() - { - this.FadeOut(100); - } + protected override void PopIn() => this.FadeIn(JudgementCounterDisplay.TRANSFORM_DURATION, Easing.OutQuint); + protected override void PopOut() => this.FadeOut(100); private sealed partial class JudgementRollingCounter : RollingCounter { diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 1842ba1eae..4e2b2a10cd 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -16,6 +16,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable { + public const int TRANSFORM_DURATION = 500; public bool UsesFixedAnchor { get; set; } [SettingSource("Display mode")] @@ -47,9 +48,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }; foreach (var result in tally.Results) - { JudgementContainer.Add(createCounter(result)); - } } protected override void LoadComplete() @@ -62,22 +61,13 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter //Can't pass directly due to Enum conversion foreach (var counter in JudgementContainer.Children.OfType()) - { counter.Direction.Value = getFlow(direction.NewValue); - } }, true); Mode.BindValueChanged(_ => updateMode(), true); ShowMax.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); - - if (value.NewValue) - { - firstChild?.Show(); - return; - } - - firstChild?.Hide(); + firstChild.FadeTo(value.NewValue ? 1 : 0, TRANSFORM_DURATION, Easing.OutQuint); }, true); } @@ -89,22 +79,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { case DisplayMode.Simple: counter.Hide(); - break; case DisplayMode.Normal: - if (counter.Result.Type.IsBonus()) - { - counter.Hide(); - break; - } - - counter.Show(); + counter.FadeTo(counter.Result.Type.IsBonus() ? 0 : 1); break; case DisplayMode.All: counter.Show(); - break; default: diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index e6bc336b0b..d8eac309aa 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter @@ -35,17 +36,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { base.LoadComplete(); - scoreProcessor.NewJudgement += judgement => - { - foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) - result.ResultCount.Value++; - }; + scoreProcessor.NewJudgement += judgement => updateCount(judgement, false); + scoreProcessor.JudgementReverted += judgement => updateCount(judgement, true); + } - scoreProcessor.JudgementReverted += judgement => - { - foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) - result.ResultCount.Value--; - }; + private void updateCount(JudgementResult judgement, bool revert) + { + foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) + result.ResultCount.Value = revert ? result.ResultCount.Value - 1 : result.ResultCount.Value + 1; } } } From c200e7799418a2ca7c83b3e7f821918227eec845 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 19 Dec 2022 18:31:28 -0500 Subject: [PATCH 15/65] Add mania hidden mod configuration --- .../Mods/TestSceneManiaModHidden.cs | 19 +++++++++++++++++++ .../Mods/ManiaModHidden.cs | 12 ++++++++++++ .../Mods/ManiaModPlayfieldCover.cs | 4 +++- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs new file mode 100644 index 0000000000..65ee43dfaf --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.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 NUnit.Framework; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests.Mods +{ + public partial class TestSceneManiaModHidden : ModTestScene + { + protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + + [TestCase(0.5f)] + [TestCase(0.2f)] + [TestCase(0.8f)] + public void TestCoverage(float Coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = Coverage } }, PassCondition = () => true }); + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index eeb6e94fc7..5dcb859f7a 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -4,7 +4,9 @@ using System; using System.Linq; using osu.Framework.Localisation; +using osu.Game.Configuration; using osu.Game.Rulesets.Mania.UI; +using osu.Framework.Bindables; namespace osu.Game.Rulesets.Mania.Mods { @@ -13,6 +15,16 @@ namespace osu.Game.Rulesets.Mania.Mods public override LocalisableString Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; + [SettingSource("Coverage", "How much of the playfield notes should be hidden for.")] + public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) + { + Precision = 0.01f, + MinValue = 0.2f, + MaxValue = 0.8f, + Default = 0.5f, + }; + public override float Coverage => CoverageAmount.Value; + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray(); protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 6a94e5d371..635ad1f2e8 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } + public virtual float Coverage {get => 0.5f;} + public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { ManiaPlayfield maniaPlayfield = (ManiaPlayfield)drawableRuleset.Playfield; @@ -36,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Mods { c.RelativeSizeAxes = Axes.Both; c.Direction = ExpandDirection; - c.Coverage = 0.5f; + c.Coverage = Coverage; })); } } From 42dbb0bfd077bfa0240f81193a302d884018cbd2 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 19 Dec 2022 19:24:38 -0500 Subject: [PATCH 16/65] fix formatting --- osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 635ad1f2e8..5e9c1a4ae7 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } - public virtual float Coverage {get => 0.5f;} + public virtual float Coverage { get => 0.5f; } public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { From 4a1a023f9e7ca7a68841f1558cfa55dcb3a25cee Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Tue, 20 Dec 2022 13:33:33 -0500 Subject: [PATCH 17/65] Code quality improvements --- .../Mods/TestSceneManiaModHidden.cs | 2 +- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 5 +++-- osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs index 65ee43dfaf..44d206d9e1 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods [TestCase(0.5f)] [TestCase(0.2f)] [TestCase(0.8f)] - public void TestCoverage(float Coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = Coverage } }, PassCondition = () => true }); + public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = coverage } }, PassCondition = () => true }); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 5dcb859f7a..76a102bda3 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override LocalisableString Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; - [SettingSource("Coverage", "How much of the playfield notes should be hidden for.")] + [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) { Precision = 0.01f, @@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Mania.Mods MaxValue = 0.8f, Default = 0.5f, }; - public override float Coverage => CoverageAmount.Value; + + protected override float Coverage => CoverageAmount.Value; public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray(); diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 5e9c1a4ae7..bfb70938b9 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } - public virtual float Coverage { get => 0.5f; } + protected virtual float Coverage => 0.5f; public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { From b8fbd68e325018606a5b2de181c0d64a7f0a9c16 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Fri, 6 Jan 2023 11:39:41 -0500 Subject: [PATCH 18/65] reduce mania hidden mod precision --- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 76a102bda3..2eb9e6d1eb 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) { - Precision = 0.01f, + Precision = 0.1f, MinValue = 0.2f, MaxValue = 0.8f, Default = 0.5f, From 768a33bb64a5fef23201c5224bd53336eb80e133 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 23:31:19 +0300 Subject: [PATCH 19/65] Add request class --- .../Online/API/Requests/CommentPostRequest.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 osu.Game/Online/API/Requests/CommentPostRequest.cs diff --git a/osu.Game/Online/API/Requests/CommentPostRequest.cs b/osu.Game/Online/API/Requests/CommentPostRequest.cs new file mode 100644 index 0000000000..bd69c04bed --- /dev/null +++ b/osu.Game/Online/API/Requests/CommentPostRequest.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class CommentPostRequest : APIRequest + { + public readonly CommentableType Commentable; + public readonly long CommentableId; + public readonly string Message; + public readonly long? ReplyTo; + + public CommentPostRequest(CommentableType commentable, long commentableId, string message, long? replyTo = null) + { + Commentable = commentable; + CommentableId = commentableId; + Message = message; + ReplyTo = replyTo; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + + req.AddParameter(@"comment[commentable_type]", Commentable.ToString()); + req.AddParameter(@"comment[commentable_id]", $"{CommentableId}"); + req.AddParameter(@"comment[message]", Message); + if (ReplyTo.HasValue) + req.AddParameter(@"comment[parent_id]", $"{ReplyTo}"); + + return req; + } + + protected override string Target => "comments"; + } +} From 32e90829e3d0b2df4241ecf9f419446a4d42d587 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 02:59:24 +0300 Subject: [PATCH 20/65] Integrate comment editor into container --- .../Overlays/Comments/CommentsContainer.cs | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 7bd2d6a5e6..c8a2ab39ae 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -17,15 +17,23 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Threading; using System.Collections.Generic; using JetBrains.Annotations; +using osu.Framework.Localisation; using osu.Game.Graphics.Sprites; using osu.Game.Resources.Localisation.Web; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; +using osu.Game.Users.Drawables; +using osuTK; namespace osu.Game.Overlays.Comments { + [Cached] public partial class CommentsContainer : CompositeDrawable { + private const string cid = "commentableId"; + + [Cached] private readonly Bindable type = new Bindable(); + + [Cached(name: cid)] private readonly BindableLong id = new BindableLong(); public readonly Bindable Sort = new Bindable(); @@ -46,12 +54,14 @@ namespace osu.Game.Overlays.Comments private DeletedCommentsCounter deletedCommentsCounter; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; + private UpdateableAvatar avatar; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + AddRangeInternal(new Drawable[] { new Box @@ -86,6 +96,29 @@ namespace osu.Game.Overlays.Comments }, }, }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 50, Vertical = 20 }, + Children = new Drawable[] + { + avatar = new UpdateableAvatar(api.LocalUser.Value) + { + Size = new Vector2(50), + CornerExponent = 2, + CornerRadius = 25, + Masking = true, + }, + new Container + { + Padding = new MarginPadding { Left = 60 }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = new NewCommentEditor() + } + } + }, new CommentsHeader { Sort = { BindTarget = Sort }, @@ -146,6 +179,7 @@ namespace osu.Game.Overlays.Comments }); User.BindTo(api.LocalUser); + User.BindValueChanged(e => avatar.User = e.NewValue); } protected override void LoadComplete() @@ -336,5 +370,37 @@ namespace osu.Game.Overlays.Comments }); } } + + private partial class NewCommentEditor : CommentEditor + { + [Resolved] + public Bindable CommentableType { get; set; } + + [Resolved(name: cid)] + public BindableLong CommentableId { get; set; } + + protected override LocalisableString FooterText => default; + protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; + protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderNew; + + [Resolved] + private IAPIProvider api { get; set; } + + protected override void OnCommit(string text) + { + CommitButton.IsLoadingSpinnerShown = true; + CommentPostRequest req = new CommentPostRequest(CommentableType.Value, CommentableId.Value, text); + req.Failure += _ => Schedule(() => + { + CommitButton.IsLoadingSpinnerShown = false; + }); + req.Success += cb => Schedule(() => + { + CommitButton.IsLoadingSpinnerShown = false; + Current.Value = string.Empty; + }); + api.Queue(req); + } + } } } From 58bf7349eea9cd4a3600f7c71ca6968feb85e776 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 02:59:32 +0300 Subject: [PATCH 21/65] Fix request --- osu.Game/Online/API/Requests/CommentPostRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/CommentPostRequest.cs b/osu.Game/Online/API/Requests/CommentPostRequest.cs index bd69c04bed..7012d479bd 100644 --- a/osu.Game/Online/API/Requests/CommentPostRequest.cs +++ b/osu.Game/Online/API/Requests/CommentPostRequest.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.API.Requests var req = base.CreateWebRequest(); req.Method = HttpMethod.Post; - req.AddParameter(@"comment[commentable_type]", Commentable.ToString()); + req.AddParameter(@"comment[commentable_type]", Commentable.ToString().ToLowerInvariant()); req.AddParameter(@"comment[commentable_id]", $"{CommentableId}"); req.AddParameter(@"comment[message]", Message); if (ReplyTo.HasValue) From 927773d56584c1b288642a3b143ef118d6ce4d65 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 04:15:43 +0300 Subject: [PATCH 22/65] Display submitted comments locally --- .../Overlays/Comments/CommentsContainer.cs | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index c8a2ab39ae..98c186b273 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Game.Online.API; @@ -115,7 +116,10 @@ namespace osu.Game.Overlays.Comments Padding = new MarginPadding { Left = 60 }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = new NewCommentEditor() + Child = new NewCommentEditor + { + OnPost = prependPostedComments + } } } }, @@ -279,7 +283,6 @@ namespace osu.Game.Overlays.Comments { pinnedContent.AddRange(loaded.Where(d => d.Comment.Pinned)); content.AddRange(loaded.Where(d => !d.Comment.Pinned)); - deletedCommentsCounter.Count.Value += topLevelComments.Select(d => d.Comment).Count(c => c.IsDeleted && c.IsTopLevel); if (bundle.HasMore) @@ -322,6 +325,42 @@ namespace osu.Game.Overlays.Comments } } + private void prependPostedComments(CommentBundle bundle) + { + var topLevelComments = new List(); + + foreach (var comment in bundle.Comments) + { + // Exclude possible duplicated comments. + if (CommentDictionary.ContainsKey(comment.Id)) + continue; + + topLevelComments.Add(getDrawableComment(comment)); + } + + if (topLevelComments.Any()) + { + LoadComponentsAsync(topLevelComments, loaded => + { + if (content[0] is NoCommentsPlaceholder placeholder) + content.Remove(placeholder, true); + + foreach (var comment in loaded) + { + int pos = -1; + + if (content.Count > 0) + { + var first = content.FlowingChildren.First(); + pos = (int)(content.GetLayoutPosition(first) - 1); + } + + content.Insert(pos, comment); + } + }, (loadCancellation = new CancellationTokenSource()).Token); + } + } + private DrawableComment getDrawableComment(Comment comment) { if (CommentDictionary.TryGetValue(comment.Id, out var existing)) @@ -386,6 +425,8 @@ namespace osu.Game.Overlays.Comments [Resolved] private IAPIProvider api { get; set; } + public Action OnPost; + protected override void OnCommit(string text) { CommitButton.IsLoadingSpinnerShown = true; @@ -398,6 +439,7 @@ namespace osu.Game.Overlays.Comments { CommitButton.IsLoadingSpinnerShown = false; Current.Value = string.Empty; + OnPost?.Invoke(cb); }); api.Queue(req); } From 49ce50878d2c761fcc0a43132cf1669f9966d687 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 04:15:53 +0300 Subject: [PATCH 23/65] Add simple test --- .../Online/TestSceneCommentsContainer.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 291ccd634d..86a574cf77 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -11,7 +11,11 @@ using osu.Game.Overlays; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; +using osu.Framework.Utils; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -126,6 +130,24 @@ namespace osu.Game.Tests.Visual.Online commentsContainer.ChildrenOfType().Count(d => d.Comment.Pinned == withPinned) == 1); } + [TestCase] + public void TestPost() + { + setUpCommentsResponse(getExampleComments()); + AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123)); + setUpPostResponse(); + AddStep("Enter text", () => this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value = "comm"); + AddStep("Submit", () => this.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); + AddUntilStep("Comment sent", () => + { + var text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; + return this.ChildrenOfType().Any(x => + { + return x.ChildrenOfType().Any(y => y.Text == text); + }); + }); + } + private void setUpCommentsResponse(CommentBundle commentBundle) => AddStep("set up response", () => { @@ -139,6 +161,32 @@ namespace osu.Game.Tests.Visual.Online }; }); + private void setUpPostResponse() + => AddStep("set up response", () => + { + dummyAPI.HandleRequest = request => + { + if (!(request is CommentPostRequest req)) + return false; + + req.TriggerSuccess(new CommentBundle + { + Comments = new List + { + new Comment + { + Id = 98, + Message = req.Message, + LegacyName = "FirstUser", + CreatedAt = DateTimeOffset.Now, + VotesCount = 98, + } + } + }); + return true; + }; + }); + private CommentBundle getExampleComments(bool withPinned = false) { var bundle = new CommentBundle From 4baa2670953b4c201f5d70b64149fd6cb064d86d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 04:26:52 +0300 Subject: [PATCH 24/65] warnings --- osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 86a574cf77..e58423241b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; -using osu.Framework.Utils; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -140,7 +139,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Submit", () => this.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); AddUntilStep("Comment sent", () => { - var text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; + string text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; return this.ChildrenOfType().Any(x => { return x.ChildrenOfType().Any(y => y.Text == text); @@ -187,7 +186,7 @@ namespace osu.Game.Tests.Visual.Online }; }); - private CommentBundle getExampleComments(bool withPinned = false) + private static CommentBundle getExampleComments(bool withPinned = false) { var bundle = new CommentBundle { From efded323e4818172add38612a149c8e8e91c4382 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:49:36 +0900 Subject: [PATCH 25/65] Rename variables and avoid the need for a property --- .../Mods/TestSceneManiaModHidden.cs | 2 +- osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs | 5 +++++ osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 4 +--- osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 5 +++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs index 44d206d9e1..204f26f151 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods [TestCase(0.5f)] [TestCase(0.2f)] [TestCase(0.8f)] - public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = coverage } }, PassCondition = () => true }); + public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { Coverage = { Value = coverage } }, PassCondition = () => true }); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs index c6e9c339f4..800973ede5 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Rulesets.Mania.UI; @@ -18,5 +19,9 @@ namespace osu.Game.Rulesets.Mania.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModHidden)).ToArray(); protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AlongScroll; + + // This could be customisable like ManiaModHidden in the future if there's any demand. + // At that point, the bindable could be moved to `ManiaModPlayfieldCover`. + public override BindableNumber Coverage { get; } = new BindableFloat(0.5f); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 2eb9e6d1eb..50d40249c1 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override double ScoreMultiplier => 1; [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] - public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) + public override BindableNumber Coverage { get; } = new BindableFloat(0.5f) { Precision = 0.1f, MinValue = 0.2f, @@ -24,8 +24,6 @@ namespace osu.Game.Rulesets.Mania.Mods Default = 0.5f, }; - protected override float Coverage => CoverageAmount.Value; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray(); protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index bfb70938b9..45d0184d1d 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Objects; @@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } - protected virtual float Coverage => 0.5f; + public abstract BindableNumber Coverage { get; } public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -38,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Mods { c.RelativeSizeAxes = Axes.Both; c.Direction = ExpandDirection; - c.Coverage = Coverage; + c.Coverage = Coverage.Value; })); } } From 621c75daed39de1713040bb12ece80c31586112d Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Wed, 11 Jan 2023 11:16:24 +0100 Subject: [PATCH 26/65] Add updated SkinDeserialisationTest.cs including BPM counter --- .../Archives/modified-default-20221211.osk | Bin 1650 -> 0 bytes .../Archives/modified-default-20230111.osk | Bin 0 -> 1685 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 3 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221211.osk create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20230111.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk deleted file mode 100644 index 07190db267cfcbf0abf44a5eb95b4e43bb0955d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1650 zcmWIWW@Zs#U|`^2__41$)V#A{#{nQOh#4fpz)+l>nWvYTm-)2cFptSlz_ogQ(hG;C zH@8F=E%uturR8F1usI>|yvx0fVRLj{`=)5Kh%9yb!m&$#@A~!s>-O!N%@*d~<`;ZP z@f71Xtz$_B3H%Yh#!+{Yz0w_&)Nagm{B6aw>S`{J3j_M*Aq3^;H=}T|8F6)dAv(Ab<5aqY1+2Z>O|HRMo z=|^O*rEI>?cH!LLn%^>Fr~Wd|K|=s@#Vyw=@NZF-`xgcUZ^iK^V0J5 zvWoNbO8Yi)9WoGc{a$y}IG8)v!$>ro{pF)YewP#{EU~$@&tcLdg@3!*&fa)i^sco! zPLyHyi>sTI4dk~oU(sB!EOX<=#;UJuvQd{0EIx8BV)=H}QZEhFs+;}Rb47yQmU*3; zxb^2Bku`pHPySnM)8007O90!Ns(J=g zhwp#q^9Xfu&d)8#&r8iKDF*xC?R4Ml#|8pz?|+J_rMsWl zm~))lvSjXE-romjEqlB4%K|N7_mGKQD$Zv&{jYs`jPJ6-FWs`BcD?Mo z>hJ};;YEEHA3v|2DIJqF!&_tRvP0iLeF`i1#=MHVl)XsLTk+Vxd)4cBw&!h&K3He# zS6$HCz>?8rs8+W+%#T;OMgDgE?3d3^T}rEZTcy8FLbM=h!`nO`R$1@#Nx4(kSx<8N zxwi6P_UTOJ7%7AJpUi9clg&dUGWIrYjS*W`c1P;$wwN`hSKQX+yY+7V|8!rHmvj7` zLiXT}c7?hCHmAB{5i2!U|5{{M>HAWy?eL*^CegCp51!pC{W9-^?UU+Ts&-!(7pF|j z4$Uxlru&KS@nn&HcBOq!zI9*o`p;CpM&irNSISRyFYy;l|L6E~!T*?Flb5U8SDOAP zz97A{JjCdP==5tmp;wL=7M1Jv-49HhY?)Sm%r$}4=Va;jyU`1slUx=}XpwEm6nUVb zc%H|jBgu!ObJ62hD?{h+GUW5RfAHr^y#xbW`wc-olOm_69JfB)IpfIX@-4>uroUz? zQ^DtQ)=Hi-THF6kzeb!+_4#F^7J1$uPry5p|;f1 zQSkropj>mUWReY~TlDD8rhZwUB}upTn8nIe8{If2()ak$1dF(o?Juq^sB5Wxb@_m8!|%4ok*}6K zT=BL4fr+ohoJ~S9Uz}eBZ9jZ#L0o%@#wDL=&$irW@K=rA7M6(ANZGIP>R}+Y)!F-u0p5&E zA`H08T3}>BKqH8PmAvS>(915U9tMWSXHZ@6k_=rddg+1CIvnWvYTm-%#pVHcC5fa_;F*O{6x z&iOPeq`A$`-6GxTn0YlLx%}#-;Ij{In%z*YWEC|uF%Uk>b?^D-c-jB|R&(tu=UIDf zMePLLoRFTQ3y$+`n4z|1!$ArD1{a?Vb`52z3?ZLX1r%tg$H=jzfa z7S2h|PKWuo|4Dh+Q}}e>xz3+kGcqg}Fztl?Zxw18LVI4+{A1kKV5c;=7MF3n>IETePff23O=ZN{8+^D>6)fq8mdt@@0rgK z3CcB6{Z=ozI((yE#N3*QyX#CQ)nC~DUQ^ANv((Ao*7E=6=f}?r*U3%f$b2yUPfBjq z3Ffdp_fVaFRMl)UHxmQHD?tVZF`(0Z6EpKXLS3Bma|`nGQu9iR!G3r<{e1py1(DFpBiq9J&s4Mh+D)-^lICapXoQ^Pgx5T2Tpx@#kS)7 zl4r-xZPT_`b3BWG+rvQqpAyNhw!ONyO2y&F#=o0q{_~Z(=CeLl{z&LKFAKvPW#-HF z%v)+aF@NbQ>qTxqS5+L$KJBR-lX*e@2lJZ#Wb-vwE>y85@6afDyTf!=UggfP0O_6k zW}2M)H|4k1bgs5XebqBKfxr~T)e zZ0(N2JESMieBNrNWhlAN;_qz7nRou6rTj*z`V-ZR3=9u|nVcV(e1h}y(t}fTQj<%- z>E>u~Y&J0M*M1LAseR{k>&xjzey!Vb$7Y<#(|_c=w%lxn+EPzP!T-O5a?Q1x4b3GL z`M;}JJ}>fnx2FBVxtx|Y710f)%{nW!YUV#_Se~uMBCKsQtx}PdW9*{uQF#K90v|~&1wXM$+UkS~>U~F7)>v7wKEAi6r zC)pS53%zt~$E~{&VVP|uY#OPlryOG=WxvL&f6>1zG)rHmC9phV5rg%!_0{RmTsFLC z&y%RQcXETw!w*f5KS@T#eQ=TYx! From 1f4e0303f733265aa574d21d648d1ec1e3a5fa41 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 11 Jan 2023 14:13:29 -0500 Subject: [PATCH 27/65] add mania FadeIn mod configuration --- osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs | 10 +++++++--- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs index 800973ede5..196514c7b1 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs @@ -20,8 +20,12 @@ namespace osu.Game.Rulesets.Mania.Mods protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AlongScroll; - // This could be customisable like ManiaModHidden in the future if there's any demand. - // At that point, the bindable could be moved to `ManiaModPlayfieldCover`. - public override BindableNumber Coverage { get; } = new BindableFloat(0.5f); + public override BindableNumber Coverage { get; } = new BindableFloat(0.5f) + { + Precision = 0.1f, + MinValue = 0.1f, + MaxValue = 0.7f, + Default = 0.5f, + }; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 50d40249c1..8f0d5a770e 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -15,7 +15,6 @@ namespace osu.Game.Rulesets.Mania.Mods public override LocalisableString Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; - [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public override BindableNumber Coverage { get; } = new BindableFloat(0.5f) { Precision = 0.1f, diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 45d0184d1d..09abe8d7f4 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; @@ -23,6 +24,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } + [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public abstract BindableNumber Coverage { get; } public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) From 4fce7f03bd48c2dbe091949a6c60fa4814d5b7a9 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 11 Jan 2023 14:14:17 -0500 Subject: [PATCH 28/65] add mania mod fadein test --- .../Mods/TestSceneManiaModFadeIn.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs new file mode 100644 index 0000000000..2c8c151e7f --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.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 NUnit.Framework; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests.Mods +{ + public partial class TestSceneManiaModFadeIn : ModTestScene + { + protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + + [TestCase(0.5f)] + [TestCase(0.1f)] + [TestCase(0.7f)] + public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModFadeIn { Coverage = { Value = coverage } }, PassCondition = () => true }); + } +} From e23c565c8418a31bd5746eb36f112983702f876c Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 11 Jan 2023 14:28:11 -0500 Subject: [PATCH 29/65] code quality --- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 8f0d5a770e..f23cb335a5 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using osu.Framework.Localisation; -using osu.Game.Configuration; using osu.Game.Rulesets.Mania.UI; using osu.Framework.Bindables; From 9e7ecbf4a14ebf97459677b128ef70528d0115e2 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:41:11 +0300 Subject: [PATCH 30/65] Adapt to changes in base class --- osu.Game/Overlays/Comments/CommentsContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 98c186b273..08542bbcea 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -429,15 +429,15 @@ namespace osu.Game.Overlays.Comments protected override void OnCommit(string text) { - CommitButton.IsLoadingSpinnerShown = true; + ShowLoadingSpinner = true; CommentPostRequest req = new CommentPostRequest(CommentableType.Value, CommentableId.Value, text); req.Failure += _ => Schedule(() => { - CommitButton.IsLoadingSpinnerShown = false; + ShowLoadingSpinner = false; }); req.Success += cb => Schedule(() => { - CommitButton.IsLoadingSpinnerShown = false; + ShowLoadingSpinner = false; Current.Value = string.Empty; OnPost?.Invoke(cb); }); From bb8bcd7248153a5bf1ae2c96dcaf0e93bda0502e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:50:30 +0300 Subject: [PATCH 31/65] Move avatar update bind to LoadComplete --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 08542bbcea..9446857f5e 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -183,12 +183,12 @@ namespace osu.Game.Overlays.Comments }); User.BindTo(api.LocalUser); - User.BindValueChanged(e => avatar.User = e.NewValue); } protected override void LoadComplete() { User.BindValueChanged(_ => refetchComments()); + User.BindValueChanged(e => avatar.User = e.NewValue); Sort.BindValueChanged(_ => refetchComments(), true); base.LoadComplete(); } From fbb674d8e9d809b9a5154525d96e36685e928fac Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 20:15:19 +0300 Subject: [PATCH 32/65] Rename parent comment id field --- osu.Game/Online/API/Requests/CommentPostRequest.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/CommentPostRequest.cs b/osu.Game/Online/API/Requests/CommentPostRequest.cs index 7012d479bd..45e5eb1a94 100644 --- a/osu.Game/Online/API/Requests/CommentPostRequest.cs +++ b/osu.Game/Online/API/Requests/CommentPostRequest.cs @@ -12,14 +12,14 @@ namespace osu.Game.Online.API.Requests public readonly CommentableType Commentable; public readonly long CommentableId; public readonly string Message; - public readonly long? ReplyTo; + public readonly long? ParentCommentId; - public CommentPostRequest(CommentableType commentable, long commentableId, string message, long? replyTo = null) + public CommentPostRequest(CommentableType commentable, long commentableId, string message, long? parentCommentId = null) { Commentable = commentable; CommentableId = commentableId; Message = message; - ReplyTo = replyTo; + ParentCommentId = parentCommentId; } protected override WebRequest CreateWebRequest() @@ -30,8 +30,8 @@ namespace osu.Game.Online.API.Requests req.AddParameter(@"comment[commentable_type]", Commentable.ToString().ToLowerInvariant()); req.AddParameter(@"comment[commentable_id]", $"{CommentableId}"); req.AddParameter(@"comment[message]", Message); - if (ReplyTo.HasValue) - req.AddParameter(@"comment[parent_id]", $"{ReplyTo}"); + if (ParentCommentId.HasValue) + req.AddParameter(@"comment[parent_id]", $"{ParentCommentId}"); return req; } From 88c3eef8e1b48e01827c50d10cacfca55bebad53 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 20:59:13 +0300 Subject: [PATCH 33/65] Add test case with no existing comments --- .../Online/TestSceneCommentsContainer.cs | 45 ++++++++++++++----- .../Overlays/Comments/CommentsContainer.cs | 2 +- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index e58423241b..4a41eca898 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -32,13 +32,18 @@ namespace osu.Game.Tests.Visual.Online private CommentsContainer commentsContainer; + private TextBox editorTextBox; + [SetUp] public void SetUp() => Schedule(() => + { Child = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, Child = commentsContainer = new CommentsContainer() - }); + }; + editorTextBox = commentsContainer.ChildrenOfType().First(); + }); [Test] public void TestIdleState() @@ -129,21 +134,41 @@ namespace osu.Game.Tests.Visual.Online commentsContainer.ChildrenOfType().Count(d => d.Comment.Pinned == withPinned) == 1); } - [TestCase] + [Test] public void TestPost() + { + setUpCommentsResponse(new CommentBundle { Comments = new List() }); + AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123)); + AddAssert("no comments placeholder shown", () => commentsContainer.ChildrenOfType().Any()); + + setUpPostResponse(); + AddStep("enter text", () => editorTextBox.Current.Value = "comm"); + AddStep("submit", () => commentsContainer.ChildrenOfType().First().TriggerClick()); + + AddUntilStep("comment sent", () => + { + string writtenText = editorTextBox.Current.Value; + var comment = commentsContainer.ChildrenOfType().Last(); + return comment.ChildrenOfType().Any(y => y.Text == writtenText); + }); + AddAssert("no comments placeholder removed", () => !commentsContainer.ChildrenOfType().Any()); + } + + [Test] + public void TestPostWithExistingComments() { setUpCommentsResponse(getExampleComments()); AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123)); + setUpPostResponse(); - AddStep("Enter text", () => this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value = "comm"); - AddStep("Submit", () => this.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); - AddUntilStep("Comment sent", () => + AddStep("enter text", () => editorTextBox.Current.Value = "comm"); + AddStep("submit", () => commentsContainer.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); + + AddUntilStep("comment sent", () => { - string text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; - return this.ChildrenOfType().Any(x => - { - return x.ChildrenOfType().Any(y => y.Text == text); - }); + string writtenText = editorTextBox.Current.Value; + var comment = commentsContainer.ChildrenOfType().Last(); + return comment.ChildrenOfType().Any(y => y.Text == writtenText); }); } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 9446857f5e..a8939ffdc6 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -390,7 +390,7 @@ namespace osu.Game.Overlays.Comments base.Dispose(isDisposing); } - private partial class NoCommentsPlaceholder : CompositeDrawable + internal partial class NoCommentsPlaceholder : CompositeDrawable { [BackgroundDependencyLoader] private void load() From cdf3aafdddd4c987c2ad8b5aa4ece2a03703f174 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 22:37:05 +0300 Subject: [PATCH 34/65] Add check for any drawables in content before looking for placeholder --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index a8939ffdc6..58f7a72ee5 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -342,7 +342,7 @@ namespace osu.Game.Overlays.Comments { LoadComponentsAsync(topLevelComments, loaded => { - if (content[0] is NoCommentsPlaceholder placeholder) + if (content.Count > 0 && content[0] is NoCommentsPlaceholder placeholder) content.Remove(placeholder, true); foreach (var comment in loaded) From c2bb0949f52404739cea5dd5d544b3068615efb8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 22:57:23 +0300 Subject: [PATCH 35/65] Take type and id from container directly on submit --- .../Overlays/Comments/CommentsContainer.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 58f7a72ee5..67db0714dc 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -29,13 +29,10 @@ namespace osu.Game.Overlays.Comments [Cached] public partial class CommentsContainer : CompositeDrawable { - private const string cid = "commentableId"; - - [Cached] private readonly Bindable type = new Bindable(); - - [Cached(name: cid)] private readonly BindableLong id = new BindableLong(); + public IBindable Type => type; + public IBindable Id => id; public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -413,24 +410,23 @@ namespace osu.Game.Overlays.Comments private partial class NewCommentEditor : CommentEditor { [Resolved] - public Bindable CommentableType { get; set; } - - [Resolved(name: cid)] - public BindableLong CommentableId { get; set; } - - protected override LocalisableString FooterText => default; - protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; - protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderNew; + private CommentsContainer commentsContainer { get; set; } [Resolved] private IAPIProvider api { get; set; } public Action OnPost; + protected override LocalisableString FooterText => default; + + protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; + + protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderNew; + protected override void OnCommit(string text) { ShowLoadingSpinner = true; - CommentPostRequest req = new CommentPostRequest(CommentableType.Value, CommentableId.Value, text); + CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text); req.Failure += _ => Schedule(() => { ShowLoadingSpinner = false; From c36922dd2c630dfb621633e359de61b0636941e7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 22:57:51 +0300 Subject: [PATCH 36/65] Use clock to obtain a position for comment insertion --- osu.Game/Overlays/Comments/CommentsContainer.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 67db0714dc..c626d1f26c 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -344,15 +344,7 @@ namespace osu.Game.Overlays.Comments foreach (var comment in loaded) { - int pos = -1; - - if (content.Count > 0) - { - var first = content.FlowingChildren.First(); - pos = (int)(content.GetLayoutPosition(first) - 1); - } - - content.Insert(pos, comment); + content.Insert((int)-Clock.CurrentTime, comment); } }, (loadCancellation = new CancellationTokenSource()).Token); } From 58406cae19851cf6910ffb5fbc04aea54af78e42 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 23:42:10 +0300 Subject: [PATCH 37/65] Make test wait for comment loading --- .../Visual/Online/TestSceneCommentsContainer.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 4a41eca898..3d8781d902 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -30,9 +28,9 @@ namespace osu.Game.Tests.Visual.Online private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - private CommentsContainer commentsContainer; + private CommentsContainer commentsContainer = null!; - private TextBox editorTextBox; + private TextBox editorTextBox = null!; [SetUp] public void SetUp() => Schedule(() => @@ -148,8 +146,8 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("comment sent", () => { string writtenText = editorTextBox.Current.Value; - var comment = commentsContainer.ChildrenOfType().Last(); - return comment.ChildrenOfType().Any(y => y.Text == writtenText); + var comment = commentsContainer.ChildrenOfType().LastOrDefault(); + return comment != null && comment.ChildrenOfType().Any(y => y.Text == writtenText); }); AddAssert("no comments placeholder removed", () => !commentsContainer.ChildrenOfType().Any()); } @@ -167,8 +165,8 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("comment sent", () => { string writtenText = editorTextBox.Current.Value; - var comment = commentsContainer.ChildrenOfType().Last(); - return comment.ChildrenOfType().Any(y => y.Text == writtenText); + var comment = commentsContainer.ChildrenOfType().LastOrDefault(); + return comment != null && comment.ChildrenOfType().Any(y => y.Text == writtenText); }); } From 1480c691ae8bbf2ca0fbe4b88acc5eb426f7ffc5 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 23:42:56 +0300 Subject: [PATCH 38/65] Explain empty string in editor's footer --- osu.Game/Overlays/Comments/CommentsContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index c626d1f26c..3639fe1835 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -409,6 +409,7 @@ namespace osu.Game.Overlays.Comments public Action OnPost; + //TODO should match web, left empty due to no multiline support protected override LocalisableString FooterText => default; protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; From 0a7d6948ca5f6947e5f1f49cf464672bb33c54d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:16:46 +0900 Subject: [PATCH 39/65] Nest model class --- .../HUD/JudgementCounter/JudgementCounter.cs | 4 ++-- .../JudgementCounter/JudgementCounterDisplay.cs | 2 +- .../JudgementCounter/JudgementCounterInfo.cs | 15 --------------- .../Play/HUD/JudgementCounter/JudgementTally.cs | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 21 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index ea6e9997e3..635b9220f4 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -18,9 +18,9 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public BindableBool ShowName = new BindableBool(); public Bindable Direction = new Bindable(); - public readonly JudgementCounterInfo Result; + public readonly JudgementTally.JudgementCount Result; - public JudgementCounter(JudgementCounterInfo result) => Result = result; + public JudgementCounter(JudgementTally.JudgementCount result) => Result = result; public OsuSpriteText ResultName = null!; private FillFlowContainer flowContainer = null!; diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 4e2b2a10cd..7dd28b29b9 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -124,7 +124,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter All } - private JudgementCounter createCounter(JudgementCounterInfo info) + private JudgementCounter createCounter(JudgementTally.JudgementCount info) { JudgementCounter counter = new JudgementCounter(info) { diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs deleted file mode 100644 index 0237981db1..0000000000 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs +++ /dev/null @@ -1,15 +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.Bindables; -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Screens.Play.HUD.JudgementCounter -{ - public struct JudgementCounterInfo - { - public HitResult Type { get; set; } - - public BindableInt ResultCount { get; set; } - } -} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index d8eac309aa..e9e3fde92a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -12,19 +12,23 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter { + /// + /// Keeps track of judgements for a current play session, exposing bindable counts which can + /// be used for display purposes. + /// public partial class JudgementTally : CompositeDrawable { [Resolved] private ScoreProcessor scoreProcessor { get; set; } = null!; - public List Results = new List(); + public List Results = new List(); [BackgroundDependencyLoader] private void load(IBindable ruleset) { foreach (var result in ruleset.Value.CreateInstance().GetHitResults()) { - Results.Add(new JudgementCounterInfo + Results.Add(new JudgementCount { Type = result.result, ResultCount = new BindableInt() @@ -42,8 +46,15 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void updateCount(JudgementResult judgement, bool revert) { - foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) + foreach (JudgementCount result in Results.Where(result => result.Type == judgement.Type)) result.ResultCount.Value = revert ? result.ResultCount.Value - 1 : result.ResultCount.Value + 1; } + + public struct JudgementCount + { + public HitResult Type { get; set; } + + public BindableInt ResultCount { get; set; } + } } } From f923dc500937e4628c26a1917db63db296fe239d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:21:30 +0900 Subject: [PATCH 40/65] Use framework `Direction` instead of local enum It should be stable enough to use. --- .../Gameplay/TestSceneJudgementCounter.cs | 4 +-- .../JudgementCounterDisplay.cs | 35 ++++++++----------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index a8d9f203ae..abd66d85ae 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -94,8 +94,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestChangeFlowDirection() { - AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); - AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); + AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = Direction.Vertical); + AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = Direction.Horizontal); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 7dd28b29b9..6aa956943b 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public Bindable Mode { get; set; } = new Bindable(); [SettingSource("Counter direction")] - public Bindable FlowDirection { get; set; } = new Bindable(); + public Bindable FlowDirection { get; set; } = new Bindable(); [SettingSource("Show judgement names")] public BindableBool ShowName { get; set; } = new BindableBool(true); @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter AutoSizeAxes = Axes.Both; InternalChild = JudgementContainer = new FillFlowContainer { - Direction = getFlow(FlowDirection.Value), + Direction = getFillDirection(FlowDirection.Value), Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; @@ -57,11 +57,11 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter FlowDirection.BindValueChanged(direction => { - JudgementContainer.Direction = getFlow(direction.NewValue); + JudgementContainer.Direction = getFillDirection(direction.NewValue); //Can't pass directly due to Enum conversion foreach (var counter in JudgementContainer.Children.OfType()) - counter.Direction.Value = getFlow(direction.NewValue); + counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); ShowMax.BindValueChanged(value => @@ -95,14 +95,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - private FillDirection getFlow(Flow flow) + private FillDirection getFillDirection(Direction flow) { switch (flow) { - case Flow.Horizontal: + case Direction.Horizontal: return FillDirection.Horizontal; - case Flow.Vertical: + case Direction.Vertical: return FillDirection.Vertical; default: @@ -110,20 +110,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - //Used to hide default full option in FillDirection - public enum Flow - { - Horizontal, - Vertical - } - - public enum DisplayMode - { - Simple, - Normal, - All - } - private JudgementCounter createCounter(JudgementTally.JudgementCount info) { JudgementCounter counter = new JudgementCounter(info) @@ -133,5 +119,12 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }; return counter; } + + public enum DisplayMode + { + Simple, + Normal, + All + } } } From 09c7ab3af628d71e9f860cea3dddd1fa281ca3d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:24:55 +0900 Subject: [PATCH 41/65] Rename exposed settings to make more sense --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 8 ++++---- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index abd66d85ae..f387f1e055 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -101,10 +101,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestToggleJudgementNames() { - AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = false); + AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); - AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = true); + AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } @@ -112,10 +112,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestHideMaxValue() { - AddStep("Hide max judgement", () => counterDisplay.ShowMax.Value = false); + AddStep("Hide max judgement", () => counterDisplay.ShowMaxJudgement.Value = false); AddWaitStep("wait some", 2); AddAssert("Check max hidden", () => counterDisplay.JudgementContainer.ChildrenOfType().First().Alpha == 0); - AddStep("Show max judgement", () => counterDisplay.ShowMax.Value = true); + AddStep("Show max judgement", () => counterDisplay.ShowMaxJudgement.Value = true); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 6aa956943b..f4a732e68e 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -26,10 +26,10 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public Bindable FlowDirection { get; set; } = new Bindable(); [SettingSource("Show judgement names")] - public BindableBool ShowName { get; set; } = new BindableBool(true); + public BindableBool ShowJudgementNames { get; set; } = new BindableBool(true); [SettingSource("Show max judgement")] - public BindableBool ShowMax { get; set; } = new BindableBool(true); + public BindableBool ShowMaxJudgement { get; set; } = new BindableBool(true); [Resolved] private JudgementTally tally { get; set; } = null!; @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); - ShowMax.BindValueChanged(value => + ShowMaxJudgement.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); firstChild.FadeTo(value.NewValue ? 1 : 0, TRANSFORM_DURATION, Easing.OutQuint); @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter JudgementCounter counter = new JudgementCounter(info) { State = { Value = Visibility.Visible }, - ShowName = { BindTarget = ShowName } + ShowName = { BindTarget = ShowJudgementNames } }; return counter; } From 35ad66eef94e6a9ec9202b29772e4643e1bf895a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:27:33 +0900 Subject: [PATCH 42/65] Give flow container a type to avoid locally casting in every location --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 8 ++++---- .../JudgementCounter/JudgementCounterDisplay.cs | 15 ++++++--------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index f387f1e055..0a501c55c7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -103,10 +103,10 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); - AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); + AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 0); AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); - AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); + AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 1); } [Test] @@ -132,13 +132,13 @@ namespace osu.Game.Tests.Visual.Gameplay private int hiddenCount() { - var num = counterDisplay.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); + var num = counterDisplay.JudgementContainer.Children.First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } private partial class TestJudgementCounterDisplay : JudgementCounterDisplay { - public new FillFlowContainer JudgementContainer => base.JudgementContainer; + public new FillFlowContainer JudgementContainer => base.JudgementContainer; } } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index f4a732e68e..d3efbc9871 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -34,13 +34,13 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer = null!; + protected FillFlowContainer JudgementContainer = null!; [BackgroundDependencyLoader] private void load() { AutoSizeAxes = Axes.Both; - InternalChild = JudgementContainer = new FillFlowContainer + InternalChild = JudgementContainer = new FillFlowContainer { Direction = getFillDirection(FlowDirection.Value), Spacing = new Vector2(10), @@ -60,7 +60,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter JudgementContainer.Direction = getFillDirection(direction.NewValue); //Can't pass directly due to Enum conversion - foreach (var counter in JudgementContainer.Children.OfType()) + foreach (var counter in JudgementContainer.Children) counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void updateMode() { - foreach (var counter in JudgementContainer.Children.OfType().Where(counter => !counter.Result.Type.IsBasic())) + foreach (var counter in JudgementContainer.Children.Where(counter => !counter.Result.Type.IsBasic())) { switch (Mode.Value) { @@ -110,15 +110,12 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - private JudgementCounter createCounter(JudgementTally.JudgementCount info) - { - JudgementCounter counter = new JudgementCounter(info) + private JudgementCounter createCounter(JudgementTally.JudgementCount info) => + new JudgementCounter(info) { State = { Value = Visibility.Visible }, ShowName = { BindTarget = ShowJudgementNames } }; - return counter; - } public enum DisplayMode { From 181473c5fc9c9c0d784d4ad834ec82a3d242eaca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:28:08 +0900 Subject: [PATCH 43/65] Rename flow to better match its purpose --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 14 +++++++------- .../JudgementCounter/JudgementCounterDisplay.cs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 0a501c55c7..d104e25df0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -103,10 +103,10 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); - AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 0); + AddAssert("Assert hidden", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 0); AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); - AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 1); + AddAssert("Assert shown", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 1); } [Test] @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Hide max judgement", () => counterDisplay.ShowMaxJudgement.Value = false); AddWaitStep("wait some", 2); - AddAssert("Check max hidden", () => counterDisplay.JudgementContainer.ChildrenOfType().First().Alpha == 0); + AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); AddStep("Show max judgement", () => counterDisplay.ShowMaxJudgement.Value = true); } @@ -123,22 +123,22 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Show basic judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); AddWaitStep("wait some", 2); - AddAssert("Check only basic", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 0); + AddAssert("Check only basic", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 0); AddStep("Show normal judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddWaitStep("wait some", 2); - AddAssert("Check all visible", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 1); + AddAssert("Check all visible", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 1); } private int hiddenCount() { - var num = counterDisplay.JudgementContainer.Children.First(child => child.Result.Type == HitResult.LargeTickHit); + var num = counterDisplay.CounterFlow.Children.First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } private partial class TestJudgementCounterDisplay : JudgementCounterDisplay { - public new FillFlowContainer JudgementContainer => base.JudgementContainer; + public new FillFlowContainer CounterFlow => base.CounterFlow; } } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index d3efbc9871..a29335ff50 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -34,13 +34,13 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer = null!; + protected FillFlowContainer CounterFlow = null!; [BackgroundDependencyLoader] private void load() { AutoSizeAxes = Axes.Both; - InternalChild = JudgementContainer = new FillFlowContainer + InternalChild = CounterFlow = new FillFlowContainer { Direction = getFillDirection(FlowDirection.Value), Spacing = new Vector2(10), @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }; foreach (var result in tally.Results) - JudgementContainer.Add(createCounter(result)); + CounterFlow.Add(createCounter(result)); } protected override void LoadComplete() @@ -57,23 +57,23 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter FlowDirection.BindValueChanged(direction => { - JudgementContainer.Direction = getFillDirection(direction.NewValue); + CounterFlow.Direction = getFillDirection(direction.NewValue); //Can't pass directly due to Enum conversion - foreach (var counter in JudgementContainer.Children) + foreach (var counter in CounterFlow.Children) counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); ShowMaxJudgement.BindValueChanged(value => { - var firstChild = JudgementContainer.Children.FirstOrDefault(); + var firstChild = CounterFlow.Children.FirstOrDefault(); firstChild.FadeTo(value.NewValue ? 1 : 0, TRANSFORM_DURATION, Easing.OutQuint); }, true); } private void updateMode() { - foreach (var counter in JudgementContainer.Children.Where(counter => !counter.Result.Type.IsBasic())) + foreach (var counter in CounterFlow.Children.Where(counter => !counter.Result.Type.IsBasic())) { switch (Mode.Value) { From ca1799376952d97a77e97ce0ca88cd31bbdd2beb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:30:50 +0900 Subject: [PATCH 44/65] Don't use `OverlayContainer` (what) --- osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 635b9220f4..0630b73376 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter { - public partial class JudgementCounter : OverlayContainer + public partial class JudgementCounter : VisibilityContainer { public BindableBool ShowName = new BindableBool(); public Bindable Direction = new Bindable(); @@ -30,6 +30,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void load(OsuColour colours, IBindable ruleset) { AutoSizeAxes = Axes.Both; + InternalChild = flowContainer = new FillFlowContainer { AutoSizeAxes = Axes.Both, From 448abf897a5824c115d0071a2f15f876e48572a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:31:08 +0900 Subject: [PATCH 45/65] Tidy up direction assignment --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index a29335ff50..0899870005 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -57,13 +57,16 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter FlowDirection.BindValueChanged(direction => { - CounterFlow.Direction = getFillDirection(direction.NewValue); + var convertedDirection = getFillDirection(direction.NewValue); + + CounterFlow.Direction = convertedDirection; - //Can't pass directly due to Enum conversion foreach (var counter in CounterFlow.Children) - counter.Direction.Value = getFillDirection(direction.NewValue); + counter.Direction.Value = convertedDirection; }, true); + Mode.BindValueChanged(_ => updateMode(), true); + ShowMaxJudgement.BindValueChanged(value => { var firstChild = CounterFlow.Children.FirstOrDefault(); From 7d1fd24ab4e8387703829fd67ca187bc0a61f374 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:31:25 +0900 Subject: [PATCH 46/65] Start all counters hidden to fix pop out animation when some portions are hidden --- .../HUD/JudgementCounter/JudgementCounterDisplay.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 0899870005..a9a3ca2cf6 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -76,8 +76,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void updateMode() { - foreach (var counter in CounterFlow.Children.Where(counter => !counter.Result.Type.IsBasic())) + foreach (var counter in CounterFlow.Children) { + if (counter.Result.Type.IsBasic()) + { + counter.Show(); + continue; + } + switch (Mode.Value) { case DisplayMode.Simple: @@ -116,7 +122,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private JudgementCounter createCounter(JudgementTally.JudgementCount info) => new JudgementCounter(info) { - State = { Value = Visibility.Visible }, + State = { Value = Visibility.Hidden }, ShowName = { BindTarget = ShowJudgementNames } }; From 48959c0212ddbbdf8e0fd98a2ba879efbb1d9eef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:35:19 +0900 Subject: [PATCH 47/65] Start name not visible to avoid pop out when hidden on startup --- osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 0630b73376..7675d0cc4f 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -42,6 +42,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }, ResultName = new OsuSpriteText { + Alpha = 0, Font = OsuFont.Numeric.With(size: 8), Text = ruleset.Value.CreateInstance().GetDisplayNameForHitResult(Result.Type) } From 81aa7feeb5299d18d6cb02e47cce53c0b6c7e45d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:35:30 +0900 Subject: [PATCH 48/65] Fix using `FadeTo` on a visibility container --- .../JudgementCounterDisplay.cs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index a9a3ca2cf6..1d82fa5397 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -78,25 +78,27 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { foreach (var counter in CounterFlow.Children) { - if (counter.Result.Type.IsBasic()) - { + if (shouldShow(counter)) counter.Show(); - continue; - } + else + counter.Hide(); + } + + bool shouldShow(JudgementCounter counter) + { + if (counter.Result.Type.IsBasic()) + return true; switch (Mode.Value) { case DisplayMode.Simple: - counter.Hide(); - break; + return false; case DisplayMode.Normal: - counter.FadeTo(counter.Result.Type.IsBonus() ? 0 : 1); - break; + return !counter.Result.Type.IsBonus(); case DisplayMode.All: - counter.Show(); - break; + return true; default: throw new ArgumentOutOfRangeException(); From 14649160e15f4bfd7c3bef56d26126efc7b8fd5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:38:29 +0900 Subject: [PATCH 49/65] Adjust transform delay to make things feel more snappy --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 1d82fa5397..4ec90edeb0 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -16,7 +16,8 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable { - public const int TRANSFORM_DURATION = 500; + public const int TRANSFORM_DURATION = 250; + public bool UsesFixedAnchor { get; set; } [SettingSource("Display mode")] From 905dec913a716ae4272b8d780dad2a851446c736 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Tue, 17 Jan 2023 12:37:30 +0100 Subject: [PATCH 50/65] update skin deserialisation --- .../Archives/modified-default-20230111.osk | Bin 1685 -> 0 bytes .../Archives/modified-default-20230117.osk | Bin 0 -> 1686 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20230111.osk create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20230117.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20230111.osk b/osu.Game.Tests/Resources/Archives/modified-default-20230111.osk deleted file mode 100644 index 53dda9744edacb6fa6bb4f1ec5a5dbb3e2fe9317..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1685 zcmWIWW@Zs#U|`^2SRJVyrrnWvYTm-%#pVHcC5fa_;F*O{6x z&iOPeq`A$`-6GxTn0YlLx%}#-;Ij{In%z*YWEC|uF%Uk>b?^D-c-jB|R&(tu=UIDf zMePLLoRFTQ3y$+`n4z|1!$ArD1{a?Vb`52z3?ZLX1r%tg$H=jzfa z7S2h|PKWuo|4Dh+Q}}e>xz3+kGcqg}Fztl?Zxw18LVI4+{A1kKV5c;=7MF3n>IETePff23O=ZN{8+^D>6)fq8mdt@@0rgK z3CcB6{Z=ozI((yE#N3*QyX#CQ)nC~DUQ^ANv((Ao*7E=6=f}?r*U3%f$b2yUPfBjq z3Ffdp_fVaFRMl)UHxmQHD?tVZF`(0Z6EpKXLS3Bma|`nGQu9iR!G3r<{e1py1(DFpBiq9J&s4Mh+D)-^lICapXoQ^Pgx5T2Tpx@#kS)7 zl4r-xZPT_`b3BWG+rvQqpAyNhw!ONyO2y&F#=o0q{_~Z(=CeLl{z&LKFAKvPW#-HF z%v)+aF@NbQ>qTxqS5+L$KJBR-lX*e@2lJZ#Wb-vwE>y85@6afDyTf!=UggfP0O_6k zW}2M)H|4k1bgs5XebqBKfxr~T)e zZ0(N2JESMieBNrNWhlAN;_qz7nRou6rTj*z`V-ZR3=9u|nVcV(e1h}y(t}fTQj<%- z>E>u~Y&J0M*M1LAseR{k>&xjzey!Vb$7Y<#(|_c=w%lxn+EPzP!T-O5a?Q1x4b3GL z`M;}JJ}>fnx2FBVxtx|Y710f)%{nW!YUV#_Se~uMBCKsQtx}PdW9*{uQF#K90v|~&1wXM$+UkS~>U~F7)>v7wKEAi6r zC)pS53%zt~$E~{&VVP|uY#OPlryOG=WxvL&f6>1zG)rHmC9phV5rg%!_0{RmTsFLC z&y%RQcXETw!w*f5KS@T#eQ=TYx!?n|z!vYdvU?|Sc%+t%v%X~V)u#3r2!1c48>rBlT z=X{zK(%fd}ZjtVE%)FYBTz>UZ@Yx49&2A`HvWgm-7zm%`y7&BZyzKvftGV`-^Q=9# zqIQCAPDszu1;_a|%uw61;h+S6gNx4wyN0qMv}6uc_wCS?c6(Yx#fk^W*1*>*OYKWImYwCnY!Q z1asJ)d#FzLYu|i=hlzpVxgZ0B7|`jyiJ5sGp)St(xdr)osd**EU_ZQ_em?uQfynXq zKec_%t(&0x^SVO&wVPtwrp{b;cj=b}R{DJ_ltn$;W^MdmTa?WH=*@+xSM}Z+*uBtx zY5TF#|I+2JM+)n1-7j1={j05yy+!a!?JqNP8FhXEa_WoNh#V>6rt9o3eu2&p(XyUqa1o!aOL{>?$fMGb0-u&)Nh!YX8iouy)vG8 zADEw1UsAXG#;EK%Q8QBG!Y|!VY7Yau+LZ<43qA*Gt~_^8PFrfOVd;WBuD|5oUB0jV z|E2x(e`P7HjY=dQp%b zA$a*hy}R{e9cy`=-@@`2TaG+22xRU_n*T$e?=OG&!H5g{Lsm0wQ}F5j=OMA`&-XtZ zN9Tzj**iVFLrI@&(saI)7lR+fyQLI;mPSoKjZ*a|su>v=9sqMWKQR3S=jWvdr{<(4 zmw*$_(csu@VB)X+9-dPB&gs^d(~bOEx8;t_IFqOU$a!tK*$lO%o{ob5e+T87Yc(61 zODghzSFwCv$A=PmZ!`aq|)Ay?DZ22cO$|w+e+9pQd3Vk#zxA1jaUDoe_3djzD!GCdBh?H>u2k$)1SF) zc+Z|EQE~6&2APK+njU|WjEei^&G`@!Ff){k?TG5LZgw|!i1cSYxK{o?Ec_GYr#*C5J0=!w-KnhrZ L@Dq^kV+HX5+q}g^ literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index f7744cb9c6..5c4f59ba2c 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tests.Skins // Covers BPM counter. "Archives/modified-default-20221205.osk", // Covers judgement counter. - "Archives/modified-default-20230111.osk" + "Archives/modified-default-20230117.osk" }; /// From e65108533ab3f42a0d6a6fdfc0926d2cf02f96a0 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 17 Jan 2023 22:12:06 +0900 Subject: [PATCH 51/65] Reduce number of tested value combination 121 combinations took 2min+ --- .../TestSceneSliderFollowCircleInput.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index 0af0ff5604..369c3d6168 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -31,9 +31,9 @@ namespace osu.Game.Rulesets.Osu.Tests [Test] public void TestMaximumDistanceTrackingWithoutMovement( - [Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] + [Values(0, 5, 10)] float circleSize, - [Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] + [Values(0, 5, 10)] double velocity) { const double time_slider_start = 1000; From 8e1002b7448e1045f12cea690ed50c2e3361c6ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 01:56:12 +0900 Subject: [PATCH 52/65] Fix song select potentially operating on `Carousel` before it is fully loaded Should fix test failures like https://github.com/ppy/osu/actions/runs/3939620830/jobs/6739690253. --- osu.Game/Screens/Select/SongSelect.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 64deb59026..db4d326991 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -860,9 +860,13 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - // if we have a pending filter operation, we want to run it now. - // it could change selection (ie. if the ruleset has been changed). - Carousel.FlushPendingFilterOperations(); + if (Carousel.IsLoaded) + { + // if we have a pending filter operation, we want to run it now. + // it could change selection (ie. if the ruleset has been changed). + Carousel.FlushPendingFilterOperations(); + } + return true; } From 452bf9255023fe6a7ac9c62e6856af7d721b4b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 17 Jan 2023 18:02:06 +0100 Subject: [PATCH 53/65] Fix code quality inspection --- .../TestSceneSliderFollowCircleInput.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index 369c3d6168..a32f0a13b8 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -31,10 +31,8 @@ namespace osu.Game.Rulesets.Osu.Tests [Test] public void TestMaximumDistanceTrackingWithoutMovement( - [Values(0, 5, 10)] - float circleSize, - [Values(0, 5, 10)] - double velocity) + [Values(0, 5, 10)] float circleSize, + [Values(0, 5, 10)] double velocity) { const double time_slider_start = 1000; From 97bd76efc6638c4994c06442c3bcd28057bd9672 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 09:47:42 -0800 Subject: [PATCH 54/65] Add ability to easily mention users in chat by right clicking username --- osu.Game/Localisation/ChatStrings.cs | 5 +++++ osu.Game/Online/Chat/StandAloneChatDisplay.cs | 1 + osu.Game/Overlays/Chat/DrawableUsername.cs | 13 +++++++++++++ 3 files changed, 19 insertions(+) diff --git a/osu.Game/Localisation/ChatStrings.cs b/osu.Game/Localisation/ChatStrings.cs index 7bd284a94e..6b0a6bd8e1 100644 --- a/osu.Game/Localisation/ChatStrings.cs +++ b/osu.Game/Localisation/ChatStrings.cs @@ -19,6 +19,11 @@ namespace osu.Game.Localisation /// public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"join the real-time discussion"); + /// + /// "Mention" + /// + public static LocalisableString MentionUser => new TranslatableString(getKey(@"mention_user"), @"Mention"); + private static string getKey(string key) => $"{prefix}:{key}"; } } diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 0a5434822b..e3b5037367 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -25,6 +25,7 @@ namespace osu.Game.Online.Chat /// public partial class StandAloneChatDisplay : CompositeDrawable { + [Cached] public readonly Bindable Channel = new Bindable(); protected readonly ChatTextBox TextBox; diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 8cd16047f3..73eb335e99 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -24,6 +25,7 @@ using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; using osuTK; using osuTK.Graphics; +using ChatStrings = osu.Game.Localisation.ChatStrings; namespace osu.Game.Overlays.Chat { @@ -65,6 +67,9 @@ namespace osu.Game.Overlays.Chat [Resolved(canBeNull: true)] private UserProfileOverlay? profileOverlay { get; set; } + [Resolved] + private Bindable? currentChannel { get; set; } + private readonly APIUser user; private readonly OsuSpriteText drawableText; @@ -156,6 +161,14 @@ namespace osu.Game.Overlays.Chat if (!user.Equals(api.LocalUser.Value)) items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); + if (currentChannel != null) + { + items.Add(new OsuMenuItem(ChatStrings.MentionUser, MenuItemType.Standard, () => + { + currentChannel.Value.TextBoxMessage.Value += $"@{user.Username}"; + })); + } + return items.ToArray(); } } From 364034280563cfd683136e9c005e91801fc3a678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 17 Jan 2023 21:30:46 +0100 Subject: [PATCH 55/65] Add logging on comment post failure --- osu.Game/Overlays/Comments/CommentsContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 3639fe1835..a334fac215 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -19,6 +19,7 @@ using osu.Framework.Threading; using System.Collections.Generic; using JetBrains.Annotations; using osu.Framework.Localisation; +using osu.Framework.Logging; using osu.Game.Graphics.Sprites; using osu.Game.Resources.Localisation.Web; using osu.Game.Users.Drawables; @@ -420,9 +421,10 @@ namespace osu.Game.Overlays.Comments { ShowLoadingSpinner = true; CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text); - req.Failure += _ => Schedule(() => + req.Failure += e => Schedule(() => { ShowLoadingSpinner = false; + Logger.Error(e, "Posting comment failed."); }); req.Success += cb => Schedule(() => { From 350cce1315d050b8d466edd3549ad309517fe8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:39:36 +0100 Subject: [PATCH 56/65] Move contents of detail header to separate component --- .../Profile/Header/Components/MainDetails.cs | 187 ++++++++++++++++++ .../Profile/Header/DetailHeaderContainer.cs | 161 +-------------- 2 files changed, 190 insertions(+), 158 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/Components/MainDetails.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs new file mode 100644 index 0000000000..930ba29c7f --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs @@ -0,0 +1,187 @@ +// 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.Extensions.LocalisationExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Leaderboards; +using osu.Game.Resources.Localisation.Web; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class MainDetails : CompositeDrawable + { + private readonly Dictionary scoreRankInfos = new Dictionary(); + private ProfileValueDisplay medalInfo = null!; + private ProfileValueDisplay ppInfo = null!; + private ProfileValueDisplay detailGlobalRank = null!; + private ProfileValueDisplay detailCountryRank = null!; + private RankGraph rankGraph = null!; + + public readonly Bindable User = new Bindable(); + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Y; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + AutoSizeDuration = 200, + AutoSizeEasing = Easing.OutQuint, + Masking = true, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 15), + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20), + Children = new Drawable[] + { + detailGlobalRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankGlobalSimple, + }, + detailCountryRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankCountrySimple, + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 60, + Children = new Drawable[] + { + rankGraph = new RankGraph + { + RelativeSizeAxes = Axes.Both, + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + medalInfo = new ProfileValueDisplay + { + Title = UsersStrings.ShowStatsMedals, + }, + ppInfo = new ProfileValueDisplay + { + Title = "pp", + }, + new TotalPlayTime + { + User = { BindTarget = User } + }, + } + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Children = new[] + { + scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), + scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), + scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), + scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), + scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), + } + } + } + }, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + User.BindValueChanged(e => updateDisplay(e.NewValue), true); + } + + private void updateDisplay(UserProfileData? data) + { + var user = data?.User; + + medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; + ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; + + foreach (var scoreRankInfo in scoreRankInfos) + scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0; + + detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; + detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; + + rankGraph.Statistics.Value = user?.Statistics; + } + + private partial class ScoreRankInfo : CompositeDrawable + { + private readonly OsuSpriteText rankCount; + + public int RankCount + { + set => rankCount.Text = value.ToLocalisableString("#,##0"); + } + + public ScoreRankInfo(ScoreRank rank) + { + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 44, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new DrawableRank(rank) + { + RelativeSizeAxes = Axes.X, + Height = 22, + }, + rankCount = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + } + }; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 890e6c4e04..17de8b8ba0 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -1,33 +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.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Localisation; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.Leaderboards; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Resources.Localisation.Web; -using osu.Game.Scoring; -using osuTK; namespace osu.Game.Overlays.Profile.Header { public partial class DetailHeaderContainer : CompositeDrawable { - private readonly Dictionary scoreRankInfos = new Dictionary(); - private ProfileValueDisplay medalInfo = null!; - private ProfileValueDisplay ppInfo = null!; - private ProfileValueDisplay detailGlobalRank = null!; - private ProfileValueDisplay detailCountryRank = null!; - private RankGraph rankGraph = null!; - public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] @@ -35,8 +19,6 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); - InternalChildren = new Drawable[] { new Box @@ -44,149 +26,12 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background5, }, - new FillFlowContainer + new MainDetails { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - AutoSizeDuration = 200, - AutoSizeEasing = Easing.OutQuint, - Masking = true, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 15), - Children = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(20), - Children = new Drawable[] - { - detailGlobalRank = new ProfileValueDisplay(true) - { - Title = UsersStrings.ShowRankGlobalSimple, - }, - detailCountryRank = new ProfileValueDisplay(true) - { - Title = UsersStrings.ShowRankCountrySimple, - }, - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - Height = 60, - Children = new Drawable[] - { - rankGraph = new RankGraph - { - RelativeSizeAxes = Axes.Both, - }, - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - medalInfo = new ProfileValueDisplay - { - Title = UsersStrings.ShowStatsMedals, - }, - ppInfo = new ProfileValueDisplay - { - Title = "pp", - }, - new TotalPlayTime - { - User = { BindTarget = User } - }, - } - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5), - Children = new[] - { - scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), - scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), - scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), - scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), - scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), - } - } - } - }, - } - }, + User = { BindTarget = User } + } }; } - - private void updateDisplay(UserProfileData? data) - { - var user = data?.User; - - medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; - ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; - - foreach (var scoreRankInfo in scoreRankInfos) - scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0; - - detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; - detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; - - rankGraph.Statistics.Value = user?.Statistics; - } - - private partial class ScoreRankInfo : CompositeDrawable - { - private readonly OsuSpriteText rankCount; - - public int RankCount - { - set => rankCount.Text = value.ToLocalisableString("#,##0"); - } - - public ScoreRankInfo(ScoreRank rank) - { - AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 44, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new DrawableRank(rank) - { - RelativeSizeAxes = Axes.X, - Height = 22, - }, - rankCount = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre - } - } - }; - } - } } } From 7a475d9cf8b160ad9ce77ba283c8b4696298c2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:55:27 +0100 Subject: [PATCH 57/65] Move out stats from top header container --- .../Header/Components/ExtendedDetails.cs | 108 ++++++++++++++++++ .../Profile/Header/TopHeaderContainer.cs | 51 --------- 2 files changed, 108 insertions(+), 51 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs new file mode 100644 index 0000000000..b50b0041d0 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs @@ -0,0 +1,108 @@ +// 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.Extensions.LocalisationExtensions; +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.Resources.Localisation.Web; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class ExtendedDetails : CompositeDrawable + { + public Bindable UserProfile { get; } = new Bindable(); + + private SpriteText rankedScore = null!; + private SpriteText hitAccuracy = null!; + private SpriteText playCount = null!; + private SpriteText totalScore = null!; + private SpriteText totalHits = null!; + private SpriteText maximumCombo = null!; + private SpriteText replaysWatched = null!; + + [BackgroundDependencyLoader] + private void load() + { + var font = OsuFont.Default.With(size: 12); + const float vertical_spacing = 4; + + AutoSizeAxes = Axes.Both; + + // this should really be a grid, but trying to avoid one to avoid the performance hit. + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20, 0), + Children = new[] + { + new FillFlowContainer + { + Name = @"Labels", + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, vertical_spacing), + Children = new Drawable[] + { + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsRankedScore }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsHitAccuracy }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsPlayCount }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsTotalScore }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsTotalHits }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsMaximumCombo }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsReplaysWatchedByOthers }, + } + }, + new FillFlowContainer + { + Name = @"Values", + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, vertical_spacing), + Children = new Drawable[] + { + rankedScore = new OsuSpriteText { Font = font }, + hitAccuracy = new OsuSpriteText { Font = font }, + playCount = new OsuSpriteText { Font = font }, + totalScore = new OsuSpriteText { Font = font }, + totalHits = new OsuSpriteText { Font = font }, + maximumCombo = new OsuSpriteText { Font = font }, + replaysWatched = new OsuSpriteText { Font = font }, + } + }, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + UserProfile.BindValueChanged(userProfile => updateStatistics(userProfile.NewValue?.User.Statistics), true); + } + + private void updateStatistics(UserStatistics? statistics) + { + if (statistics == null) + { + Alpha = 0; + return; + } + + Alpha = 1; + + rankedScore.Text = statistics.RankedScore.ToLocalisableString(@"N0"); + hitAccuracy.Text = statistics.DisplayAccuracy; + playCount.Text = statistics.PlayCount.ToLocalisableString(@"N0"); + totalScore.Text = statistics.TotalScore.ToLocalisableString(@"N0"); + totalHits.Text = statistics.TotalHits.ToLocalisableString(@"N0"); + maximumCombo.Text = statistics.MaxCombo.ToLocalisableString(@"N0"); + replaysWatched.Text = statistics.ReplaysWatched.ToLocalisableString(@"N0"); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index e04a8ad9ad..1fe39cb570 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -5,18 +5,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Resources.Localisation.Web; using osu.Game.Users.Drawables; using osuTK; @@ -38,7 +35,6 @@ namespace osu.Game.Overlays.Profile.Header private OsuSpriteText titleText = null!; private UpdateableFlag userFlag = null!; private OsuSpriteText userCountryText = null!; - private FillFlowContainer userStats = null!; private GroupBadgeFlow groupBadgeFlow = null!; [BackgroundDependencyLoader] @@ -164,16 +160,6 @@ namespace osu.Game.Overlays.Profile.Header } } }, - userStats = new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Y, - Width = 300, - Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, - Padding = new MarginPadding { Vertical = 15 }, - Spacing = new Vector2(0, 2) - } }; User.BindValueChanged(user => updateUser(user.NewValue)); @@ -192,43 +178,6 @@ namespace osu.Game.Overlays.Profile.Header titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); groupBadgeFlow.User.Value = user; - - userStats.Clear(); - - if (user?.Statistics != null) - { - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsRankedScore, user.Statistics.RankedScore.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsHitAccuracy, user.Statistics.DisplayAccuracy)); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsPlayCount, user.Statistics.PlayCount.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsTotalScore, user.Statistics.TotalScore.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsTotalHits, user.Statistics.TotalHits.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsMaximumCombo, user.Statistics.MaxCombo.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsReplaysWatchedByOthers, user.Statistics.ReplaysWatched.ToLocalisableString("#,##0"))); - } - } - - private partial class UserStatsLine : Container - { - public UserStatsLine(LocalisableString left, LocalisableString right) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 15), - Text = left, - }, - new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), - Text = right, - }, - }; - } } } } From f7c942ac10b22d365f9f9b98228959d8c5d8350e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 19:00:40 +0100 Subject: [PATCH 58/65] Move user stats into detail header container --- .../Header/Components/ExtendedDetails.cs | 6 ++- .../Profile/Header/Components/MainDetails.cs | 1 - .../Profile/Header/DetailHeaderContainer.cs | 44 ++++++++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs index b50b0041d0..50fc52600c 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class ExtendedDetails : CompositeDrawable { - public Bindable UserProfile { get; } = new Bindable(); + public Bindable User { get; } = new Bindable(); private SpriteText rankedScore = null!; private SpriteText hitAccuracy = null!; @@ -46,6 +46,7 @@ namespace osu.Game.Overlays.Profile.Header.Components new FillFlowContainer { Name = @"Labels", + AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, vertical_spacing), Children = new Drawable[] @@ -62,6 +63,7 @@ namespace osu.Game.Overlays.Profile.Header.Components new FillFlowContainer { Name = @"Values", + AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, vertical_spacing), Children = new Drawable[] @@ -83,7 +85,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { base.LoadComplete(); - UserProfile.BindValueChanged(userProfile => updateStatistics(userProfile.NewValue?.User.Statistics), true); + User.BindValueChanged(user => updateStatistics(user.NewValue?.User.Statistics), true); } private void updateStatistics(UserStatistics? statistics) diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs index 930ba29c7f..b89973c5e5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs @@ -40,7 +40,6 @@ namespace osu.Game.Overlays.Profile.Header.Components AutoSizeDuration = 200, AutoSizeEasing = Easing.OutQuint, Masking = true, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 15), Children = new Drawable[] diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 17de8b8ba0..1cc3aae735 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -26,10 +26,50 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background5, }, - new MainDetails + new Container { RelativeSizeAxes = Axes.X, - User = { BindTarget = User } + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + }, + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] + { + new MainDetails + { + RelativeSizeAxes = Axes.X, + User = { BindTarget = User } + }, + new Box + { + RelativeSizeAxes = Axes.Y, + Width = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Horizontal = 15 } + }, + new ExtendedDetails + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + User = { BindTarget = User } + } + } + } + } } }; } From 254c881ded6bc1c7b7875d3fe07ab88a02a39409 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 14:12:48 -0800 Subject: [PATCH 59/65] Also check null for bindable channel value --- osu.Game/Overlays/Chat/DrawableUsername.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 73eb335e99..771ccdcbef 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Chat private UserProfileOverlay? profileOverlay { get; set; } [Resolved] - private Bindable? currentChannel { get; set; } + private Bindable? currentChannel { get; set; } private readonly APIUser user; private readonly OsuSpriteText drawableText; @@ -161,7 +161,7 @@ namespace osu.Game.Overlays.Chat if (!user.Equals(api.LocalUser.Value)) items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); - if (currentChannel != null) + if (currentChannel?.Value != null) { items.Add(new OsuMenuItem(ChatStrings.MentionUser, MenuItemType.Standard, () => { From dfea42fd163f0ec8c558ba2b954a054a2af2d10c Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 14:13:50 -0800 Subject: [PATCH 60/65] Add space after username mention --- osu.Game/Overlays/Chat/DrawableUsername.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 771ccdcbef..031a0b6ae2 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -165,7 +165,7 @@ namespace osu.Game.Overlays.Chat { items.Add(new OsuMenuItem(ChatStrings.MentionUser, MenuItemType.Standard, () => { - currentChannel.Value.TextBoxMessage.Value += $"@{user.Username}"; + currentChannel.Value.TextBoxMessage.Value += $"@{user.Username} "; })); } From 12544c16eab2510ce4c8d90ba415103ba632b364 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 02:10:02 +0300 Subject: [PATCH 61/65] Remove canBeNull --- osu.Game/Overlays/Comments/DrawableComment.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 834abd5e9f..70ffbd8baf 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays.Comments private GridContainer content = null!; private VotePill votePill = null!; - [Resolved(canBeNull: true)] + [Resolved] private IDialogOverlay? dialogOverlay { get; set; } [Resolved] @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Comments [Resolved] private GameHost host { get; set; } = null!; - [Resolved(canBeNull: true)] + [Resolved] private OnScreenDisplay? onScreenDisplay { get; set; } public DrawableComment(Comment comment) From ca3be7138149e9ed8f6af73986cef0b559fa60f6 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 02:11:07 +0300 Subject: [PATCH 62/65] Track comment's nesting and reduce padding for too nested --- osu.Game/Overlays/Comments/DrawableComment.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 70ffbd8baf..1df65ab4b1 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -57,6 +57,11 @@ namespace osu.Game.Overlays.Comments /// public bool WasDeleted { get; protected set; } + /// + /// Tracks this comment's level of nesting. 0 means that this comment has no parents. + /// + public int Level { get; private set; } + private FillFlowContainer childCommentsVisibilityContainer = null!; private FillFlowContainer childCommentsContainer = null!; private LoadRepliesButton loadRepliesButton = null!; @@ -88,12 +93,16 @@ namespace osu.Game.Overlays.Comments } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load(OverlayColourProvider colourProvider, DrawableComment? parentComment) { LinkFlowContainer username; FillFlowContainer info; CommentMarkdownContainer message; + Level = parentComment?.Level + 1 ?? 0; + + float childrenPadding = Level < 6 ? 20 : 5; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; InternalChildren = new Drawable[] @@ -248,7 +257,7 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Padding = new MarginPadding { Left = 20 }, + Padding = new MarginPadding { Left = childrenPadding }, Children = new Drawable[] { childCommentsContainer = new FillFlowContainer From 4ad79a8a0ac721be0e409a9fd729a45d5c6c1bd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 12:00:47 +0900 Subject: [PATCH 63/65] Move `IsLoaded` check inside `BeatmapCarousel` --- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 +++ osu.Game/Screens/Select/SongSelect.cs | 9 +++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 19eced08d9..774ecc2c9c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -596,6 +596,9 @@ namespace osu.Game.Screens.Select public void FlushPendingFilterOperations() { + if (!IsLoaded) + return; + if (PendingFilter?.Completed == false) { applyActiveCriteria(false); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index db4d326991..4b3222c14a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -860,12 +860,9 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - if (Carousel.IsLoaded) - { - // if we have a pending filter operation, we want to run it now. - // it could change selection (ie. if the ruleset has been changed). - Carousel.FlushPendingFilterOperations(); - } + // if we have a pending filter operation, we want to run it now. + // it could change selection (ie. if the ruleset has been changed). + Carousel.FlushPendingFilterOperations(); return true; } From 7d0388c55cc9d1131a7a6ba92a73ec72aacc8795 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:29:42 +0900 Subject: [PATCH 64/65] Cache `IFrameStableClock` in `Player` for easier access Allows directly referencing rather than going through `DrawableRuleset`. Helps with testing and implementation of the new song progress display (#22144). --- .../ClicksPerSecondCalculator.cs | 8 +++----- osu.Game/Screens/Play/HUD/SongProgress.cs | 18 ++++++++++-------- osu.Game/Screens/Play/Player.cs | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs index bf1f508d7b..ba0c47dc8b 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs @@ -15,14 +15,12 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond [Resolved] private IGameplayClock gameplayClock { get; set; } = null!; - [Resolved(canBeNull: true)] - private DrawableRuleset? drawableRuleset { get; set; } + [Resolved] + private IFrameStableClock? frameStableClock { get; set; } public int Value { get; private set; } - // Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset` - // as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency. - private IGameplayClock clock => drawableRuleset?.FrameStableClock ?? gameplayClock; + private IGameplayClock clock => frameStableClock ?? gameplayClock; public ClicksPerSecondCalculator() { diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index 4504745eb9..c5f5de6f48 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -25,10 +25,15 @@ namespace osu.Game.Screens.Play.HUD [Resolved] protected IGameplayClock GameplayClock { get; private set; } = null!; - [Resolved(canBeNull: true)] - private DrawableRuleset? drawableRuleset { get; set; } + [Resolved] + private IFrameStableClock? frameStableClock { get; set; } + + /// + /// The reference clock is used to accurately tell the current playfield's time (including catch-up lag). + /// However, if none is available (i.e. used in tests), we fall back to the gameplay clock. + /// + protected IClock FrameStableClock => frameStableClock ?? GameplayClock; - private IClock? referenceClock; private IEnumerable? objects; public IEnumerable Objects @@ -58,12 +63,11 @@ namespace osu.Game.Screens.Play.HUD protected virtual void UpdateObjects(IEnumerable objects) { } [BackgroundDependencyLoader] - private void load() + private void load(DrawableRuleset? drawableRuleset) { if (drawableRuleset != null) { Objects = drawableRuleset.Objects; - referenceClock = drawableRuleset.FrameStableClock; } } @@ -74,9 +78,7 @@ namespace osu.Game.Screens.Play.HUD if (objects == null) return; - // The reference clock is used to accurately tell the playfield's time. This is obtained from the drawable ruleset. - // However, if no drawable ruleset is available (i.e. used in tests), we fall back to the gameplay clock. - double currentTime = referenceClock?.CurrentTime ?? GameplayClock.CurrentTime; + double currentTime = FrameStableClock.CurrentTime; bool isInIntro = currentTime < FirstHitTime; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 05133fba35..d3ab936a38 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -225,6 +225,7 @@ namespace osu.Game.Screens.Play DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods); dependencies.CacheAs(DrawableRuleset); + dependencies.CacheAs(DrawableRuleset.FrameStableClock); ScoreProcessor = ruleset.CreateScoreProcessor(); ScoreProcessor.Mods.Value = gameplayMods; From 04705504c583de28139af134ae8d00d194c104a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 17:19:57 +0900 Subject: [PATCH 65/65] Move cache to more appropriate location --- osu.Game/Screens/Play/Player.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d3ab936a38..77c16718f5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -225,7 +225,6 @@ namespace osu.Game.Screens.Play DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods); dependencies.CacheAs(DrawableRuleset); - dependencies.CacheAs(DrawableRuleset.FrameStableClock); ScoreProcessor = ruleset.CreateScoreProcessor(); ScoreProcessor.Mods.Value = gameplayMods; @@ -310,6 +309,8 @@ namespace osu.Game.Screens.Play }); } + dependencies.CacheAs(DrawableRuleset.FrameStableClock); + // add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components. // also give the overlays the ruleset skin provider to allow rulesets to potentially override HUD elements (used to disable combo counters etc.) // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there.