diff --git a/osu-framework b/osu-framework index 3ad1dd52ae..c80d5f53e7 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3ad1dd52ae511b816fb928f70ef811ec605c5c18 +Subproject commit c80d5f53e740ffe63d9deca41749c5ba0573e744 diff --git a/osu.Desktop.Deploy/App.config b/osu.Desktop.Deploy/App.config index 45685a74a8..6711f9c54e 100644 --- a/osu.Desktop.Deploy/App.config +++ b/osu.Desktop.Deploy/App.config @@ -31,6 +31,10 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste + + + + \ No newline at end of file diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index 1f9726b573..c6474eae5a 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -49,10 +49,6 @@ $(SolutionDir)\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.PatchApi.dll True - - $(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\ICSharpCode.SharpZipLib.dll - True - $(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll True @@ -73,15 +69,19 @@ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - $(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll + $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\NuGet.Squirrel.dll + True + + + $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll True $(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll True - - $(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll + + $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\Squirrel.dll True diff --git a/osu.Desktop.Deploy/packages.config b/osu.Desktop.Deploy/packages.config index 4878297be9..3c5ca9f9a3 100644 --- a/osu.Desktop.Deploy/packages.config +++ b/osu.Desktop.Deploy/packages.config @@ -7,7 +7,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - + + - + \ No newline at end of file diff --git a/osu.Desktop.Tests/app.config b/osu.Desktop.Tests/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Desktop.Tests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index f0620c98ef..f940e4be9e 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -37,8 +37,9 @@ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - $(SolutionDir)\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll + + $(SolutionDir)\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll + True False @@ -100,6 +101,7 @@ osu.licenseheader + diff --git a/osu.Desktop.Tests/packages.config b/osu.Desktop.Tests/packages.config index ad51a60195..7bd35a3abe 100644 --- a/osu.Desktop.Tests/packages.config +++ b/osu.Desktop.Tests/packages.config @@ -5,7 +5,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste --> - + diff --git a/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs index 58cbad936a..df80ffdf53 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs @@ -41,7 +41,7 @@ namespace osu.Desktop.VisualTests.Tests StarDifficulty = 5.3f, Metrics = new BeatmapMetrics { - Ratings = Enumerable.Range(0,10), + Ratings = Enumerable.Range(0, 10), Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6), Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6), }, diff --git a/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs b/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs new file mode 100644 index 0000000000..00d4d33c86 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseContextMenu.cs @@ -0,0 +1,125 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseContextMenu : TestCase + { + public override string Description => @"Menu visible on right click"; + + private const int start_time = 0; + private const int duration = 1000; + + private MyContextMenuContainer container; + + public override void Reset() + { + base.Reset(); + + Add(container = new MyContextMenuContainer + { + Size = new Vector2(200), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Green, + } + } + }); + + Add(new AnotherContextMenuContainer + { + Size = new Vector2(200), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Red, + } + } + }); + + container.Transforms.Add(new TransformPosition + { + StartValue = Vector2.Zero, + EndValue = new Vector2(0, 100), + StartTime = start_time, + EndTime = start_time + duration, + LoopCount = -1, + LoopDelay = duration * 3 + }); + container.Transforms.Add(new TransformPosition + { + StartValue = new Vector2(0, 100), + EndValue = new Vector2(100, 100), + StartTime = start_time + duration, + EndTime = start_time + duration * 2, + LoopCount = -1, + LoopDelay = duration * 3 + }); + container.Transforms.Add(new TransformPosition + { + StartValue = new Vector2(100, 100), + EndValue = new Vector2(100, 0), + StartTime = start_time + duration * 2, + EndTime = start_time + duration * 3, + LoopCount = -1, + LoopDelay = duration * 3 + }); + container.Transforms.Add(new TransformPosition + { + StartValue = new Vector2(100, 0), + EndValue = Vector2.Zero, + StartTime = start_time + duration * 3, + EndTime = start_time + duration * 4, + LoopCount = -1, + LoopDelay = duration * 3 + }); + } + + private class MyContextMenuContainer : Container, IHasContextMenu + { + public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[] + { + new OsuContextMenuItem(@"Some option"), + new OsuContextMenuItem(@"Highlighted option", MenuItemType.Highlighted), + new OsuContextMenuItem(@"Another option"), + new OsuContextMenuItem(@"Choose me please"), + new OsuContextMenuItem(@"And me too"), + new OsuContextMenuItem(@"Trying to fill"), + new OsuContextMenuItem(@"Destructive option", MenuItemType.Destructive), + }; + } + + private class AnotherContextMenuContainer : Container, IHasContextMenu + { + public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[] + { + new OsuContextMenuItem(@"Simple option"), + new OsuContextMenuItem(@"Simple very very long option"), + new OsuContextMenuItem(@"Change width", MenuItemType.Highlighted) { Action = () => ResizeWidthTo(Width * 2, 100, EasingTypes.OutQuint) }, + new OsuContextMenuItem(@"Change height", MenuItemType.Highlighted) { Action = () => ResizeHeightTo(Height * 2, 100, EasingTypes.OutQuint) }, + new OsuContextMenuItem(@"Change width back", MenuItemType.Destructive) { Action = () => ResizeWidthTo(Width / 2, 100, EasingTypes.OutQuint) }, + new OsuContextMenuItem(@"Change height back", MenuItemType.Destructive) { Action = () => ResizeHeightTo(Height / 2, 100, EasingTypes.OutQuint) }, + }; + } + } +} diff --git a/osu.Desktop.VisualTests/Tests/TestCaseDrawableRoom.cs b/osu.Desktop.VisualTests/Tests/TestCaseDrawableRoom.cs index de58323abe..0a401700cf 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseDrawableRoom.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseDrawableRoom.cs @@ -36,12 +36,12 @@ namespace osu.Desktop.VisualTests.Tests }); first.Room.Name.Value = @"Great Room Right Here"; - first.Room.Host.Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" }}; + first.Room.Host.Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } }; first.Room.Status.Value = new RoomStatusOpen(); first.Room.Beatmap.Value = new BeatmapMetadata { Title = @"Seiryu", Artist = @"Critical Crystal" }; second.Room.Name.Value = @"Relax It's The Weekend"; - second.Room.Host.Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" }}; + second.Room.Host.Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } }; second.Room.Status.Value = new RoomStatusPlaying(); second.Room.Beatmap.Value = new BeatmapMetadata { Title = @"ZAQ", Artist = @"Serendipity" }; diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs b/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs index 7ac795f6f9..f653e2b9b4 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs @@ -30,7 +30,7 @@ namespace osu.Desktop.VisualTests.Tests }, }; - AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1,10).Select(i => (float)i)); + AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Select(i => (float)i)); AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).Select(i => (float)i)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().Select(i => (float)i)); AddStep("Bottom to top", () => graph.Direction = BarDirection.BottomToTop); diff --git a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs index b1b9ddbcda..000d59a365 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs @@ -54,7 +54,7 @@ namespace osu.Desktop.VisualTests.Tests Children = new Drawable[] { new SpriteText { Text = "FadeTime" }, - sliderBar =new TestSliderBar + sliderBar = new TestSliderBar { Width = 150, Height = 10, diff --git a/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs b/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs index 23fe8f16db..4de8b297eb 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs @@ -35,7 +35,7 @@ namespace osu.Desktop.VisualTests.Tests }); AddStep(@"Pause", delegate { - if(failOverlay.State == Visibility.Visible) + if (failOverlay.State == Visibility.Visible) { failOverlay.Hide(); } diff --git a/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs index f86fa4dab5..45ae82109f 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs @@ -79,7 +79,8 @@ namespace osu.Desktop.VisualTests.Tests { score.Current.Value += 300 + (ulong)(300.0 * (comboCounter.Current > 0 ? comboCounter.Current - 1 : 0) / 25.0); comboCounter.Increment(); - numerator++; denominator++; + numerator++; + denominator++; accuracyCounter.SetFraction(numerator, denominator); }); diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index d1d0cc1c1a..0712aa7278 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -87,11 +87,13 @@ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True - - $(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll + + $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll + True False @@ -187,6 +189,7 @@ + diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config index cad2ffff0d..2fb1023253 100644 --- a/osu.Desktop.VisualTests/packages.config +++ b/osu.Desktop.VisualTests/packages.config @@ -5,8 +5,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste --> - - + + diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 4f66dfd3eb..5ac888b515 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -121,18 +121,23 @@ - $(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll + $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\NuGet.Squirrel.dll True - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True + + + $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll + True $(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll True - - $(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll + + $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\Squirrel.dll True diff --git a/osu.Desktop/packages.config b/osu.Desktop/packages.config index 60e8182c82..3ad2106d2b 100644 --- a/osu.Desktop/packages.config +++ b/osu.Desktop/packages.config @@ -7,7 +7,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - + + - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 281d2b5a79..83996df41a 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -33,8 +33,9 @@ false - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True diff --git a/osu.Game.Rulesets.Catch/packages.config b/osu.Game.Rulesets.Catch/packages.config index 634d0b51f6..fa6edb9c8f 100644 --- a/osu.Game.Rulesets.Catch/packages.config +++ b/osu.Game.Rulesets.Catch/packages.config @@ -5,5 +5,5 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 2d1f75e196..7e9615a703 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -448,7 +448,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy return curveData.RepeatSamples[index]; } - /// /// Constructs and adds a note to a pattern. /// @@ -480,7 +479,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy Tail = { Samples = sampleInfoListAt(endTime) } }; - newObject = holdNote; } diff --git a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs index ff3fd8e4b7..f31873d1c8 100644 --- a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs +++ b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs @@ -87,6 +87,5 @@ namespace osu.Game.Rulesets.Mania.MathUtils bitIndex++; return ((bitBuffer >>= 1) & 1) == 1; } - } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 9ecc77d3fc..734b62c931 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.AccentColour = value; - glowContainer.EdgeEffect = new EdgeEffect + glowContainer.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Radius = 2f, diff --git a/osu.Game.Rulesets.Mania/Timing/ControlPointContainer.cs b/osu.Game.Rulesets.Mania/Timing/ControlPointContainer.cs index 2619ce150c..26d5146aae 100644 --- a/osu.Game.Rulesets.Mania/Timing/ControlPointContainer.cs +++ b/osu.Game.Rulesets.Mania/Timing/ControlPointContainer.cs @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Mania.Timing public override void InvalidateFromChild(Invalidation invalidation) { // We only want to re-compute our size when a child's size or position has changed - if ((invalidation & Invalidation.Geometry) == 0) + if ((invalidation & Invalidation.RequiredParentSizeToFit) == 0) { base.InvalidateFromChild(invalidation); return; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 6dfd5000d4..41c693a5d9 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.UI { Name = "Hit target + hit objects", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = ManiaPlayfield.HIT_TARGET_POSITION}, + Padding = new MarginPadding { Top = ManiaPlayfield.HIT_TARGET_POSITION }, Children = new Drawable[] { new Container @@ -171,14 +171,14 @@ namespace osu.Game.Rulesets.Mania.UI background.Colour = accentColour; - hitTargetBar.EdgeEffect = new EdgeEffect + hitTargetBar.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Radius = 5, Colour = accentColour.Opacity(0.5f), }; - keyIcon.EdgeEffect = new EdgeEffect + keyIcon.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Radius = 5, diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 3d5614bd90..154e3d9b3e 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -33,8 +33,9 @@ false - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True diff --git a/osu.Game.Rulesets.Mania/packages.config b/osu.Game.Rulesets.Mania/packages.config index 634d0b51f6..fa6edb9c8f 100644 --- a/osu.Game.Rulesets.Mania/packages.config +++ b/osu.Game.Rulesets.Mania/packages.config @@ -5,5 +5,5 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 9f8ff17853..20b4655e59 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections Masking = true; AutoSizeAxes = Axes.Both; CornerRadius = width / 2; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = Color4.White.Opacity(0.2f), diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs index 07b21657a5..21bcc07f63 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Masking = true, Origin = Anchor.Centre, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Radius = 60, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs index 66cf7758b9..4c8f9cd18f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Disc.Colour = value; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Hollow = true, Type = EdgeEffectType.Glow, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs index 4dbb6bd4d6..f95063dcea 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Colour = Color4.Black, Alpha = 0.4f, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Radius = 10, diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs deleted file mode 100644 index 1786771dca..0000000000 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using System; -using System.Diagnostics; -using System.Linq; - -namespace osu.Game.Rulesets.Osu.Objects -{ - internal class OsuHitObjectDifficulty - { - /// - /// Factor by how much speed / aim strain decays per second. - /// - /// - /// These values are results of tweaking a lot and taking into account general feedback. - /// Opinionated observation: Speed is easier to maintain than accurate jumps. - /// - internal static readonly double[] DECAY_BASE = { 0.3, 0.15 }; - - /// - /// Pseudo threshold values to distinguish between "singles" and "streams" - /// - /// - /// Of course the border can not be defined clearly, therefore the algorithm has a smooth transition between those values. - /// They also are based on tweaking and general feedback. - /// - private const double stream_spacing_threshold = 110, - single_spacing_threshold = 125; - - /// - /// Scaling values for weightings to keep aim and speed difficulty in balance. - /// - /// - /// Found from testing a very large map pool (containing all ranked maps) and keeping the average values the same. - /// - private static readonly double[] spacing_weight_scaling = { 1400, 26.25 }; - - /// - /// Almost the normed diameter of a circle (104 osu pixel). That is -after- position transforming. - /// - private const double almost_diameter = 90; - - internal OsuHitObject BaseHitObject; - internal double[] Strains = { 1, 1 }; - - internal int MaxCombo = 1; - - private readonly float scalingFactor; - private float lazySliderLength; - - private readonly Vector2 startPosition; - private readonly Vector2 endPosition; - - internal OsuHitObjectDifficulty(OsuHitObject baseHitObject) - { - BaseHitObject = baseHitObject; - float circleRadius = baseHitObject.Scale * 64; - - Slider slider = BaseHitObject as Slider; - if (slider != null) - MaxCombo += slider.Ticks.Count(); - - // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps. - scalingFactor = 52.0f / circleRadius; - if (circleRadius < 30) - { - float smallCircleBonus = Math.Min(30.0f - circleRadius, 5.0f) / 50.0f; - scalingFactor *= 1.0f + smallCircleBonus; - } - - lazySliderLength = 0; - startPosition = baseHitObject.StackedPosition; - - // Calculate approximation of lazy movement on the slider - if (slider != null) - { - float sliderFollowCircleRadius = circleRadius * 3; // Not sure if this is correct, but here we do not need 100% exact values. This comes pretty darn close in my tests. - - // For simplifying this step we use actual osu! coordinates and simply scale the length, that we obtain by the ScalingFactor later - Vector2 cursorPos = startPosition; - - Action addSliderVertex = delegate (Vector2 pos) - { - Vector2 difference = pos - cursorPos; - float distance = difference.Length; - - // Did we move away too far? - if (distance > sliderFollowCircleRadius) - { - // Yep, we need to move the cursor - difference.Normalize(); // Obtain the direction of difference. We do no longer need the actual difference - distance -= sliderFollowCircleRadius; - cursorPos += difference * distance; // We move the cursor just as far as needed to stay in the follow circle - lazySliderLength += distance; - } - }; - - // Actual computation of the first lazy curve - foreach (var tick in slider.Ticks) - addSliderVertex(tick.StackedPosition); - - addSliderVertex(baseHitObject.StackedEndPosition); - - lazySliderLength *= scalingFactor; - endPosition = cursorPos; - } - // We have a normal HitCircle or a spinner - else - endPosition = startPosition; - } - - internal void CalculateStrains(OsuHitObjectDifficulty previousHitObject, double timeRate) - { - calculateSpecificStrain(previousHitObject, OsuDifficultyCalculator.DifficultyType.Speed, timeRate); - calculateSpecificStrain(previousHitObject, OsuDifficultyCalculator.DifficultyType.Aim, timeRate); - } - - // Caution: The subjective values are strong with this one - private static double spacingWeight(double distance, OsuDifficultyCalculator.DifficultyType type) - { - switch (type) - { - case OsuDifficultyCalculator.DifficultyType.Speed: - if (distance > single_spacing_threshold) - return 2.5; - else if (distance > stream_spacing_threshold) - return 1.6 + 0.9 * (distance - stream_spacing_threshold) / (single_spacing_threshold - stream_spacing_threshold); - else if (distance > almost_diameter) - return 1.2 + 0.4 * (distance - almost_diameter) / (stream_spacing_threshold - almost_diameter); - else if (distance > almost_diameter / 2) - return 0.95 + 0.25 * (distance - almost_diameter / 2) / (almost_diameter / 2); - else - return 0.95; - - case OsuDifficultyCalculator.DifficultyType.Aim: - return Math.Pow(distance, 0.99); - } - - Debug.Assert(false, "Invalid osu difficulty hit object type."); - return 0; - } - - private void calculateSpecificStrain(OsuHitObjectDifficulty previousHitObject, OsuDifficultyCalculator.DifficultyType type, double timeRate) - { - double addition = 0; - double timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) / timeRate; - double decay = Math.Pow(DECAY_BASE[(int)type], timeElapsed / 1000); - - if (BaseHitObject is Spinner) - { - // Do nothing for spinners - } - else if (BaseHitObject is Slider) - { - switch (type) - { - case OsuDifficultyCalculator.DifficultyType.Speed: - - // For speed strain we treat the whole slider as a single spacing entity, since "Speed" is about how hard it is to click buttons fast. - // The spacing weight exists to differentiate between being able to easily alternate or having to single. - addition = - spacingWeight(previousHitObject.lazySliderLength + - DistanceTo(previousHitObject), type) * - spacing_weight_scaling[(int)type]; - - break; - case OsuDifficultyCalculator.DifficultyType.Aim: - - // For Aim strain we treat each slider segment and the jump after the end of the slider as separate jumps, since movement-wise there is no difference - // to multiple jumps. - addition = - ( - spacingWeight(previousHitObject.lazySliderLength, type) + - spacingWeight(DistanceTo(previousHitObject), type) - ) * - spacing_weight_scaling[(int)type]; - - break; - } - } - else if (BaseHitObject is HitCircle) - { - addition = spacingWeight(DistanceTo(previousHitObject), type) * spacing_weight_scaling[(int)type]; - } - - // Scale addition by the time, that elapsed. Filter out HitObjects that are too close to be played anyway to avoid crazy values by division through close to zero. - // You will never find maps that require this amongst ranked maps. - addition /= Math.Max(timeElapsed, 50); - - Strains[(int)type] = previousHitObject.Strains[(int)type] * decay + addition; - } - - internal double DistanceTo(OsuHitObjectDifficulty other) - { - // Scale the distance by circle size. - return (startPosition - other.endPosition).Length * scalingFactor; - } - } -} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs new file mode 100644 index 0000000000..a164566263 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Beatmaps; +using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +using osu.Game.Rulesets.Osu.OsuDifficulty.Skills; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty +{ + public class OsuDifficultyCalculator : DifficultyCalculator + { + private const int section_length = 400; + private const double difficulty_multiplier = 0.0675; + + public OsuDifficultyCalculator(Beatmap beatmap) : base(beatmap) + { + } + + protected override void PreprocessHitObjects() + { + foreach (OsuHitObject h in Objects) + (h as Slider)?.Curve?.Calculate(); + } + + protected override double CalculateInternal(Dictionary categoryDifficulty) + { + OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Objects); + Skill[] skills = + { + new Aim(), + new Speed() + }; + + double sectionEnd = section_length / TimeRate; + foreach (OsuDifficultyHitObject h in beatmap) + { + while (h.BaseObject.StartTime > sectionEnd) + { + foreach (Skill s in skills) + { + s.SaveCurrentPeak(); + s.StartNewSectionFrom(sectionEnd); + } + + sectionEnd += section_length; + } + + foreach (Skill s in skills) + s.Process(h); + } + + double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; + double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; + + double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; + + if (categoryDifficulty != null) + { + categoryDifficulty.Add("Aim", aimRating.ToString("0.00")); + categoryDifficulty.Add("Speed", speedRating.ToString("0.00")); + } + + return starRating; + } + + protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs new file mode 100644 index 0000000000..72ba421344 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -0,0 +1,93 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections; +using System.Collections.Generic; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing +{ + /// + /// An enumerable container wrapping input as + /// which contains extra data required for difficulty calculation. + /// + public class OsuDifficultyBeatmap : IEnumerable + { + private readonly IEnumerator difficultyObjects; + private readonly Queue onScreen = new Queue(); + + /// + /// Creates an enumerator, which preprocesses a list of s recieved as input, wrapping them as + /// which contains extra data required for difficulty calculation. + /// + public OsuDifficultyBeatmap(List objects) + { + // Sort OsuHitObjects by StartTime - they are not correctly ordered in some cases. + // This should probably happen before the objects reach the difficulty calculator. + objects.Sort((a, b) => a.StartTime.CompareTo(b.StartTime)); + difficultyObjects = createDifficultyObjectEnumerator(objects); + } + + /// + /// Returns an enumerator that enumerates all s in the . + /// The inner loop adds objects that appear on screen into a queue until we need to hit the next object. + /// The outer loop returns objects from this queue one at a time, only after they had to be hit, and should no longer be on screen. + /// This means that we can loop through every object that is on screen at the time when a new one appears, + /// allowing us to determine a reading strain for the object that just appeared. + /// + public IEnumerator GetEnumerator() + { + while (true) + { + // Add upcoming objects to the queue until we have at least one object that had been hit and can be dequeued. + // This means there is always at least one object in the queue unless we reached the end of the map. + do + { + if (!difficultyObjects.MoveNext()) + break; // New objects can't be added anymore, but we still need to dequeue and return the ones already on screen. + + OsuDifficultyHitObject latest = difficultyObjects.Current; + // Calculate flow values here + + foreach (OsuDifficultyHitObject h in onScreen) + { + h.TimeUntilHit -= latest.DeltaTime; + // Calculate reading strain here + } + + onScreen.Enqueue(latest); + } + while (onScreen.Peek().TimeUntilHit > 0); // Keep adding new objects on screen while there is still time before we have to hit the next one. + + if (onScreen.Count == 0) break; // We have reached the end of the map and enumerated all the objects. + yield return onScreen.Dequeue(); // Remove and return objects one by one that had to be hit before the latest one appeared. + } + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + private IEnumerator createDifficultyObjectEnumerator(List objects) + { + // We will process OsuHitObjects in groups of three to form a triangle, so we can calculate an angle for each object. + OsuHitObject[] triangle = new OsuHitObject[3]; + + // OsuDifficultyHitObject construction requires three components, an extra copy of the first OsuHitObject is used at the beginning. + if (objects.Count > 1) + { + triangle[1] = objects[0]; // This copy will get shifted to the last spot in the triangle. + triangle[0] = objects[0]; // This component corresponds to the real first OsuHitOject. + } + + // The final component of the first triangle will be the second OsuHitOject of the map, which forms the first jump. + // If the map has less than two OsuHitObjects, the enumerator will not return anything. + for (int i = 1; i < objects.Count; ++i) + { + triangle[2] = triangle[1]; + triangle[1] = triangle[0]; + triangle[0] = objects[i]; + + yield return new OsuDifficultyHitObject(triangle); + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs new file mode 100644 index 0000000000..bdeb62df3e --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -0,0 +1,70 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing +{ + /// + /// A wrapper around extending it with additional data required for difficulty calculation. + /// + public class OsuDifficultyHitObject + { + /// + /// The this refers to. + /// + public OsuHitObject BaseObject { get; } + + /// + /// Normalized distance from the of the previous . + /// + public double Distance { get; private set; } + + /// + /// Milliseconds elapsed since the StartTime of the previous . + /// + public double DeltaTime { get; private set; } + + /// + /// Number of milliseconds until the has to be hit. + /// + public double TimeUntilHit { get; set; } + + private const int normalized_radius = 52; + + private readonly OsuHitObject[] t; + + /// + /// Initializes the object calculating extra data required for difficulty calculation. + /// + public OsuDifficultyHitObject(OsuHitObject[] triangle) + { + t = triangle; + BaseObject = t[0]; + setDistances(); + setTimingValues(); + // Calculate angle here + } + + private void setDistances() + { + // We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps. + double scalingFactor = normalized_radius / BaseObject.Radius; + if (BaseObject.Radius < 30) + { + double smallCircleBonus = Math.Min(30 - BaseObject.Radius, 5) / 50; + scalingFactor *= 1 + smallCircleBonus; + } + + Distance = (t[0].StackedPosition - t[1].StackedPosition).Length * scalingFactor; + } + + private void setTimingValues() + { + // Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure. + DeltaTime = Math.Max(40, t[0].StartTime - t[1].StartTime); + TimeUntilHit = 450; // BaseObject.PreEmpt; + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs new file mode 100644 index 0000000000..aad53f6fe8 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +{ + /// + /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. + /// + public class Aim : Skill + { + protected override double SkillMultiplier => 26.25; + protected override double StrainDecayBase => 0.15; + + protected override double StrainValueOf(OsuDifficultyHitObject current) => Math.Pow(current.Distance, 0.99) / current.DeltaTime; + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs new file mode 100644 index 0000000000..b9632e18e2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs @@ -0,0 +1,100 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +using osu.Game.Rulesets.Osu.OsuDifficulty.Utils; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +{ + /// + /// Used to processes strain values of s, keep track of strain levels caused by the processed objects + /// and to calculate a final difficulty value representing the difficulty of hitting all the processed objects. + /// + public abstract class Skill + { + /// + /// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other. + /// + protected abstract double SkillMultiplier { get; } + + /// + /// Determines how quickly strain decays for the given skill. + /// For example a value of 0.15 indicates that strain decays to 15% of its original value in one second. + /// + protected abstract double StrainDecayBase { get; } + + /// + /// s that were processed previously. They can affect the strain values of the following objects. + /// + protected readonly History Previous = new History(2); // Contained objects not used yet + + private double currentStrain = 1; // We keep track of the strain level at all times throughout the beatmap. + private double currentSectionPeak = 1; // We also keep track of the peak strain level in the current section. + private readonly List strainPeaks = new List(); + + /// + /// Process an and update current strain values accordingly. + /// + public void Process(OsuDifficultyHitObject current) + { + currentStrain *= strainDecay(current.DeltaTime); + if (!(current.BaseObject is Spinner)) + currentStrain += StrainValueOf(current) * SkillMultiplier; + + currentSectionPeak = Math.Max(currentStrain, currentSectionPeak); + + Previous.Push(current); + } + + /// + /// Saves the current peak strain level to the list of strain peaks, which will be used to calculate an overall difficulty. + /// + public void SaveCurrentPeak() + { + if (Previous.Count > 0) + strainPeaks.Add(currentSectionPeak); + } + + /// + /// Sets the initial strain level for a new section. + /// + /// The beginning of the new section in milliseconds + public void StartNewSectionFrom(double offset) + { + // The maximum strain of the new section is not zero by default, strain decays as usual regardless of section boundaries. + // This means we need to capture the strain level at the beginning of the new section, and use that as the initial peak level. + if (Previous.Count > 0) + currentSectionPeak = currentStrain * strainDecay(offset - Previous[0].BaseObject.StartTime); + } + + /// + /// Returns the calculated difficulty value representing all processed s. + /// + public double DifficultyValue() + { + strainPeaks.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain. + + double difficulty = 0; + double weight = 1; + + // Difficulty is the weighted sum of the highest strains from every section. + foreach (double strain in strainPeaks) + { + difficulty += strain * weight; + weight *= 0.9; + } + + return difficulty; + } + + /// + /// Calculates the strain value of an . This value is affected by previously processed objects. + /// + protected abstract double StrainValueOf(OsuDifficultyHitObject current); + + private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs new file mode 100644 index 0000000000..6c43c53e35 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +{ + /// + /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. + /// + public class Speed : Skill + { + protected override double SkillMultiplier => 1400; + protected override double StrainDecayBase => 0.3; + + private const double single_spacing_threshold = 125; + private const double stream_spacing_threshold = 110; + private const double almost_diameter = 90; + + protected override double StrainValueOf(OsuDifficultyHitObject current) + { + double distance = current.Distance; + + double speedValue; + if (distance > single_spacing_threshold) + speedValue = 2.5; + else if (distance > stream_spacing_threshold) + speedValue = 1.6 + 0.9 * (distance - stream_spacing_threshold) / (single_spacing_threshold - stream_spacing_threshold); + else if (distance > almost_diameter) + speedValue = 1.2 + 0.4 * (distance - almost_diameter) / (stream_spacing_threshold - almost_diameter); + else if (distance > almost_diameter / 2) + speedValue = 0.95 + 0.25 * (distance - almost_diameter / 2) / (almost_diameter / 2); + else + speedValue = 0.95; + + return speedValue / current.DeltaTime; + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs new file mode 100644 index 0000000000..d2c2e1d774 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils +{ + /// + /// An indexed stack with Push() only, which disposes items at the bottom after the capacity is full. + /// Indexing starts at the top of the stack. + /// + public class History : IEnumerable + { + public int Count { get; private set; } + + private readonly T[] array; + private readonly int capacity; + private int marker; // Marks the position of the most recently added item. + + /// + /// Initializes a new instance of the History class that is empty and has the specified capacity. + /// + /// The number of items the History can hold. + public History(int capacity) + { + if (capacity < 0) + throw new ArgumentOutOfRangeException(); + + this.capacity = capacity; + array = new T[capacity]; + marker = capacity; // Set marker to the end of the array, outside of the indexed range by one. + } + + /// + /// The most recently added item is returned at index 0. + /// + public T this[int i] + { + get + { + if (i < 0 || i > Count - 1) + throw new IndexOutOfRangeException(); + + i += marker; + if (i > capacity - 1) + i -= capacity; + + return array[i]; + } + } + + /// + /// Adds the item as the most recent one in the history. + /// The oldest item is disposed if the history is full. + /// + public void Push(T item) // Overwrite the oldest item instead of shifting every item by one with every addition. + { + if (marker == 0) + marker = capacity - 1; + else + --marker; + + array[marker] = item; + + if (Count < capacity) + ++Count; + } + + /// + /// Returns an enumerator which enumerates items in the history starting from the most recently added one. + /// + public IEnumerator GetEnumerator() + { + for (int i = marker; i < capacity; ++i) + yield return array[i]; + + if (Count == capacity) + for (int i = 0; i < marker; ++i) + yield return array[i]; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs deleted file mode 100644 index 5669993e67..0000000000 --- a/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Beatmaps; -using osu.Game.Rulesets.Osu.Beatmaps; -using osu.Game.Rulesets.Osu.Objects; -using System; -using System.Collections.Generic; - -namespace osu.Game.Rulesets.Osu -{ - public class OsuDifficultyCalculator : DifficultyCalculator - { - private const double star_scaling_factor = 0.0675; - private const double extreme_scaling_factor = 0.5; - - /// - /// HitObjects are stored as a member variable. - /// - internal List DifficultyHitObjects = new List(); - - public OsuDifficultyCalculator(Beatmap beatmap) : base(beatmap) - { - } - - protected override void PreprocessHitObjects() - { - foreach (var h in Objects) - (h as Slider)?.Curve?.Calculate(); - } - - protected override double CalculateInternal(Dictionary categoryDifficulty) - { - // Fill our custom DifficultyHitObject class, that carries additional information - DifficultyHitObjects.Clear(); - - foreach (var hitObject in Objects) - DifficultyHitObjects.Add(new OsuHitObjectDifficulty(hitObject)); - - // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. - DifficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime)); - - if (!CalculateStrainValues()) return 0; - - double speedDifficulty = CalculateDifficulty(DifficultyType.Speed); - double aimDifficulty = CalculateDifficulty(DifficultyType.Aim); - - // OverallDifficulty is not considered in this algorithm and neither is HpDrainRate. That means, that in this form the algorithm determines how hard it physically is - // to play the map, assuming, that too much of an error will not lead to a death. - // It might be desirable to include OverallDifficulty into map difficulty, but in my personal opinion it belongs more to the weighting of the actual peformance - // and is superfluous in the beatmap difficulty rating. - // If it were to be considered, then I would look at the hit window of normal HitCircles only, since Sliders and Spinners are (almost) "free" 300s and take map length - // into account as well. - - // The difficulty can be scaled by any desired metric. - // In osu!tp it gets squared to account for the rapid increase in difficulty as the limit of a human is approached. (Of course it also gets scaled afterwards.) - // It would not be suitable for a star rating, therefore: - - // The following is a proposal to forge a star rating from 0 to 5. It consists of taking the square root of the difficulty, since by simply scaling the easier - // 5-star maps would end up with one star. - double speedStars = Math.Sqrt(speedDifficulty) * star_scaling_factor; - double aimStars = Math.Sqrt(aimDifficulty) * star_scaling_factor; - - if (categoryDifficulty != null) - { - categoryDifficulty.Add("Aim", aimStars.ToString("0.00")); - categoryDifficulty.Add("Speed", speedStars.ToString("0.00")); - - double hitWindow300 = 30/*HitObjectManager.HitWindow300*/ / TimeRate; - double preEmpt = 450/*HitObjectManager.PreEmpt*/ / TimeRate; - - categoryDifficulty.Add("OD", (-(hitWindow300 - 80.0) / 6.0).ToString("0.00")); - categoryDifficulty.Add("AR", (preEmpt > 1200.0 ? -(preEmpt - 1800.0) / 120.0 : -(preEmpt - 1200.0) / 150.0 + 5.0).ToString("0.00")); - - int maxCombo = 0; - foreach (OsuHitObjectDifficulty hitObject in DifficultyHitObjects) - maxCombo += hitObject.MaxCombo; - - categoryDifficulty.Add("Max combo", maxCombo.ToString()); - } - - // Again, from own observations and from the general opinion of the community a map with high speed and low aim (or vice versa) difficulty is harder, - // than a map with mediocre difficulty in both. Therefore we can not just add both difficulties together, but will introduce a scaling that favors extremes. - double starRating = speedStars + aimStars + Math.Abs(speedStars - aimStars) * extreme_scaling_factor; - // Another approach to this would be taking Speed and Aim separately to a chosen power, which again would be equivalent. This would be more convenient if - // the hit window size is to be considered as well. - - // Note: The star rating is tuned extremely tight! Airman (/b/104229) and Freedom Dive (/b/126645), two of the hardest ranked maps, both score ~4.66 stars. - // Expect the easier kind of maps that officially get 5 stars to obtain around 2 by this metric. The tutorial still scores about half a star. - // Tune by yourself as you please. ;) - - return starRating; - } - - protected bool CalculateStrainValues() - { - // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment. - using (List.Enumerator hitObjectsEnumerator = DifficultyHitObjects.GetEnumerator()) - { - - if (!hitObjectsEnumerator.MoveNext()) return false; - - OsuHitObjectDifficulty current = hitObjectsEnumerator.Current; - - // First hitObject starts at strain 1. 1 is the default for strain values, so we don't need to set it here. See DifficultyHitObject. - while (hitObjectsEnumerator.MoveNext()) - { - var next = hitObjectsEnumerator.Current; - next?.CalculateStrains(current, TimeRate); - current = next; - } - - return true; - } - } - - /// - /// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP. - /// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain. - /// The higher this value, the less strains there will be, indirectly giving long beatmaps an advantage. - /// - protected const double STRAIN_STEP = 400; - - /// - /// The weighting of each strain value decays to this number * it's previous value - /// - protected const double DECAY_WEIGHT = 0.9; - - protected double CalculateDifficulty(DifficultyType type) - { - double actualStrainStep = STRAIN_STEP * TimeRate; - - // Find the highest strain value within each strain step - List highestStrains = new List(); - double intervalEndTime = actualStrainStep; - double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval - - OsuHitObjectDifficulty previousHitObject = null; - foreach (OsuHitObjectDifficulty hitObject in DifficultyHitObjects) - { - // While we are beyond the current interval push the currently available maximum to our strain list - while (hitObject.BaseHitObject.StartTime > intervalEndTime) - { - highestStrains.Add(maximumStrain); - - // The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay - // until the beginning of the next interval. - if (previousHitObject == null) - { - maximumStrain = 0; - } - else - { - double decay = Math.Pow(OsuHitObjectDifficulty.DECAY_BASE[(int)type], (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000); - maximumStrain = previousHitObject.Strains[(int)type] * decay; - } - - // Go to the next time interval - intervalEndTime += actualStrainStep; - } - - // Obtain maximum strain - maximumStrain = Math.Max(hitObject.Strains[(int)type], maximumStrain); - - previousHitObject = hitObject; - } - - // Build the weighted sum over the highest strains for each interval - double difficulty = 0; - double weight = 1; - highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain. - - foreach (double strain in highestStrains) - { - difficulty += weight * strain; - weight *= DECAY_WEIGHT; - } - - return difficulty; - } - - protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); - - // Those values are used as array indices. Be careful when changing them! - public enum DifficultyType - { - Speed = 0, - Aim, - }; - } -} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index bfed889b36..63fe6aaa59 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -7,6 +7,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.OsuDifficulty; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index b91bdc6a78..f6f565c502 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -34,8 +34,9 @@ false - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True @@ -68,9 +69,14 @@ - - + + + + + + + diff --git a/osu.Game.Rulesets.Osu/packages.config b/osu.Game.Rulesets.Osu/packages.config index 634d0b51f6..fa6edb9c8f 100644 --- a/osu.Game.Rulesets.Osu/packages.config +++ b/osu.Game.Rulesets.Osu/packages.config @@ -5,5 +5,5 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 37efd8aba4..037b9dae89 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER), BlendingMode = BlendingMode.Additive, Masking = true, - Children = new [] + Children = new[] { new Box { @@ -119,7 +119,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Children = new [] + Children = new[] { symbol = new SwellSymbolPiece() } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs index 3ea05b6558..9f115d07eb 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces private void resetEdgeEffects() { - background.EdgeEffect = new EdgeEffect + background.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = AccentColour.Opacity(KiaiMode ? edge_alpha_kiai : 1f), diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index e0da3ed3db..403730aa0e 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours) { - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = isRim ? colours.BlueDarker : colours.PinkDarker, diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index c7bd4a6704..97b2c9d343 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, BorderThickness = 2, Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.2f), @@ -229,7 +229,6 @@ namespace osu.Game.Rulesets.Taiko.UI if (judgedObject.HitObject.Kiai) kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject.Judgement, isRim)); - } else hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit(); diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 8d6fcb503c..f719f2002b 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -33,8 +33,9 @@ false - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True diff --git a/osu.Game.Rulesets.Taiko/packages.config b/osu.Game.Rulesets.Taiko/packages.config index dc059c684b..8add43d5d5 100644 --- a/osu.Game.Rulesets.Taiko/packages.config +++ b/osu.Game.Rulesets.Taiko/packages.config @@ -4,5 +4,5 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - + \ No newline at end of file diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 7fb01cedc0..4a6b972f4a 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -166,4 +166,3 @@ namespace osu.Game.Tests.Beatmaps.IO } } } - diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 03d09e24e0..c9b3b1b922 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -86,4 +86,3 @@ namespace osu.Game.Tests.Beatmaps.IO } } } - diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index b8fcb80aaf..8ec68b41be 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -30,11 +30,13 @@ false - - $(SolutionDir)\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll + + $(SolutionDir)\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll + True - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index 9972fb41a1..9ad76308d7 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -4,8 +4,8 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - - + + \ No newline at end of file diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 9df1f0f284..14298c4172 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -10,7 +10,6 @@ using OpenTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class DifficultyIcon : DifficultyColouredContainer { private readonly BeatmapInfo beatmap; diff --git a/osu.Game/Beatmaps/Drawables/Panel.cs b/osu.Game/Beatmaps/Drawables/Panel.cs index f7349d981a..3dac50732c 100644 --- a/osu.Game/Beatmaps/Drawables/Panel.cs +++ b/osu.Game/Beatmaps/Drawables/Panel.cs @@ -88,7 +88,7 @@ namespace osu.Game.Beatmaps.Drawables protected virtual void Selected() { nestedContainer.BorderThickness = 2.5f; - nestedContainer.EdgeEffect = new EdgeEffect + nestedContainer.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = new Color4(130, 204, 255, 150), @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps.Drawables protected virtual void Deselected() { nestedContainer.BorderThickness = 0; - nestedContainer.EdgeEffect = new EdgeEffect + nestedContainer.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Offset = new Vector2(1), diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3f56dc0b79..6b07d5c967 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -13,7 +13,6 @@ namespace osu.Game.Configuration protected override void InitialiseDefaults() { // UI/selection defaults - Set(OsuSetting.Ruleset, 0, 0, int.MaxValue); Set(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Details); @@ -25,7 +24,6 @@ namespace osu.Game.Configuration Set(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2, 1); // Online settings - Set(OsuSetting.Username, string.Empty); Set(OsuSetting.Token, string.Empty); @@ -40,14 +38,12 @@ namespace osu.Game.Configuration }; // Audio - Set(OsuSetting.MenuVoice, true); Set(OsuSetting.MenuMusic, true); Set(OsuSetting.AudioOffset, 0, -500.0, 500.0); // Input - Set(OsuSetting.MenuCursorSize, 1.0, 0.5f, 2); Set(OsuSetting.GameplayCursorSize, 1.0, 0.5f, 2); Set(OsuSetting.AutoCursorSize, false); @@ -56,7 +52,6 @@ namespace osu.Game.Configuration Set(OsuSetting.MouseDisableWheel, false); // Graphics - Set(OsuSetting.ShowFpsDisplay, false); Set(OsuSetting.MenuParallax, true); @@ -65,7 +60,6 @@ namespace osu.Game.Configuration Set(OsuSetting.SnakingOutSliders, true); // Gameplay - Set(OsuSetting.DimLevel, 0.3, 0, 1); Set(OsuSetting.ShowInterface, true); @@ -75,7 +69,6 @@ namespace osu.Game.Configuration Set(OsuSetting.PlaybackSpeed, 1.0, 0.5f, 2); // Update - Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); } diff --git a/osu.Game/Database/BeatmapDifficulty.cs b/osu.Game/Database/BeatmapDifficulty.cs index cf1305f705..87c651aa88 100644 --- a/osu.Game/Database/BeatmapDifficulty.cs +++ b/osu.Game/Database/BeatmapDifficulty.cs @@ -39,4 +39,3 @@ namespace osu.Game.Database } } } - diff --git a/osu.Game/Database/BeatmapSetInfo.cs b/osu.Game/Database/BeatmapSetInfo.cs index 0875d3c01f..aa5fa21394 100644 --- a/osu.Game/Database/BeatmapSetInfo.cs +++ b/osu.Game/Database/BeatmapSetInfo.cs @@ -36,4 +36,3 @@ namespace osu.Game.Database public string StoryboardFile { get; set; } } } - diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 7a2345a80c..e6a5c5104d 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -7,7 +7,6 @@ using osu.Framework.MathUtils; using OpenTK; using OpenTK.Graphics; using System; -using osu.Framework.Graphics.OpenGL; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Textures; using OpenTK.Graphics.ES30; @@ -16,6 +15,7 @@ using osu.Framework.Graphics.Primitives; using osu.Framework.Allocation; using System.Collections.Generic; using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.OpenGL.Vertices; using osu.Framework.Lists; namespace osu.Game.Graphics.Backgrounds diff --git a/osu.Game/Graphics/Cursor/CursorTrail.cs b/osu.Game/Graphics/Cursor/CursorTrail.cs index 11475a0f19..183679fbd3 100644 --- a/osu.Game/Graphics/Cursor/CursorTrail.cs +++ b/osu.Game/Graphics/Cursor/CursorTrail.cs @@ -8,13 +8,13 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Input; using OpenTK; using System; -using osu.Framework.Graphics.OpenGL; using osu.Framework.Graphics.OpenGL.Buffers; using OpenTK.Graphics.ES30; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Colour; using osu.Framework.Timing; using System.Diagnostics; +using osu.Framework.Graphics.OpenGL.Vertices; namespace osu.Game.Graphics.Cursor { diff --git a/osu.Game/Graphics/Cursor/GameplayCursor.cs b/osu.Game/Graphics/Cursor/GameplayCursor.cs index 801fe1d011..453d821a96 100644 --- a/osu.Game/Graphics/Cursor/GameplayCursor.cs +++ b/osu.Game/Graphics/Cursor/GameplayCursor.cs @@ -67,7 +67,7 @@ namespace osu.Game.Graphics.Cursor Masking = true, BorderThickness = Size.X / 6, BorderColour = Color4.White, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Pink.Opacity(0.5f), diff --git a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs new file mode 100644 index 0000000000..2cc6c3a46a --- /dev/null +++ b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Graphics.Cursor +{ + public class OsuContextMenuContainer : ContextMenuContainer + { + protected override ContextMenu CreateContextMenu() => new OsuContextMenu(); + + public OsuContextMenuContainer(CursorContainer cursor) : base(cursor) + { + } + } +} \ No newline at end of file diff --git a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs deleted file mode 100644 index 8b71182263..0000000000 --- a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Input; -using osu.Game.Configuration; -using System; - -namespace osu.Game.Graphics.Cursor -{ - public class OsuCursorContainer : CursorContainer - { - protected override Drawable CreateCursor() => new OsuCursor(); - - public OsuCursorContainer() - { - Add(new CursorTrail { Depth = 1 }); - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - ActiveCursor.Scale = new Vector2(1); - ActiveCursor.ScaleTo(1.2f, 100, EasingTypes.OutQuad); - return base.OnMouseDown(state, args); - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - if (!state.Mouse.HasMainButtonPressed) - ActiveCursor.ScaleTo(1, 200, EasingTypes.OutQuad); - return base.OnMouseUp(state, args); - } - - public class OsuCursor : Container - { - private Container cursorContainer; - private Bindable cursorScale; - - public OsuCursor() - { - Origin = Anchor.Centre; - Size = new Vector2(42); - } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - cursorScale = config.GetBindable(OsuConfig.CursorSize); - - Children = new Drawable[] - { - cursorContainer = new CircularContainer - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Scale = new Vector2((float)cursorScale), - Masking = true, - BorderThickness = Size.X / 6, - BorderColour = Color4.White, - EdgeEffect = new EdgeEffect { - Type = EdgeEffectType.Shadow, - Colour = Color4.Pink.Opacity(0.5f), - Radius = 5, - }, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, - }, - new CircularContainer - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - BorderThickness = Size.X / 3, - BorderColour = Color4.White.Opacity(0.5f), - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, - }, - }, - }, - new CircularContainer - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.1f), - Masking = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - }, - }, - }, - } - }, - }; - cursorScale.ValueChanged += scaleChanged; - } - - private void scaleChanged(object sender, EventArgs e) - { - cursorContainer.Scale = new Vector2((float)cursorScale); - } - } - } -} diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index 815d820a47..42d82a088c 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -52,7 +52,7 @@ namespace osu.Game.Graphics.Cursor CornerRadius = 5; Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(40), diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 3d83668d07..d2f4d4768c 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -87,5 +87,7 @@ namespace osu.Game.Graphics public readonly Color4 RedDarker = FromHex(@"870000"); public readonly Color4 ChatBlue = FromHex(@"17292e"); + + public readonly Color4 ContextMenuGray = FromHex(@"223034"); } } diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs index 76b75f1084..a0f796050b 100644 --- a/osu.Game/Graphics/UserInterface/Bar.cs +++ b/osu.Game/Graphics/UserInterface/Bar.cs @@ -81,7 +81,7 @@ namespace osu.Game.Graphics.UserInterface background = new Box { RelativeSizeAxes = Axes.Both, - Colour = new Color4(0,0,0,0) + Colour = new Color4(0, 0, 0, 0) }, bar = new Box { diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index c935d58a4b..2076b3e9be 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -222,7 +222,7 @@ namespace osu.Game.Graphics.UserInterface Width = 0.8f, Masking = true, MaskingSmoothness = 2, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.2f), diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index d2a87d2dd0..7cacd09618 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -50,7 +50,7 @@ namespace osu.Game.Graphics.UserInterface CornerRadius = 5, Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.04f), Type = EdgeEffectType.Shadow, diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index 61ec859b44..27a888f0b5 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -1,15 +1,48 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using OpenTK; namespace osu.Game.Graphics.UserInterface { - public class LoadingAnimation : SpriteText + public class LoadingAnimation : VisibilityContainer { + private readonly TextAwesome spinner; + public LoadingAnimation() { - Text = "Loading"; + Size = new Vector2(20); + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Children = new Drawable[] + { + spinner = new TextAwesome + { + TextSize = 20, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_spinner + } + }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + spinner.RotateTo(360, 2000); + using (spinner.BeginDelayedSequence(2000)) + spinner.Loop(); + } + + private const float transition_duration = 500; + + protected override void PopIn() => FadeIn(transition_duration * 5, EasingTypes.OutQuint); + + protected override void PopOut() => FadeOut(transition_duration, EasingTypes.OutQuint); } -} \ No newline at end of file +} diff --git a/osu.Game/Graphics/UserInterface/MenuItemType.cs b/osu.Game/Graphics/UserInterface/MenuItemType.cs new file mode 100644 index 0000000000..bd89dbfced --- /dev/null +++ b/osu.Game/Graphics/UserInterface/MenuItemType.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Graphics.UserInterface +{ + public enum MenuItemType + { + Standard, + Highlighted, + Destructive, + } +} \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index a5cbc9f53f..b91612f3c0 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -56,7 +56,7 @@ namespace osu.Game.Graphics.UserInterface GlowingAccentColour = colours.PinkLighter; GlowColour = colours.PinkDarker; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = GlowColour, Type = EdgeEffectType.Glow, diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs new file mode 100644 index 0000000000..e17ce2a5b2 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Graphics.UserInterface +{ + public class OsuContextMenu : ContextMenu + where TItem : ContextMenuItem + { + protected override Menu CreateMenu() => new CustomMenu(); + + public class CustomMenu : Menu + { + private const int fade_duration = 250; + + public CustomMenu() + { + CornerRadius = 5; + ItemsContainer.Padding = new MarginPadding { Vertical = OsuContextMenuItem.MARGIN_VERTICAL }; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.1f), + Radius = 4, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Background.Colour = colours.ContextMenuGray; + } + + protected override void AnimateOpen() => FadeIn(fade_duration, EasingTypes.OutQuint); + protected override void AnimateClose() => FadeOut(fade_duration, EasingTypes.OutQuint); + + protected override void UpdateContentHeight() + { + var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; + ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, EasingTypes.OutQuint); + } + } + } +} \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs b/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs new file mode 100644 index 0000000000..769df18566 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs @@ -0,0 +1,114 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Graphics.UserInterface +{ + public class OsuContextMenuItem : ContextMenuItem + { + private const int transition_length = 80; + private const int margin_horizontal = 17; + public const int MARGIN_VERTICAL = 4; + private const int text_size = 17; + + private OsuSpriteText text; + private OsuSpriteText textBold; + + private SampleChannel sampleClick; + private SampleChannel sampleHover; + + private readonly MenuItemType type; + + protected override Container CreateTextContainer(string title) => new Container + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Text = title, + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + }, + textBold = new OsuSpriteText + { + AlwaysPresent = true, + Alpha = 0, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Text = title, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + } + } + }; + + public OsuContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) : base(title) + { + this.type = type; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleHover = audio.Sample.Get(@"Menu/menuclick"); + sampleClick = audio.Sample.Get(@"Menu/menuback"); + + BackgroundColour = Color4.Transparent; + BackgroundColourHover = OsuColour.FromHex(@"172023"); + + updateTextColour(); + } + + private void updateTextColour() + { + switch (type) + { + case MenuItemType.Standard: + textBold.Colour = text.Colour = Color4.White; + break; + case MenuItemType.Destructive: + textBold.Colour = text.Colour = Color4.Red; + break; + case MenuItemType.Highlighted: + textBold.Colour = text.Colour = OsuColour.FromHex(@"ffcc22"); + break; + } + } + + protected override bool OnHover(InputState state) + { + sampleHover.Play(); + textBold.FadeIn(transition_length, EasingTypes.OutQuint); + text.FadeOut(transition_length, EasingTypes.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + textBold.FadeOut(transition_length, EasingTypes.OutQuint); + text.FadeIn(transition_length, EasingTypes.OutQuint); + base.OnHoverLost(state); + } + + protected override bool OnClick(InputState state) + { + sampleClick.Play(); + return base.OnClick(state); + } + } +} \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs b/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs index 5de6507bb3..bf835f0165 100644 --- a/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs @@ -16,7 +16,7 @@ namespace osu.Game.Graphics.UserInterface throw new InvalidOperationException("OsuEnumDropdown only supports enums as the generic type argument"); List> items = new List>(); - foreach(var val in (T[])Enum.GetValues(typeof(T))) + foreach (var val in (T[])Enum.GetValues(typeof(T))) { var field = typeof(T).GetField(Enum.GetName(typeof(T), val)); items.Add( diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 4bbae4efd1..6f955b1696 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -74,21 +74,6 @@ namespace osu.Game.Graphics.UserInterface } } - public override bool Active - { - get { return base.Active; } - set - { - if (Active == value) return; - - if (value) - fadeActive(); - else - fadeInactive(); - base.Active = value; - } - } - private const float transition_length = 500; private void fadeActive() @@ -150,6 +135,10 @@ namespace osu.Game.Graphics.UserInterface } }; } + + protected override void OnActivated() => fadeActive(); + + protected override void OnDeactivated() => fadeInactive(); } private class OsuTabDropdown : OsuDropdown diff --git a/osu.Game/Graphics/UserInterface/PageTabControl.cs b/osu.Game/Graphics/UserInterface/PageTabControl.cs index 8bf455b099..993ac4a238 100644 --- a/osu.Game/Graphics/UserInterface/PageTabControl.cs +++ b/osu.Game/Graphics/UserInterface/PageTabControl.cs @@ -29,21 +29,6 @@ namespace osu.Game.Graphics.UserInterface private readonly Box box; - public override bool Active - { - get { return base.Active; } - set - { - if (Active == value) return; - - if (value) - slideActive(); - else - slideInactive(); - base.Active = value; - } - } - public PageTabItem(T value) : base(value) { AutoSizeAxes = Axes.X; @@ -100,6 +85,10 @@ namespace osu.Game.Graphics.UserInterface { box.ScaleTo(new Vector2(1f, 0f), transition_duration); } + + protected override void OnActivated() => slideActive(); + + protected override void OnDeactivated() => slideInactive(); } } } diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index ebaef661c4..4c4b6c4d48 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -79,18 +79,21 @@ namespace osu.Game.Graphics.UserInterface Width = 0.4f, Children = new Drawable[] { - new Container { + new Container + { RelativeSizeAxes = Axes.Both, Shear = new Vector2(shear, 0), Masking = true, MaskingSmoothness = 2, - EdgeEffect = new EdgeEffect { + EdgeEffect = new EdgeEffectParameters + { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.2f), Offset = new Vector2(2, 0), Radius = 2, }, - Children = new [] { + Children = new[] + { IconLayer = new Box { RelativeSizeAxes = Axes.Both, @@ -113,18 +116,21 @@ namespace osu.Game.Graphics.UserInterface Width = 0.6f, Children = new Drawable[] { - new Container { + new Container + { RelativeSizeAxes = Axes.Both, Shear = new Vector2(shear, 0), Masking = true, MaskingSmoothness = 2, - EdgeEffect = new EdgeEffect { + EdgeEffect = new EdgeEffectParameters + { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.2f), Offset = new Vector2(2, 0), Radius = 2, }, - Children = new [] { + Children = new[] + { TextLayer = new Box { Origin = Anchor.TopLeft, diff --git a/osu.Game/Online/API/OAuthToken.cs b/osu.Game/Online/API/OAuthToken.cs index 328888ab8a..1788adbf56 100644 --- a/osu.Game/Online/API/OAuthToken.cs +++ b/osu.Game/Online/API/OAuthToken.cs @@ -59,7 +59,6 @@ namespace osu.Game.Online.API { } - return null; } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ed244a7b48..7e5b913d10 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -77,8 +77,10 @@ namespace osu.Game public void ToggleDirect() => direct.ToggleVisibility(); [BackgroundDependencyLoader] - private void load() + private void load(FrameworkConfigManager frameworkConfig) { + this.frameworkConfig = frameworkConfig; + if (!Host.IsPrimaryInstance) { Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error); @@ -150,7 +152,7 @@ namespace osu.Game RelativeSizeAxes = Axes.Both, }, volume = new VolumeControl(), - overlayContent = new Container{ RelativeSizeAxes = Axes.Both }, + overlayContent = new Container { RelativeSizeAxes = Axes.Both }, new OnScreenDisplay(), new GlobalHotkeys //exists because UserInputManager is at a level below us. { @@ -259,6 +261,19 @@ namespace osu.Game { switch (args.Key) { + case Key.R: + if (state.Keyboard.AltPressed) + { + var sensitivity = frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity); + + sensitivity.Disabled = false; + sensitivity.Value = 1; + sensitivity.Disabled = true; + + frameworkConfig.Set(FrameworkSetting.ActiveInputHandlers, string.Empty); + return true; + } + break; case Key.T: Toolbar.ToggleVisibility(); return true; @@ -284,6 +299,7 @@ namespace osu.Game private Container overlayContent; private OsuScreen currentScreen; + private FrameworkConfigManager frameworkConfig; private void screenChanged(Screen newScreen) { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b228b6485a..306cdaddf0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -158,6 +158,7 @@ namespace osu.Game Children = new Drawable[] { Cursor = new MenuCursor(), + new OsuContextMenuContainer(Cursor) { Depth = -2 }, new OsuTooltipContainer(Cursor) { Depth = -1 }, } }, diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 23ddff9381..1bc1daa599 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -26,6 +26,8 @@ namespace osu.Game.Overlays.Chat public readonly Bindable ChannelSelectorActive = new Bindable(); + private readonly ChannelTabItem.ChannelSelectorTabItem selectorTab; + public ChatTabControl() { TabContainer.Margin = new MarginPadding { Left = 50 }; @@ -41,7 +43,22 @@ namespace osu.Game.Overlays.Chat Padding = new MarginPadding(10), }); - AddTabItem(new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" }, ChannelSelectorActive)); + AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); + + ChannelSelectorActive.BindTo(selectorTab.Active); + } + + protected override void SelectTab(TabItem tab) + { + if (tab is ChannelTabItem.ChannelSelectorTabItem) + { + tab.Active.Toggle(); + return; + } + + selectorTab.Active.Value = false; + + base.SelectTab(tab); } private class ChannelTabItem : TabItem @@ -56,18 +73,6 @@ namespace osu.Game.Overlays.Chat private readonly Box highlightBox; private readonly TextAwesome icon; - public override bool Active - { - get { return base.Active; } - set - { - if (Active == value) return; - - base.Active = value; - updateState(); - } - } - private void updateState() { if (Active) @@ -141,7 +146,7 @@ namespace osu.Game.Overlays.Chat Shear = new Vector2(shear_width / ChatOverlay.TAB_AREA_HEIGHT, 0); Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Radius = 10, @@ -205,28 +210,8 @@ namespace osu.Game.Overlays.Chat public class ChannelSelectorTabItem : ChannelTabItem { - public override bool Active + public ChannelSelectorTabItem(Channel value) : base(value) { - get { return false; } - // ReSharper disable once ValueParameterNotUsed - set - { - // we basically never want this tab to become active. - // this allows us to become a "toggle" tab. - // is a bit hacky, to say the least. - activeBindable.Value = !activeBindable.Value; - base.Active = false; - } - } - - private readonly Bindable activeBindable; - - public ChannelSelectorTabItem(Channel value, Bindable active) : base(value) - { - activeBindable = active; - activeBindable.ValueChanged += v => selectorUpdateState(); - - Depth = float.MaxValue; Width = 45; @@ -242,27 +227,11 @@ namespace osu.Game.Overlays.Chat backgroundInactive = colour.Gray2; backgroundActive = colour.Gray3; } - - protected override void LoadComplete() - { - base.LoadComplete(); - - selectorUpdateState(); - } - - protected override void OnHoverLost(InputState state) - { - selectorUpdateState(); - } - - private void selectorUpdateState() - { - if (activeBindable.Value) - fadeActive(); - else - fadeInactive(); - } } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); } } } diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 0cd6b8dd3a..e8bde11a3c 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -86,6 +86,6 @@ namespace osu.Game.Overlays.Chat } } - private void scrollToEnd() => Scheduler.AddDelayed(() => scroll.ScrollToEnd(), 50); + private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); } } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index c32199f881..4f51575da3 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Threading; -using osu.Game.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; @@ -33,7 +32,9 @@ namespace osu.Game.Overlays private ScheduledDelegate messageRequest; - private readonly Container currentChannelContainer; + private readonly Container currentChannelContainer; + + private readonly LoadingAnimation loading; private readonly FocusedTextBox inputTextBox; @@ -104,7 +105,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, }, - currentChannelContainer = new Container + currentChannelContainer = new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding @@ -138,7 +139,8 @@ namespace osu.Game.Overlays HoldFocus = true, } } - } + }, + loading = new LoadingAnimation(), } }, new Container @@ -274,14 +276,7 @@ namespace osu.Game.Overlays private void initializeChannels() { - SpriteText loading; - Add(loading = new OsuSpriteText - { - Text = @"initialising chat...", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - TextSize = 40, - }); + loading.Show(); messageRequest?.Cancel(); @@ -290,9 +285,6 @@ namespace osu.Game.Overlays { Scheduler.Add(delegate { - loading.FadeOut(100); - loading.Expire(); - addChannel(channels.Find(c => c.Name == @"#lazer")); addChannel(channels.Find(c => c.Name == @"#osu")); addChannel(channels.Find(c => c.Name == @"#lobby")); @@ -336,13 +328,17 @@ namespace osu.Game.Overlays if (loaded == null) { currentChannelContainer.FadeOut(500, EasingTypes.OutQuint); + loading.Show(); loaded = new DrawableChannel(currentChannel); loadedChannels.Add(loaded); LoadComponentAsync(loaded, l => { + if (currentChannel.Messages.Any()) + loading.Hide(); + currentChannelContainer.Clear(false); - currentChannelContainer.Add(l); + currentChannelContainer.Add(loaded); currentChannelContainer.FadeIn(500, EasingTypes.OutQuint); }); } @@ -367,7 +363,6 @@ namespace osu.Game.Overlays } else { - careChannels.Add(channel); channelTabs.AddItem(channel); } @@ -387,6 +382,7 @@ namespace osu.Game.Overlays req.Success += delegate (List messages) { + loading.Hide(); channel.AddNewMessages(messages.ToArray()); Debug.Write("success!"); }; diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 13f6d3ca23..97d8f03b9b 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Dialog { RelativeSizeAxes = Axes.Both, Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.5f), diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index 9454272728..461eb2595a 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays State = Visibility.Visible; } - private void onDialogOnStateChanged(OverlayContainer dialog, Visibility v) + private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v) { if (v != Visibility.Hidden) return; diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 4be68157d7..a4c4d51f29 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Direct CornerRadius = 4; Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Offset = new Vector2(0f, 1f), diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 48636a5228..4fe76728d1 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Direct Height = height; CornerRadius = 5; Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Offset = new Vector2(0f, 1f), diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index dd135e43ef..8a04d91cfb 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -20,7 +20,6 @@ using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Mods { - /// /// Represents a clickable button which can cycle through one of more mods. /// @@ -80,7 +79,7 @@ namespace osu.Game.Overlays.Mods backgroundIcon.RotateTo(-rotate_angle * direction, mod_switch_duration, mod_switch_easing); backgroundIcon.Icon = modAfter.Icon; - using (iconsContainer.BeginDelayedSequence(mod_switch_duration, true)) + using (BeginDelayedSequence(mod_switch_duration, true)) { foregroundIcon.RotateTo(-rotate_angle * direction); foregroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); @@ -88,7 +87,7 @@ namespace osu.Game.Overlays.Mods backgroundIcon.RotateTo(rotate_angle * direction); backgroundIcon.RotateTo(0f, mod_switch_duration, mod_switch_easing); - iconsContainer.Schedule(() => displayMod(modAfter)); + Schedule(() => displayMod(modAfter)); } } diff --git a/osu.Game/Overlays/Music/CollectionsDropdown.cs b/osu.Game/Overlays/Music/CollectionsDropdown.cs index fd2ef23b9c..f6016fd1db 100644 --- a/osu.Game/Overlays/Music/CollectionsDropdown.cs +++ b/osu.Game/Overlays/Music/CollectionsDropdown.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Music Icon.TextSize = 14; Icon.Margin = new MarginPadding(0); Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 10, Right = 10 }; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.3f), @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Music public CollectionsMenu() { CornerRadius = 5; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.3f), diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 789e45adfc..69cb9c3464 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -137,6 +137,7 @@ namespace osu.Game.Overlays.Music public bool MatchingFilter { + get { return matching; } set { if (matching == value) return; @@ -145,10 +146,6 @@ namespace osu.Game.Overlays.Music FadeTo(matching ? 1 : 0, 200); } - get - { - return matching; - } } } } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 82596252b3..1ed7da83b6 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Music RelativeSizeAxes = Axes.Both, CornerRadius = 5, Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(40), diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index bfe10e845e..3a8a0a883a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -106,7 +106,7 @@ namespace osu.Game.Overlays Height = player_height, Masking = true, CornerRadius = 5, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(40), diff --git a/osu.Game/Overlays/NotificationManager.cs b/osu.Game/Overlays/NotificationManager.cs index 3ddd85cfcf..05644599dd 100644 --- a/osu.Game/Overlays/NotificationManager.cs +++ b/osu.Game/Overlays/NotificationManager.cs @@ -46,19 +46,19 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Children = new [] + Children = new[] { new NotificationSection { Title = @"Notifications", ClearText = @"Clear All", - AcceptTypes = new [] { typeof(SimpleNotification) }, + AcceptTypes = new[] { typeof(SimpleNotification) }, }, new NotificationSection { Title = @"Running Tasks", ClearText = @"Cancel All", - AcceptTypes = new [] { typeof(ProgressNotification) }, + AcceptTypes = new[] { typeof(ProgressNotification) }, }, } } diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index cb3efaf269..4a16f5c98c 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -238,7 +238,7 @@ namespace osu.Game.Overlays.Notifications set { base.Colour = value; - pulsateLayer.EdgeEffect = new EdgeEffect + pulsateLayer.EdgeEffect = new EdgeEffectParameters { Colour = ((Color4)value).Opacity(0.5f), //todo: avoid cast Type = EdgeEffectType.Glow, diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index d262826fd2..eb2b2dbaae 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -125,6 +125,14 @@ namespace osu.Game.Overlays trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Width), v => displayResolution()); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Height), v => displayResolution()); + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity), v => display(v, "Cursor Sensitivity", v.ToString(@"0.##x"), "Ctrl+Alt+R to reset")); + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.ActiveInputHandlers), + delegate (string v) + { + bool raw = v.Contains("Raw"); + display(raw, "Raw Input", raw ? "enabled" : "disabled", "Ctrl+Alt+R to reset"); + }); + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.WindowMode), v => display(v, "Screen Mode", v.ToString(), "Alt+Enter")); } @@ -245,7 +253,7 @@ namespace osu.Game.Overlays Masking = true; CornerRadius = 3; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = colours.BlueDark.Opacity(glow_strength), Type = EdgeEffectType.Glow, diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index 62801b2ef6..08dba011df 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -41,4 +41,3 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay } } } - diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 11a964d179..43d89eebf0 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Settings.Sections.General set { bounding = value; - Invalidate(Invalidation.Geometry); + Invalidate(Invalidation.MiscGeometry); } } @@ -290,7 +290,7 @@ namespace osu.Game.Overlays.Settings.Sections.General Margin = new MarginPadding { Bottom = 5 }; Masking = true; CornerRadius = 5; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.25f), @@ -326,7 +326,7 @@ namespace osu.Game.Overlays.Settings.Sections.General CornerRadius = 5; ItemsContainer.Padding = new MarginPadding(0); Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.25f), diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 3ceb8d2ff4..01e32b5a1b 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -33,4 +33,3 @@ namespace osu.Game.Overlays.Settings.Sections.General } } } - diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index 5511f827e2..77148986ff 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -22,4 +22,3 @@ namespace osu.Game.Overlays.Settings.Sections } } } - diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index ea9ccd3492..5f8900449a 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics letterboxSettings.ClearTransforms(); letterboxSettings.AutoSizeAxes = isVisible ? Axes.Y : Axes.None; - if(!isVisible) + if (!isVisible) letterboxSettings.ResizeHeightTo(0, transition_duration, EasingTypes.OutQuint); }; letterboxing.TriggerChange(); diff --git a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs index f188f2476c..04a9a4d70c 100644 --- a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs @@ -24,4 +24,3 @@ namespace osu.Game.Overlays.Settings.Sections } } } - diff --git a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs index 311fa072c6..5ebac37cc8 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs @@ -21,9 +21,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input [BackgroundDependencyLoader] private void load(OsuConfigManager osuConfig, FrameworkConfigManager config) { - activeInputHandlers = config.GetBindable(FrameworkSetting.ActiveInputHandlers); - rawInputToggle.Value = activeInputHandlers.Value.Contains("Raw"); - Children = new Drawable[] { new SettingsCheckbox @@ -62,11 +59,17 @@ namespace osu.Game.Overlays.Settings.Sections.Input activeInputHandlers.Value = enabled ? activeInputHandlers.Value.Replace(standard_mouse_handler, raw_mouse_handler) : activeInputHandlers.Value.Replace(raw_mouse_handler, standard_mouse_handler); - - sensitivity.Bindable.Disabled = !enabled; }; - rawInputToggle.TriggerChange(); + activeInputHandlers = config.GetBindable(FrameworkSetting.ActiveInputHandlers); + activeInputHandlers.ValueChanged += handlers => + { + bool raw = handlers.Contains("Raw"); + rawInputToggle.Value = raw; + sensitivity.Bindable.Disabled = !raw; + }; + + activeInputHandlers.TriggerChange(); } private class SensitivitySetting : SettingsSlider diff --git a/osu.Game/Overlays/Settings/Sections/InputSection.cs b/osu.Game/Overlays/Settings/Sections/InputSection.cs index cfa3bc78f0..65df3746b3 100644 --- a/osu.Game/Overlays/Settings/Sections/InputSection.cs +++ b/osu.Game/Overlays/Settings/Sections/InputSection.cs @@ -22,4 +22,3 @@ namespace osu.Game.Overlays.Settings.Sections } } } - diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index 44328ae867..14082aa4db 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -52,4 +52,3 @@ namespace osu.Game.Overlays.Settings } } } - diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index be93fdbac5..0813f1898a 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Settings }, new SidebarScrollContainer { - Children = new [] + Children = new[] { content = new FillFlowContainer { diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 97c27a9ea9..c6ce20f5cf 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -9,6 +9,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; @@ -29,6 +30,8 @@ namespace osu.Game.Overlays protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable users; + private readonly LoadingAnimation loading; + public IEnumerable Users { get { return users; } @@ -68,6 +71,8 @@ namespace osu.Game.Overlays Spacing = new Vector2(10f), }, }; + + Add(loading = new LoadingAnimation()); } [BackgroundDependencyLoader] @@ -83,8 +88,14 @@ namespace osu.Game.Overlays // no this is not the correct data source, but it's something. var request = new GetUsersRequest(); - request.Success += res => Users = res.Select(e => e.User); + request.Success += res => + { + Users = res.Select(e => e.User); + loading.Hide(); + }; + api.Queue(request); + loading.Show(); } public void APIStateChanged(APIAccess api, APIState state) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 5ae88d9049..e2eac477bf 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -172,7 +172,7 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.Both; Masking = true; MaskingSmoothness = 0; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(40), diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs index dd70289f7d..a444a1ec71 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Toolbar { DrawableIcon.Colour = Color4.White; DrawableIcon.Masking = true; - DrawableIcon.EdgeEffect = new EdgeEffect + DrawableIcon.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = new Color4(255, 194, 224, 100), diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 8e610545f5..05f54b5408 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -46,14 +46,14 @@ namespace osu.Game.Overlays.Toolbar Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = new Color4(255, 194, 224, 100), Radius = 15, Roundness = 15, }, - Children = new [] + Children = new[] { new Box { diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index fa668bad60..976164a53e 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Toolbar stateContainer.StateChanged -= stateChanged; } - private void stateChanged(OverlayContainer c, Visibility state) + private void stateChanged(VisibilityContainer c, Visibility state) { switch (state) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index 4e59f87bee..deacfbb9ec 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Toolbar Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, CornerRadius = 4, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Radius = 4, diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index 7c68b0ad83..3669001d72 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -173,7 +173,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X; Width = 1.5f; Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(50), diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 850c640770..2582c68296 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -25,13 +25,13 @@ namespace osu.Game.Screens.Edit protected override void OnEntering(Screen last) { base.OnEntering(last); - Background.Schedule(() => Background.FadeColour(Color4.DarkGray, 500)); + Background.FadeColour(Color4.DarkGray, 500); Beatmap?.Track?.Stop(); } protected override bool OnExiting(Screen next) { - Background.Schedule(() => Background.FadeColour(Color4.White, 500)); + Background.FadeColour(Color4.White, 500); Beatmap?.Track?.Start(); return base.OnExiting(next); } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index fe9f7b4bf6..741fcf80a2 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Menu { Masking = true, MaskingSmoothness = 2, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.2f), @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Menu Scale = new Vector2(0, 1), Size = boxSize, Shear = new Vector2(ButtonSystem.WEDGE_WIDTH / boxSize.Y, 0), - Children = new [] + Children = new[] { new Box { @@ -283,9 +283,9 @@ namespace osu.Game.Screens.Menu public ButtonState State { get { return state; } + set { - if (state == value) return; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 52039a8417..73f1c91be3 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -192,10 +192,8 @@ namespace osu.Game.Screens.Menu public MenuState State { - get - { - return state; - } + get { return state; } + set { if (state == value) return; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 44b7b6bceb..db1f008dcf 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -51,10 +51,7 @@ namespace osu.Game.Screens.Menu public bool Triangles { - set - { - colourAndTriangles.Alpha = value ? 1 : 0; - } + set { colourAndTriangles.Alpha = value ? 1 : 0; } } protected override bool InternalContains(Vector2 screenSpacePos) => logoContainer.Contains(screenSpacePos); @@ -62,10 +59,7 @@ namespace osu.Game.Screens.Menu public bool Ripple { get { return rippleContainer.Alpha > 0; } - set - { - rippleContainer.Alpha = value ? 1 : 0; - } + set { rippleContainer.Alpha = value ? 1 : 0; } } public bool Interactive = true; diff --git a/osu.Game/Screens/Multiplayer/DrawableRoom.cs b/osu.Game/Screens/Multiplayer/DrawableRoom.cs index 7365963085..57f556725d 100644 --- a/osu.Game/Screens/Multiplayer/DrawableRoom.cs +++ b/osu.Game/Screens/Multiplayer/DrawableRoom.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Multiplayer Height = height; CornerRadius = 5; Masking = true; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(40), @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Multiplayer }, avatar = new UpdateableAvatar { - Size = new Vector2(Height - content_padding* 2), + Size = new Vector2(Height - content_padding * 2), Masking = true, CornerRadius = 5f, Margin = new MarginPadding { Left = content_padding * 2, Top = content_padding }, diff --git a/osu.Game/Screens/Multiplayer/Match.cs b/osu.Game/Screens/Multiplayer/Match.cs index 7da6ef800e..ec6a66062d 100644 --- a/osu.Game/Screens/Multiplayer/Match.cs +++ b/osu.Game/Screens/Multiplayer/Match.cs @@ -24,12 +24,12 @@ namespace osu.Game.Screens.Multiplayer { base.OnEntering(last); - Background.Schedule(() => Background.FadeColour(Color4.DarkGray, 500)); + Background.FadeColour(Color4.DarkGray, 500); } protected override bool OnExiting(Screen next) { - Background.Schedule(() => Background.FadeColour(Color4.White, 500)); + Background.FadeColour(Color4.White, 500); return base.OnExiting(next); } } diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 4a10438cdb..921accf6ac 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -54,7 +54,6 @@ namespace osu.Game.Screens.Play.HUD { AutoSizeAxes = Axes.Both, Scale = new Vector2(0.6f), - }); } diff --git a/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs b/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs index 7ba5dfe1b7..82b06482aa 100644 --- a/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play.HUD return; glowColour = value; - fill.EdgeEffect = new EdgeEffect + fill.EdgeEffect = new EdgeEffectParameters { Colour = glowColour.Opacity(base_glow_opacity), Radius = 8, diff --git a/osu.Game/Screens/Play/MenuOverlay.cs b/osu.Game/Screens/Play/MenuOverlay.cs index 424b26350f..8d83dcdda0 100644 --- a/osu.Game/Screens/Play/MenuOverlay.cs +++ b/osu.Game/Screens/Play/MenuOverlay.cs @@ -164,7 +164,7 @@ namespace osu.Game.Screens.Play AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.6f), diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d4b8445ed9..c38ea65f90 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -278,7 +278,6 @@ namespace osu.Game.Screens.Play { if (!pauseContainer.IsPaused) decoupledClock.Start(); - }); pauseContainer.Alpha = 0; diff --git a/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs b/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs index 3e4c0dca5c..91850a99d2 100644 --- a/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs +++ b/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs @@ -79,7 +79,7 @@ namespace osu.Game.Screens.Play.ReplaySettings { Origin = Anchor.Centre, Anchor = Anchor.CentreRight, - Position = new Vector2(-15,0), + Position = new Vector2(-15, 0), Icon = FontAwesome.fa_bars, Scale = new Vector2(0.75f), Action = toggleContentVisibility, diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs index ee11fc0ca6..06c7044049 100644 --- a/osu.Game/Screens/Play/SkipButton.cs +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -232,7 +232,7 @@ namespace osu.Game.Screens.Play AutoSizeAxes = Axes.Both, Origin = Anchor.Centre, Direction = FillDirection.Horizontal, - Children = new [] + Children = new[] { new TextAwesome { Icon = FontAwesome.fa_chevron_right }, new TextAwesome { Icon = FontAwesome.fa_chevron_right }, diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 6b3f81628c..e5b18292ab 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Play double progress = ((audioClock?.CurrentTime ?? Time.Current) - firstHitTime) / (lastHitTime - firstHitTime); - if(progress < 1) + if (progress < 1) { bar.UpdatePosition((float)progress); graph.Progress = (int)(graph.ColumnCount * progress); diff --git a/osu.Game/Screens/Play/SongProgressGraph.cs b/osu.Game/Screens/Play/SongProgressGraph.cs index 4e56f60c31..ea7c465e4d 100644 --- a/osu.Game/Screens/Play/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/SongProgressGraph.cs @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Play { IHasEndTime end = h as IHasEndTime; - int startRange = (int)((h.StartTime - firstHit)/ interval); + int startRange = (int)((h.StartTime - firstHit) / interval); int endRange = (int)(((end?.EndTime > 0 ? end.EndTime : h.StartTime) - firstHit) / interval); for (int i = startRange; i <= endRange; i++) values[i]++; diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 43a8253b53..0b3bcc55a2 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -69,7 +69,7 @@ namespace osu.Game.Screens.Play public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { - if ((invalidation & Invalidation.SizeInParentSpace) > 0) + if ((invalidation & Invalidation.DrawSize) > 0) layout.Invalidate(); return base.Invalidate(invalidation, source, shallPropagate); } diff --git a/osu.Game/Screens/Ranking/ResultModeButton.cs b/osu.Game/Screens/Ranking/ResultModeButton.cs index fc62342860..cc1dbbe444 100644 --- a/osu.Game/Screens/Ranking/ResultModeButton.cs +++ b/osu.Game/Screens/Ranking/ResultModeButton.cs @@ -36,19 +36,6 @@ namespace osu.Game.Screens.Ranking } } - public override bool Active - { - get - { - return base.Active; - } - set - { - base.Active = value; - colouredPart.FadeColour(Active ? activeColour : inactiveColour, 200, EasingTypes.OutQuint); - } - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -60,7 +47,7 @@ namespace osu.Game.Screens.Ranking activeColour = colours.PinkDarker; inactiveColour = OsuColour.Gray(0.8f); - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.4f), Type = EdgeEffectType.Shadow, @@ -104,5 +91,9 @@ namespace osu.Game.Screens.Ranking } }; } + + protected override void OnActivated() => colouredPart.FadeColour(activeColour, 200, EasingTypes.OutQuint); + + protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, EasingTypes.OutQuint); } } diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index f3dae710b2..2523ce05ec 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -71,7 +71,6 @@ namespace osu.Game.Screens.Ranking using (BeginDelayedSequence(transition_time * 0.25f, true)) { - circleOuter.ScaleTo(1, transition_time, EasingTypes.OutQuint); circleOuter.FadeTo(1, transition_time, EasingTypes.OutQuint); @@ -135,7 +134,7 @@ namespace osu.Game.Screens.Ranking circleOuter = new CircularContainer { Size = new Vector2(circle_outer_scale), - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.4f), Type = EdgeEffectType.Shadow, @@ -226,7 +225,7 @@ namespace osu.Game.Screens.Ranking circleInner = new CircularContainer { Size = new Vector2(0.6f), - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.4f), Type = EdgeEffectType.Shadow, diff --git a/osu.Game/Screens/Ranking/ResultsPage.cs b/osu.Game/Screens/Ranking/ResultsPage.cs index 02eae3643b..f02850bf82 100644 --- a/osu.Game/Screens/Ranking/ResultsPage.cs +++ b/osu.Game/Screens/Ranking/ResultsPage.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Ranking }, new CircularContainer { - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = colours.GrayF.Opacity(0.8f), Type = EdgeEffectType.Shadow, @@ -64,7 +64,8 @@ namespace osu.Game.Screens.Ranking Origin = Anchor.Centre, Children = new Drawable[] { - new Box{ + new Box + { RelativeSizeAxes = Axes.Both, Alpha = 0, AlwaysPresent = true @@ -73,7 +74,7 @@ namespace osu.Game.Screens.Ranking }, content = new CircularContainer { - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.2f), Type = EdgeEffectType.Shadow, @@ -87,6 +88,5 @@ namespace osu.Game.Screens.Ranking } }); } - } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 26820fc388..3f8d6af320 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -244,7 +244,7 @@ namespace osu.Game.Screens.Select private BeatmapGroup createGroup(BeatmapSetInfo beatmapSet) { - foreach(var b in beatmapSet.Beatmaps) + foreach (var b in beatmapSet.Beatmaps) { if (b.Metadata == null) b.Metadata = beatmapSet.Metadata; diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index abe54375cc..aefb9901b6 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -47,6 +47,7 @@ namespace osu.Game.Screens.Select public BeatmapInfo Beatmap { get { return beatmap; } + set { if (beatmap == value) return; @@ -79,8 +80,8 @@ namespace osu.Game.Screens.Select lookup.Success += res => { if (beatmap != requestedBeatmap) - //the beatmap has been changed since we started the lookup. - return; + //the beatmap has been changed since we started the lookup. + return; requestedBeatmap.Metrics = res; Schedule(() => updateMetrics(res)); @@ -88,6 +89,7 @@ namespace osu.Game.Screens.Select lookup.Failure += e => updateMetrics(null); api.Queue(lookup); + loading.Show(); } updateMetrics(requestedBeatmap.Metrics, false); @@ -103,6 +105,9 @@ namespace osu.Game.Screens.Select var hasRatings = metrics?.Ratings.Any() ?? false; var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any(); + if (failOnMissing) + loading.Hide(); + if (hasRatings) { var ratings = metrics.Ratings.ToList(); @@ -165,7 +170,7 @@ namespace osu.Game.Screens.Select Direction = FillDirection.Vertical, LayoutDuration = 200, LayoutEasing = EasingTypes.OutQuint, - Children = new [] + Children = new[] { description = new MetadataSegment("Description"), source = new MetadataSegment("Source"), @@ -199,9 +204,9 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Spacing = new Vector2(0,5), + Spacing = new Vector2(0, 5), Padding = new MarginPadding(10), - Children = new [] + Children = new[] { circleSize = new DifficultyRow("Circle Size", 7), drainRate = new DifficultyRow("HP Drain"), @@ -319,11 +324,13 @@ namespace osu.Game.Screens.Select } }, }, - } + }, + loading = new LoadingAnimation() }; } private APIAccess api; + private readonly LoadingAnimation loading; [BackgroundDependencyLoader] private void load(OsuColour colour, APIAccess api) @@ -479,7 +486,7 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Spacing = new Vector2(5,0), + Spacing = new Vector2(5, 0), Margin = new MarginPadding { Top = header.TextSize } } }; diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 2d002597ab..01a233e9a2 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Select Masking = true; BorderColour = new Color4(221, 255, 255, 255); BorderThickness = 2.5f; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = new Color4(130, 204, 255, 150), diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 7d97581a29..e560cfe413 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -12,6 +12,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Threading; using osu.Game.Database; +using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Scoring; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -25,6 +26,8 @@ namespace osu.Game.Screens.Select.Leaderboards public Action ScoreSelected; + private readonly LoadingAnimation loading; + private IEnumerable scores; public IEnumerable Scores { @@ -86,6 +89,7 @@ namespace osu.Game.Screens.Select.Leaderboards }, }, }, + loading = new LoadingAnimation() }; } @@ -117,6 +121,7 @@ namespace osu.Game.Screens.Select.Leaderboards } private GetScoresRequest getScoresRequest; + private void updateScores() { if (!IsLoaded) return; @@ -126,8 +131,14 @@ namespace osu.Game.Screens.Select.Leaderboards if (api == null || Beatmap == null) return; + loading.Show(); + getScoresRequest = new GetScoresRequest(Beatmap); - getScoresRequest.Success += r => Scores = r.Scores; + getScoresRequest.Success += r => + { + Scores = r.Scores; + loading.Hide(); + }; api.Queue(getScoresRequest); } diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index c5fa0a5011..fd26caf2b6 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -147,7 +147,7 @@ namespace osu.Game.Screens.Select.Leaderboards CornerRadius = corner_radius, Masking = true, OnLoadComplete = d => d.FadeInFromZero(200), - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Radius = 1, diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 182f778dd4..7aaed9b360 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -99,7 +99,7 @@ namespace osu.Game.Screens.Select.Options RelativeSizeAxes = Axes.Both, Shear = new Vector2(0.2f, 0f), Masking = true, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.2f), diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index 05bf3a250f..483841122b 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -335,7 +335,6 @@ namespace osu.Game.Screens.Tournament { Logger.Error(ex, "Failed to read last drawings results."); } - } else { diff --git a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs index 3eea239f55..31043a411b 100644 --- a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs +++ b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs @@ -83,6 +83,7 @@ namespace osu.Game.Screens.Tournament private ScrollState scrollState { get { return _scrollState; } + set { if (_scrollState == value) @@ -329,6 +330,7 @@ namespace osu.Game.Screens.Tournament public bool Selected { get { return selected; } + set { selected = value; diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index bdfe6d1c8e..a031cbe64a 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -34,7 +34,7 @@ namespace osu.Game.Users Height = height - status_height; Masking = true; CornerRadius = 5; - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.25f), @@ -68,7 +68,7 @@ namespace osu.Game.Users User = user, Masking = true, CornerRadius = 5, - EdgeEffect = new EdgeEffect + EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.25f), diff --git a/osu.Game/Users/UserStatus.cs b/osu.Game/Users/UserStatus.cs index 461008db0f..37b796630b 100644 --- a/osu.Game/Users/UserStatus.cs +++ b/osu.Game/Users/UserStatus.cs @@ -48,7 +48,7 @@ namespace osu.Game.Users public override string Message => @"Solo Game"; } - public class UserStatusMultiplayerGame: UserStatusBusy + public class UserStatusMultiplayerGame : UserStatusBusy { public override string Message => @"Multiplaying"; } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1ebbb4adf3..20785463ea 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -39,11 +39,13 @@ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll + + $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + True - - $(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll + + True + $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll @@ -74,8 +76,12 @@ + + + + diff --git a/osu.Game/packages.config b/osu.Game/packages.config index d51b0033ed..434f9328ea 100644 --- a/osu.Game/packages.config +++ b/osu.Game/packages.config @@ -6,8 +6,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - - + +