diff --git a/README.md b/README.md
index 016bd7d922..8f922f74a7 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
# osu!
-[](https://ci.appveyor.com/project/peppy/osu)
+[](https://github.com/ppy/osu/actions/workflows/ci.yml)
[](https://github.com/ppy/osu/releases/latest)
[](https://www.codefactor.io/repository/github/ppy/osu)
[](https://discord.gg/ppy)
diff --git a/osu.Android.props b/osu.Android.props
index f8cd4e41d4..7a0a542ee9 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -51,8 +51,8 @@
-
-
+
+
diff --git a/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs b/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs
new file mode 100644
index 0000000000..c345320e28
--- /dev/null
+++ b/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs
@@ -0,0 +1,90 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Linq;
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.Colours
+{
+ public class TestSceneStarDifficultyColours : OsuTestScene
+ {
+ [Resolved]
+ private OsuColour colours { get; set; }
+
+ [Test]
+ public void TestColours()
+ {
+ AddStep("load colour displays", () =>
+ {
+ Child = new FillFlowContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5f),
+ ChildrenEnumerable = Enumerable.Range(0, 10).Select(i => new FillFlowContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(10f),
+ ChildrenEnumerable = Enumerable.Range(0, 10).Select(j =>
+ {
+ var colour = colours.ForStarDifficulty(1f * i + 0.1f * j);
+
+ return new FillFlowContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0f, 10f),
+ Children = new Drawable[]
+ {
+ new CircularContainer
+ {
+ Masking = true,
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Size = new Vector2(75f, 25f),
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = colour,
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Colour = OsuColour.ForegroundTextColourFor(colour),
+ Text = colour.ToHex(),
+ },
+ }
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Text = $"*{(1f * i + 0.1f * j):0.00}",
+ }
+ }
+ };
+ })
+ })
+ };
+ });
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index c62b803d1a..3210ef0112 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -93,20 +93,20 @@ namespace osu.Game.Beatmaps.Drawables
new CircularContainer
{
RelativeSizeAxes = Axes.Both,
- Scale = new Vector2(0.84f),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Masking = true,
EdgeEffect = new EdgeEffectParameters
{
- Colour = Color4.Black.Opacity(0.08f),
+ Colour = Color4.Black.Opacity(0.06f),
+
Type = EdgeEffectType.Shadow,
- Radius = 5,
+ Radius = 3,
},
Child = background = new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.ForDifficultyRating(beatmap.DifficultyRating) // Default value that will be re-populated once difficulty calculation completes
+ Colour = colours.ForStarDifficulty(beatmap.StarDifficulty) // Default value that will be re-populated once difficulty calculation completes
},
},
new ConstrainedIconContainer
@@ -124,7 +124,7 @@ namespace osu.Game.Beatmaps.Drawables
else
difficultyBindable.Value = new StarDifficulty(beatmap.StarDifficulty, 0);
- difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForDifficultyRating(difficulty.NewValue.DifficultyRating));
+ difficultyBindable.BindValueChanged(difficulty => background.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars));
}
public ITooltip GetCustomTooltip() => new DifficultyIconTooltip();
@@ -271,7 +271,7 @@ namespace osu.Game.Beatmaps.Drawables
starDifficulty.BindValueChanged(difficulty =>
{
starRating.Text = $"{difficulty.NewValue.Stars:0.##}";
- difficultyFlow.Colour = colours.ForDifficultyRating(difficulty.NewValue.DifficultyRating, true);
+ difficultyFlow.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars);
}, true);
return true;
diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs
index c0bc8fdb76..1f87c06dd2 100644
--- a/osu.Game/Graphics/OsuColour.cs
+++ b/osu.Game/Graphics/OsuColour.cs
@@ -1,11 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
+using osu.Game.Utils;
using osuTK.Graphics;
namespace osu.Game.Graphics
@@ -15,31 +17,52 @@ namespace osu.Game.Graphics
public static Color4 Gray(float amt) => new Color4(amt, amt, amt, 1f);
public static Color4 Gray(byte amt) => new Color4(amt, amt, amt, 255);
+ ///
+ /// Retrieves the colour for a .
+ ///
+ ///
+ /// Sourced from the @diff-{rating} variables in https://github.com/ppy/osu-web/blob/71fbab8936d79a7929d13854f5e854b4f383b236/resources/assets/less/variables.less.
+ ///
public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterColour = false)
{
switch (difficulty)
{
case DifficultyRating.Easy:
- return Green;
+ return Color4Extensions.FromHex("4ebfff");
- default:
case DifficultyRating.Normal:
- return Blue;
+ return Color4Extensions.FromHex("66ff91");
case DifficultyRating.Hard:
- return Yellow;
+ return Color4Extensions.FromHex("f7e85d");
case DifficultyRating.Insane:
- return Pink;
+ return Color4Extensions.FromHex("ff7e68");
case DifficultyRating.Expert:
- return PurpleLight;
+ return Color4Extensions.FromHex("fe3c71");
case DifficultyRating.ExpertPlus:
- return useLighterColour ? Gray9 : Color4Extensions.FromHex("#121415");
+ return Color4Extensions.FromHex("6662dd");
+
+ default:
+ throw new ArgumentOutOfRangeException(nameof(difficulty));
}
}
+ public Color4 ForStarDifficulty(double starDifficulty) => ColourUtils.SampleFromLinearGradient(new[]
+ {
+ (1.5f, Color4Extensions.FromHex("4fc0ff")),
+ (2.0f, Color4Extensions.FromHex("4fffd5")),
+ (2.5f, Color4Extensions.FromHex("7cff4f")),
+ (3.25f, Color4Extensions.FromHex("f6f05c")),
+ (4.5f, Color4Extensions.FromHex("ff8068")),
+ (6.0f, Color4Extensions.FromHex("ff3c71")),
+ (7.0f, Color4Extensions.FromHex("6563de")),
+ (8.0f, Color4Extensions.FromHex("18158e")),
+ (8.0f, Color4.Black),
+ }, (float)Math.Round(starDifficulty, 2, MidpointRounding.AwayFromZero));
+
///
/// Retrieves the colour for a .
///
diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
index b97f12df02..61dd5fb2d9 100644
--- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs
+++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
@@ -288,7 +288,7 @@ namespace osu.Game.Graphics.UserInterface
},
};
- AddInternal(new HoverSounds());
+ AddInternal(new HoverClickSounds());
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs
index e7bf4f66ee..a16adcbd57 100644
--- a/osu.Game/Graphics/UserInterface/OsuMenu.cs
+++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs
@@ -1,6 +1,9 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@@ -13,6 +16,12 @@ namespace osu.Game.Graphics.UserInterface
{
public class OsuMenu : Menu
{
+ private Sample sampleOpen;
+ private Sample sampleClose;
+
+ // todo: this shouldn't be required after https://github.com/ppy/osu-framework/issues/4519 is fixed.
+ private bool wasOpened;
+
public OsuMenu(Direction direction, bool topLevelMenu = false)
: base(direction, topLevelMenu)
{
@@ -22,8 +31,30 @@ namespace osu.Game.Graphics.UserInterface
ItemsContainer.Padding = new MarginPadding(5);
}
- protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint);
- protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint);
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio)
+ {
+ sampleOpen = audio.Samples.Get(@"UI/dropdown-open");
+ sampleClose = audio.Samples.Get(@"UI/dropdown-close");
+ }
+
+ protected override void AnimateOpen()
+ {
+ if (!TopLevelMenu && !wasOpened)
+ sampleOpen?.Play();
+
+ this.FadeIn(300, Easing.OutQuint);
+ wasOpened = true;
+ }
+
+ protected override void AnimateClose()
+ {
+ if (!TopLevelMenu && wasOpened)
+ sampleClose?.Play();
+
+ this.FadeOut(300, Easing.OutQuint);
+ wasOpened = false;
+ }
protected override void UpdateSize(Vector2 newSize)
{
diff --git a/osu.Game/Online/Multiplayer/MultiplayerRoomSettings.cs b/osu.Game/Online/Multiplayer/MultiplayerRoomSettings.cs
index 706bc750d3..001cf2aa93 100644
--- a/osu.Game/Online/Multiplayer/MultiplayerRoomSettings.cs
+++ b/osu.Game/Online/Multiplayer/MultiplayerRoomSettings.cs
@@ -41,7 +41,7 @@ namespace osu.Game.Online.Multiplayer
public string Password { get; set; } = string.Empty;
[Key(8)]
- public MatchType MatchType { get; set; }
+ public MatchType MatchType { get; set; } = MatchType.HeadToHead;
public bool Equals(MultiplayerRoomSettings other)
=> BeatmapID == other.BeatmapID
diff --git a/osu.Game/Overlays/News/Sidebar/MonthSection.cs b/osu.Game/Overlays/News/Sidebar/MonthSection.cs
index cd6ab224a9..948f312f15 100644
--- a/osu.Game/Overlays/News/Sidebar/MonthSection.cs
+++ b/osu.Game/Overlays/News/Sidebar/MonthSection.cs
@@ -79,8 +79,6 @@ namespace osu.Game.Overlays.News.Sidebar
private readonly SpriteIcon icon;
- protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverSounds();
-
public DropdownHeader(int month, int year)
{
var date = new DateTime(year, month, 1);
diff --git a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs
index efc93ffeb0..622643f5ea 100644
--- a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs
+++ b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs
@@ -91,8 +91,8 @@ namespace osu.Game.Screens.OnlinePlay.Components
maxDisplay.Current.Value = maxDifficulty;
maxDisplay.Alpha = Precision.AlmostEquals(minDifficulty.Stars, maxDifficulty.Stars) ? 0 : 1;
- minBackground.Colour = colours.ForDifficultyRating(minDifficulty.DifficultyRating, true);
- maxBackground.Colour = colours.ForDifficultyRating(maxDifficulty.DifficultyRating, true);
+ minBackground.Colour = colours.ForStarDifficulty(minDifficulty.Stars);
+ maxBackground.Colour = colours.ForStarDifficulty(maxDifficulty.Stars);
}
}
}
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs
index 53af2fe5c7..3a56be64e0 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs
@@ -5,6 +5,8 @@ using System;
using System.Collections.Generic;
using osu.Framework;
using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions;
@@ -43,6 +45,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
public event Action StateChanged;
+ protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverSounds();
+
private Drawable selectionBox;
[Resolved(canBeNull: true)]
@@ -61,6 +65,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
private SelectionState state;
+ private Sample sampleSelect;
+ private Sample sampleJoin;
+
public SelectionState State
{
get => state;
@@ -147,7 +154,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OsuColour colours, AudioManager audio)
{
Children = new Drawable[]
{
@@ -337,6 +344,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
}
},
};
+
+ sampleSelect = audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select");
+ sampleJoin = audio.Samples.Get($@"UI/{HoverSampleSet.Submit.GetDescription()}-select");
}
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
@@ -398,22 +408,25 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
{
}
- protected override bool ShouldBeConsideredForInput(Drawable child) => state == SelectionState.Selected;
+ protected override bool ShouldBeConsideredForInput(Drawable child) => state == SelectionState.Selected || child is HoverSounds;
protected override bool OnClick(ClickEvent e)
{
if (Room != selectedRoom.Value)
{
+ sampleSelect?.Play();
selectedRoom.Value = Room;
return true;
}
if (Room.HasPassword.Value)
{
+ sampleJoin?.Play();
this.ShowPopover();
return true;
}
+ sampleJoin?.Play();
lounge?.Join(Room, null);
return base.OnClick(e);
diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs
index c72fa24b67..c6f9b0f207 100644
--- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs
+++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs
@@ -30,8 +30,6 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components
AddItem(MatchType.HeadToHead);
AddItem(MatchType.TeamVersus);
- // TODO: remove after osu-web is updated to set the correct default type.
- AddItem(MatchType.Playlists);
}
private class GameTypePickerItem : DisableableTabItem
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs
index 043cce4630..b54a4a7726 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs
@@ -96,7 +96,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
base.LoadComplete();
- ((IBindable)leaderboard.Expanded).BindTo(IsBreakTime);
+ ((IBindable)leaderboard.Expanded).BindTo(HUDOverlay.ShowHud);
}
protected override void StartGameplay()
diff --git a/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs b/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs
index e59a0de316..2b86100be8 100644
--- a/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs
+++ b/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs
@@ -23,6 +23,7 @@ namespace osu.Game.Screens.Ranking.Expanded
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue
{
private Box background;
+ private FillFlowContainer content;
private OsuTextFlowContainer textFlow;
[Resolved]
@@ -64,7 +65,7 @@ namespace osu.Game.Screens.Ranking.Expanded
},
}
},
- new FillFlowContainer
+ content = new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = 8, Vertical = 4 },
@@ -78,7 +79,6 @@ namespace osu.Game.Screens.Ranking.Expanded
Origin = Anchor.CentreLeft,
Size = new Vector2(7),
Icon = FontAwesome.Solid.Star,
- Colour = Color4.Black
},
textFlow = new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
{
@@ -107,21 +107,20 @@ namespace osu.Game.Screens.Ranking.Expanded
string fractionPart = starRatingParts[1];
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
- var rating = Current.Value.DifficultyRating;
+ var stars = Current.Value.Stars;
- background.Colour = colours.ForDifficultyRating(rating, true);
+ background.Colour = colours.ForStarDifficulty(stars);
+ content.Colour = stars >= 6.5 ? colours.Orange1 : Color4.Black;
textFlow.Clear();
textFlow.AddText($"{wholePart}", s =>
{
- s.Colour = Color4.Black;
s.Font = s.Font.With(size: 14);
s.UseFullGlyphHeight = false;
});
textFlow.AddText($"{separator}{fractionPart}", s =>
{
- s.Colour = Color4.Black;
s.Font = s.Font.With(size: 7);
s.UseFullGlyphHeight = false;
});
diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
index 763c27bcbb..3779523094 100644
--- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs
+++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
@@ -503,7 +503,7 @@ namespace osu.Game.Screens.Select
{
const float full_opacity_ratio = 0.7f;
- var difficultyColour = colours.ForDifficultyRating(difficulty.DifficultyRating);
+ var difficultyColour = colours.ForStarDifficulty(difficulty.Stars);
Children = new Drawable[]
{
diff --git a/osu.Game/Utils/ColourUtils.cs b/osu.Game/Utils/ColourUtils.cs
new file mode 100644
index 0000000000..515963971d
--- /dev/null
+++ b/osu.Game/Utils/ColourUtils.cs
@@ -0,0 +1,37 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Framework.Utils;
+using osuTK.Graphics;
+
+namespace osu.Game.Utils
+{
+ public static class ColourUtils
+ {
+ ///
+ /// Samples from a given linear gradient at a certain specified point.
+ ///
+ /// The gradient, defining the colour stops and their positions (in [0-1] range) in the gradient.
+ /// The point to sample the colour at.
+ /// A sampled from the linear gradient.
+ public static Color4 SampleFromLinearGradient(IReadOnlyList<(float position, Color4 colour)> gradient, float point)
+ {
+ if (point < gradient[0].position)
+ return gradient[0].colour;
+
+ for (int i = 0; i < gradient.Count - 1; i++)
+ {
+ var startStop = gradient[i];
+ var endStop = gradient[i + 1];
+
+ if (point >= endStop.position)
+ continue;
+
+ return Interpolation.ValueAt(point, startStop.colour, endStop.colour, startStop.position, endStop.position);
+ }
+
+ return gradient[^1].colour;
+ }
+ }
+}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index ec59b28ceb..0a6522f15e 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -36,8 +36,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
diff --git a/osu.iOS.props b/osu.iOS.props
index bcc4b5f254..00222877f1 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -70,8 +70,8 @@
-
-
+
+
@@ -93,7 +93,7 @@
-
+