diff --git a/osu.Game.Modes.Catch/CatchRuleset.cs b/osu.Game.Modes.Catch/CatchRuleset.cs index 9ee0e2c4c3..cebc7967c4 100644 --- a/osu.Game.Modes.Catch/CatchRuleset.cs +++ b/osu.Game.Modes.Catch/CatchRuleset.cs @@ -2,6 +2,7 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Game.Graphics; using osu.Game.Modes.Catch.UI; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.Objects; @@ -18,6 +19,8 @@ namespace osu.Game.Modes.Catch protected override PlayMode PlayMode => PlayMode.Catch; + public override FontAwesome Icon => FontAwesome.fa_osu_fruits_o; + public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => null; public override HitObjectParser CreateHitObjectParser() => new OsuHitObjectParser(); diff --git a/osu.Game.Modes.Mania/ManiaRuleset.cs b/osu.Game.Modes.Mania/ManiaRuleset.cs index 6671b0efaf..be444adb99 100644 --- a/osu.Game.Modes.Mania/ManiaRuleset.cs +++ b/osu.Game.Modes.Mania/ManiaRuleset.cs @@ -2,6 +2,7 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Game.Graphics; using osu.Game.Modes.Mania.UI; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu; @@ -19,6 +20,8 @@ namespace osu.Game.Modes.Mania protected override PlayMode PlayMode => PlayMode.Mania; + public override FontAwesome Icon => FontAwesome.fa_osu_mania_o; + public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => null; public override HitObjectParser CreateHitObjectParser() => new OsuHitObjectParser(); diff --git a/osu.Game.Modes.Osu/OsuRuleset.cs b/osu.Game.Modes.Osu/OsuRuleset.cs index 259a8c3880..76e3bacb65 100644 --- a/osu.Game.Modes.Osu/OsuRuleset.cs +++ b/osu.Game.Modes.Osu/OsuRuleset.cs @@ -2,6 +2,9 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Graphics; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.UI; @@ -15,6 +18,24 @@ namespace osu.Game.Modes.Osu public override HitRenderer CreateHitRendererWith(List objects) => new OsuHitRenderer { Objects = objects }; + public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] + { + new BeatmapStatistic + { + Name = @"Circle count", + Content = beatmap.Beatmap.HitObjects.Count(h => h is HitCircle).ToString(), + Icon = FontAwesome.fa_dot_circle_o + }, + new BeatmapStatistic + { + Name = @"Slider count", + Content = beatmap.Beatmap.HitObjects.Count(h => h is Slider).ToString(), + Icon = FontAwesome.fa_circle_o + } + }; + + public override FontAwesome Icon => FontAwesome.fa_osu_osu_o; + public override HitObjectParser CreateHitObjectParser() => new OsuHitObjectParser(); public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => new OsuScoreProcessor(hitObjectCount); diff --git a/osu.Game.Modes.Taiko/TaikoRuleset.cs b/osu.Game.Modes.Taiko/TaikoRuleset.cs index b8a066bc8b..f844db0169 100644 --- a/osu.Game.Modes.Taiko/TaikoRuleset.cs +++ b/osu.Game.Modes.Taiko/TaikoRuleset.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using osu.Game.Graphics; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.UI; @@ -19,6 +20,8 @@ namespace osu.Game.Modes.Taiko protected override PlayMode PlayMode => PlayMode.Taiko; + public override FontAwesome Icon => FontAwesome.fa_osu_taiko_o; + public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => null; public override HitObjectParser CreateHitObjectParser() => new OsuHitObjectParser(); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index fcdef1ce39..7151a13b74 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -2,6 +2,7 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using OpenTK.Graphics; using osu.Game.Beatmaps.Timing; using osu.Game.Database; @@ -16,6 +17,14 @@ namespace osu.Game.Beatmaps public List HitObjects { get; set; } public List ControlPoints { get; set; } public List ComboColors { get; set; } + public double BPMMaximum => 60000 / ControlPoints.Where(c => c.BeatLength != 0).OrderBy(c => c.BeatLength).First().BeatLength; + public double BPMMinimum => 60000 / ControlPoints.Where(c => c.BeatLength != 0).OrderByDescending(c => c.BeatLength).First().BeatLength; + public double BPMMode => BPMAt(ControlPoints.Where(c => c.BeatLength != 0).GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).First().First().Time); + + public double BPMAt(double time) + { + return 60000 / BeatLengthAt(time); + } public double BeatLengthAt(double time, bool applyMultipliers = false) { diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 6155e7779f..8bacbf4cc9 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -80,6 +80,7 @@ namespace osu.Game.Beatmaps.Drawables }).ToList(); BeatmapSet = set; + Header.AddDifficultyIcons(BeatmapPanels); } private void headerGainedSelection(BeatmapSetHeader panel) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index ed5db58418..ed402858a6 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; using osu.Framework.Input; +using osu.Game.Modes; namespace osu.Game.Beatmaps.Drawables { @@ -83,7 +84,7 @@ namespace osu.Game.Beatmaps.Drawables Origin = Anchor.CentreLeft, Children = new Drawable[] { - new DifficultyIcon(FontAwesome.fa_dot_circle_o, new Color4(159, 198, 0, 255)) + new DifficultyIcon(beatmap) { Scale = new Vector2(1.8f), Anchor = Anchor.CentreLeft, @@ -130,7 +131,7 @@ namespace osu.Game.Beatmaps.Drawables }, } }, - new StarCounter { Count = beatmap.BaseDifficulty?.OverallDifficulty ?? 5, StarSize = 8 } + new StarCounter { Count = beatmap.StarDifficulty, StarSize = 8 } } } } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs index 99942de133..b15942c5bb 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs @@ -2,6 +2,7 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -23,6 +24,7 @@ namespace osu.Game.Beatmaps.Drawables private OsuConfigManager config; private Bindable preferUnicode; private WorkingBeatmap beatmap; + private FlowContainer difficultyIcons; public BeatmapSetHeader(WorkingBeatmap beatmap) { @@ -56,15 +58,10 @@ namespace osu.Game.Beatmaps.Drawables TextSize = 17, Shadow = true, }, - new FlowContainer + difficultyIcons = new FlowContainer { Margin = new MarginPadding { Top = 5 }, AutoSizeAxes = Axes.Both, - Children = new[] - { - new DifficultyIcon(FontAwesome.fa_dot_circle_o, new Color4(159, 198, 0, 255)), - new DifficultyIcon(FontAwesome.fa_dot_circle_o, new Color4(246, 101, 166, 255)), - } } } } @@ -177,5 +174,11 @@ namespace osu.Game.Beatmaps.Drawables }); } } + + public void AddDifficultyIcons(IEnumerable panels) + { + foreach (var p in panels) + difficultyIcons.Add(new DifficultyIcon(p.Beatmap)); + } } } \ No newline at end of file diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 4bb02d53c4..0d1a3b7320 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -1,9 +1,14 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Game.Database; using osu.Game.Graphics; +using osu.Game.Modes; using OpenTK; using OpenTK.Graphics; @@ -11,20 +16,76 @@ namespace osu.Game.Beatmaps.Drawables { class DifficultyIcon : Container { - public DifficultyIcon(FontAwesome icon, Color4 color) + private readonly BeatmapInfo beatmap; + private OsuColour palette; + + public DifficultyIcon(BeatmapInfo beatmap) { + this.beatmap = beatmap; const float size = 20; Size = new Vector2(size); - Children = new[] + } + + [BackgroundDependencyLoader] + private void load(OsuColour palette) + { + this.palette = palette; + + Children = new[] { new TextAwesome { Anchor = Anchor.Centre, - TextSize = size, - Colour = color, - Icon = icon + TextSize = Size.X, + Colour = getColour(beatmap), + Icon = FontAwesome.fa_circle + }, + new TextAwesome + { + Anchor = Anchor.Centre, + TextSize = Size.X, + Colour = Color4.White, + Icon = Ruleset.GetRuleset(beatmap.Mode).Icon } - }; + }; + } + + enum DifficultyRating + { + Easy, + Normal, + Hard, + Insane, + Expert + } + + private DifficultyRating getDifficultyRating(BeatmapInfo beatmap) + { + var rating = beatmap.StarDifficulty; + + if (rating < 1.5) return DifficultyRating.Easy; + if (rating < 2.25) return DifficultyRating.Normal; + if (rating < 3.75) return DifficultyRating.Hard; + if (rating < 5.25) return DifficultyRating.Insane; + return DifficultyRating.Expert; + } + + private Color4 getColour(BeatmapInfo beatmap) + { + switch (getDifficultyRating(beatmap)) + { + case DifficultyRating.Easy: + return palette.Green; + default: + case DifficultyRating.Normal: + return palette.Yellow; + case DifficultyRating.Hard: + return palette.Pink; + case DifficultyRating.Insane: + return palette.Purple; + case DifficultyRating.Expert: + return palette.Gray0; + } } } } \ No newline at end of file diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index e0134fcf41..86c3985436 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -17,7 +17,6 @@ namespace osu.Game.Configuration Set(OsuConfig.MouseSpeed, 1.0); Set(OsuConfig.Username, string.Empty); - Set(OsuConfig.Password, string.Empty); Set(OsuConfig.Token, string.Empty); Set(OsuConfig.PlayMode, PlayMode.Osu); @@ -144,8 +143,6 @@ namespace osu.Game.Configuration Set(OsuConfig.HiddenShowFirstApproach, true); Set(OsuConfig.ComboColourSliderBall, true); Set(OsuConfig.AlternativeChatFont, false); - Set(OsuConfig.Password, string.Empty); - Set(OsuConfig.Username, string.Empty); Set(OsuConfig.DisplayStarsMaximum, 10.0, 0.0, 10.0); Set(OsuConfig.DisplayStarsMinimum, 0.0, 0.0, 10.0); Set(OsuConfig.AudioDevice, string.Empty); @@ -171,6 +168,16 @@ namespace osu.Game.Configuration Set(OsuConfig.CanForceOptimusCompatibility, true); Set(OsuConfig.ConfineMouse, Get(OsuConfig.ConfineMouseToFullscreen) ? ConfineMouseMode.Fullscreen : ConfineMouseMode.Never); + + + GetBindable(OsuConfig.SavePassword).ValueChanged += delegate + { + if (Get(OsuConfig.SavePassword)) Set(OsuConfig.SaveUsername, true); + }; + GetBindable(OsuConfig.SaveUsername).ValueChanged += delegate + { + if (!Get(OsuConfig.SaveUsername)) Set(OsuConfig.SavePassword, false); + }; #pragma warning restore CS0612 // Type or member is obsolete } @@ -314,7 +321,6 @@ namespace osu.Game.Configuration HiddenShowFirstApproach, ComboColourSliderBall, AlternativeChatFont, - Password, Username, DisplayStarsMaximum, DisplayStarsMinimum, diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index ef5f00b634..002a883ec5 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -73,6 +73,8 @@ namespace osu.Game.Database // Metadata public string Version { get; set; } + public float StarDifficulty => BaseDifficulty?.OverallDifficulty ?? 5; //todo: implement properly + public bool Equals(BeatmapInfo other) { return ID == other?.ID; diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 1ab5ec8f7c..2d434fb9b4 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using OpenTK.Graphics; using osu.Framework.Graphics.Colour; @@ -17,11 +18,23 @@ namespace osu.Game.Graphics private static Color4 FromHex(string hex) { - return new Color4( - Convert.ToByte(hex.Substring(0, 2), 16), - Convert.ToByte(hex.Substring(2, 2), 16), - Convert.ToByte(hex.Substring(4, 2), 16), - 255); + switch (hex.Length) + { + default: + throw new Exception(@"Invalid hex string length!"); + case 3: + return new Color4( + (byte)(Convert.ToByte(hex.Substring(0, 1), 16) * 17), + (byte)(Convert.ToByte(hex.Substring(1, 1), 16) * 17), + (byte)(Convert.ToByte(hex.Substring(2, 1), 16) * 17), + 255); + case 6: + return new Color4( + Convert.ToByte(hex.Substring(0, 2), 16), + Convert.ToByte(hex.Substring(2, 2), 16), + Convert.ToByte(hex.Substring(4, 2), 16), + 255); + } } // See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less @@ -56,6 +69,23 @@ namespace osu.Game.Graphics public Color4 GreenDark = FromHex(@"668800"); public Color4 GreenDarker = FromHex(@"445500"); + public Color4 Gray0 = FromHex(@"000"); + public Color4 Gray1 = FromHex(@"111"); + public Color4 Gray2 = FromHex(@"222"); + public Color4 Gray3 = FromHex(@"333"); + public Color4 Gray4 = FromHex(@"444"); + public Color4 Gray5 = FromHex(@"555"); + public Color4 Gray6 = FromHex(@"666"); + public Color4 Gray7 = FromHex(@"777"); + public Color4 Gray8 = FromHex(@"888"); + public Color4 Gray9 = FromHex(@"999"); + public Color4 GrayA = FromHex(@"aaa"); + public Color4 GrayB = FromHex(@"bbb"); + public Color4 GrayC = FromHex(@"ccc"); + public Color4 GrayD = FromHex(@"ddd"); + public Color4 GrayE = FromHex(@"eee"); + public Color4 GrayF = FromHex(@"fff"); + public Color4 Red = FromHex(@"fc4549"); } } diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index d246b421a2..7663c74f95 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -25,7 +25,7 @@ namespace osu.Game.Graphics.UserInterface private const double transform_time = 600; private const int pulse_length = 250; - private const float shear = 0.1f; + private const float shear = 0.15f; public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); diff --git a/osu.Game/Modes/Ruleset.cs b/osu.Game/Modes/Ruleset.cs index e0f4ce4e98..a587f82daa 100644 --- a/osu.Game/Modes/Ruleset.cs +++ b/osu.Game/Modes/Ruleset.cs @@ -4,20 +4,28 @@ using System.Collections.Generic; using osu.Game.Modes.Objects; using osu.Game.Modes.UI; -using System.Reflection; -using osu.Framework.Extensions; using System; using System.Collections.Concurrent; -using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Graphics; namespace osu.Game.Modes { + public class BeatmapStatistic + { + public FontAwesome Icon; + public string Content; + public string Name; + } + public abstract class Ruleset { private static ConcurrentDictionary availableRulesets = new ConcurrentDictionary(); public abstract ScoreOverlay CreateScoreOverlay(); + public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; + public abstract ScoreProcessor CreateScoreProcessor(int hitObjectCount); public abstract HitRenderer CreateHitRendererWith(List objects); @@ -28,6 +36,8 @@ namespace osu.Game.Modes protected abstract PlayMode PlayMode { get; } + public virtual FontAwesome Icon => FontAwesome.fa_question_circle; + public static Ruleset GetRuleset(PlayMode mode) { Type type; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a853e93879..31cee2ed39 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -70,7 +70,6 @@ namespace osu.Game Dependencies.Cache(API = new APIAccess { Username = LocalConfig.Get(OsuConfig.Username), - Password = LocalConfig.Get(OsuConfig.Password), Token = LocalConfig.Get(OsuConfig.Token) }); @@ -83,7 +82,6 @@ namespace osu.Game { case APIState.Online: LocalConfig.Set(OsuConfig.Username, LocalConfig.Get(OsuConfig.SaveUsername) ? API.Username : string.Empty); - LocalConfig.Set(OsuConfig.Password, LocalConfig.Get(OsuConfig.SavePassword) ? API.Password : string.Empty); break; } } @@ -119,7 +117,7 @@ namespace osu.Game //refresh token may have changed. if (LocalConfig != null && API != null) { - LocalConfig.Set(OsuConfig.Token, API.Token); + LocalConfig.Set(OsuConfig.Token, LocalConfig.Get(OsuConfig.SavePassword) ? API.Token : string.Empty); LocalConfig.Save(); } diff --git a/osu.Game/Overlays/Options/General/LoginOptions.cs b/osu.Game/Overlays/Options/General/LoginOptions.cs index 03789c59c9..333b794d58 100644 --- a/osu.Game/Overlays/Options/General/LoginOptions.cs +++ b/osu.Game/Overlays/Options/General/LoginOptions.cs @@ -11,14 +11,12 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; - +using osu.Game.Configuration; + namespace osu.Game.Overlays.Options.General { public class LoginOptions : OptionsSubsection, IOnlineComponent { - private Container loginForm; - - private Action performLogout; protected override string Header => "Sign In"; [BackgroundDependencyLoader(permitNulls: true)] @@ -76,30 +74,11 @@ namespace osu.Game.Overlays.Options.General class LoginForm : FlowContainer { private TextBox username; - private TextBox password; + private PasswordTextBox password; private APIAccess api; - public LoginForm() - { - Direction = FlowDirection.VerticalOnly; - AutoSizeAxes = Axes.Y; - RelativeSizeAxes = Axes.X; - Spacing = new Vector2(0, 5); - // TODO: Wire things up - Children = new Drawable[] - { - new SpriteText { Text = "Username" }, - username = new TextBox { Height = 20, RelativeSizeAxes = Axes.X, Text = api?.Username ?? string.Empty }, - new SpriteText { Text = "Password" }, - password = new PasswordTextBox { Height = 20, RelativeSizeAxes = Axes.X }, - new OsuButton - { - RelativeSizeAxes = Axes.X, - Text = "Log in", - Action = performLogin - } - }; - } + private CheckBoxOption saveUsername; + private CheckBoxOption savePassword; private void performLogin() { @@ -108,9 +87,51 @@ namespace osu.Game.Overlays.Options.General } [BackgroundDependencyLoader(permitNulls: true)] - private void load(APIAccess api) + private void load(APIAccess api, OsuConfigManager config) { this.api = api; + Direction = FlowDirection.VerticalOnly; + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + Spacing = new Vector2(0, 5); + Children = new Drawable[] + { + new SpriteText { Text = "Username" }, + username = new TextBox + { + Height = 20, + RelativeSizeAxes = Axes.X, + Text = api?.Username ?? string.Empty + }, + new SpriteText { Text = "Password" }, + password = new PasswordTextBox + { + Height = 20, + RelativeSizeAxes = Axes.X + }, + saveUsername = new CheckBoxOption + { + LabelText = "Remember Username", + Bindable = config.GetBindable(OsuConfig.SaveUsername), + }, + savePassword = new CheckBoxOption + { + LabelText = "Remember Password", + Bindable = config.GetBindable(OsuConfig.SavePassword), + }, + new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = "Log in", + Action = performLogin + }, + new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = "Register", + //Action = registerLink + } + }; } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs index 60ce228164..84c2a390aa 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs @@ -3,7 +3,6 @@ using osu.Framework.Extensions; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Game.Modes; using OpenTK.Graphics; @@ -20,7 +19,7 @@ namespace osu.Game.Overlays.Toolbar mode = value; TooltipMain = mode.GetDescription(); TooltipSub = $"Play some {mode.GetDescription()}"; - Icon = getModeIcon(mode); + Icon = Ruleset.GetRuleset(mode).Icon; } } @@ -48,17 +47,6 @@ namespace osu.Game.Overlays.Toolbar } } - private FontAwesome getModeIcon(PlayMode mode) - { - switch (mode) - { - default: return FontAwesome.fa_osu_osu_o; - case PlayMode.Taiko: return FontAwesome.fa_osu_taiko_o; - case PlayMode.Catch: return FontAwesome.fa_osu_fruits_o; - case PlayMode.Mania: return FontAwesome.fa_osu_mania_o; - } - } - protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index aad2982544..964f4552ba 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -2,6 +2,7 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Framework; using osu.Framework.Allocation; using OpenTK; @@ -14,7 +15,12 @@ using osu.Game.Beatmaps; using osu.Game.Database; using osu.Framework.Graphics.Colour; using osu.Game.Beatmaps.Drawables; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.MathUtils; using osu.Game.Graphics; +using osu.Game.Beatmaps.Timing; +using osu.Game.Modes; namespace osu.Game.Screens.Select { @@ -24,7 +30,7 @@ namespace osu.Game.Screens.Select private Container beatmapInfoContainer; - private BaseGame game; + private OsuGameBase game; public BeatmapInfoWedge() { @@ -42,7 +48,7 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader] - private void load(BaseGame game) + private void load(OsuGameBase game) { this.game = game; } @@ -59,6 +65,28 @@ namespace osu.Game.Screens.Select BeatmapSetInfo beatmapSetInfo = beatmap.BeatmapSetInfo; BeatmapInfo beatmapInfo = beatmap.BeatmapInfo; + List labels = new List(); + + if (beatmap.Beatmap != null) + { + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "Length", + Icon = FontAwesome.fa_clock_o, + Content = TimeSpan.FromMilliseconds(beatmap.Beatmap.HitObjects.Last().EndTime - beatmap.Beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), + })); + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "BPM", + Icon = FontAwesome.fa_circle, + Content = getBPMRange(beatmap.Beatmap), + })); + + //get statistics fromt he current ruleset. + Ruleset.GetRuleset(beatmap.BeatmapInfo.Mode).GetBeatmapStatistics(beatmap).ForEach(s => labels.Add(new InfoLabel(s))); + } + (beatmapInfoContainer = new BufferedContainer { Depth = newDepth, @@ -99,9 +127,9 @@ namespace osu.Game.Screens.Select Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Direction = FlowDirection.VerticalOnly, - Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 40 }, + Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 }, AutoSizeAxes = Axes.Both, - Children = new[] + Children = new Drawable[] { new SpriteText { @@ -139,11 +167,18 @@ namespace osu.Game.Screens.Select Shadow = true, }, } - } + }, + new FlowContainer + { + Margin = new MarginPadding { Top = 20 }, + Spacing = new Vector2(40,0), + AutoSizeAxes = Axes.Both, + Children = labels + }, } - } + }, } - }).Preload(game, delegate(Drawable d) + }).Preload(game, delegate (Drawable d) { FadeIn(250); @@ -153,5 +188,47 @@ namespace osu.Game.Screens.Select Add(d); }); } + + private string getBPMRange(Beatmap beatmap) + { + double bpmMax = beatmap.BPMMaximum; + double bpmMin = beatmap.BPMMinimum; + + if (Precision.AlmostEquals(bpmMin, bpmMax)) return Math.Round(bpmMin) + "bpm"; + + return Math.Round(bpmMin) + "-" + Math.Round(bpmMax) + "bpm (mostly " + Math.Round(beatmap.BPMMode) + "bpm)"; + } + + public class InfoLabel : Container + { + public InfoLabel(BeatmapStatistic statistic) + { + AutoSizeAxes = Axes.Both; + Children = new[] + { + new TextAwesome + { + Icon = FontAwesome.fa_square, + Colour = new Color4(68, 17, 136, 255), + Rotation = 45 + }, + new TextAwesome + { + Icon = statistic.Icon, + Colour = new Color4(255, 221, 85, 255), + Scale = new Vector2(0.8f) + }, + new SpriteText + { + Margin = new MarginPadding { Left = 13 }, + Font = @"Exo2.0-Bold", + Colour = new Color4(255, 221, 85, 255), + Text = statistic.Content, + TextSize = 17, + Origin = Anchor.CentreLeft + }, + }; + } + } } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 6c7936e95e..ddacf7c4b2 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -369,7 +369,7 @@ namespace osu.Game.Screens.Select if (b.Metadata == null) b.Metadata = beatmapSet.Metadata; }); - beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); + beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.StarDifficulty).ToList(); var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database);