From 6cf227a7af53014b2b5a5a14112e71537af68b7b Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Wed, 23 May 2018 03:24:18 +0200 Subject: [PATCH 001/190] Allow formatting for DrawableDate class --- osu.Game/Graphics/DrawableDate.cs | 60 +++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 763e57e397..c38deba007 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -13,6 +13,8 @@ namespace osu.Game.Graphics public class DrawableDate : OsuSpriteText, IHasTooltip { private readonly DateTimeOffset date; + private readonly String dateFormat; + private readonly String tooltipFormat; public DrawableDate(DateTimeOffset date) { @@ -20,6 +22,50 @@ namespace osu.Game.Graphics Font = "Exo2.0-RegularItalic"; this.date = date.ToLocalTime(); + // if date's format is not specified, set it to an empty string, + // so that later we will know to humanize it + dateFormat = ""; + // if tooltip's format is not specified, set it to an empty string + // so later we will know to default to a default time format + tooltipFormat = ""; + } + + public DrawableDate(string dateFormat, DateTimeOffset date) + { + AutoSizeAxes = Axes.Both; + Font = "Exo2.0-RegularItalic"; + + this.date = date.ToLocalTime(); + // set a date format for later from an argument + this.dateFormat = dateFormat; + // if tooltip's format is not specified, set it to an empty string, + // so later we will know to default to a default time format + tooltipFormat = ""; + } + + public DrawableDate(DateTimeOffset date, string tooltipFormat) + { + AutoSizeAxes = Axes.Both; + Font = "Exo2.0-RegularItalic"; + + this.date = date.ToLocalTime(); + // if date's format is not specified, set it to an empty string, + // so that later we will know to humanize it + dateFormat = ""; + // set a tooltip format for later from an argument + this.tooltipFormat = tooltipFormat; + } + + public DrawableDate(string dateFormat, DateTimeOffset date, string tooltipFormat) + { + AutoSizeAxes = Axes.Both; + Font = "Exo2.0-RegularItalic"; + + this.date = date.ToLocalTime(); + // set a date format for text generator from an argument + this.dateFormat = dateFormat; + // set a tooltip format for tooltip generator from an argument + this.tooltipFormat = tooltipFormat; } [BackgroundDependencyLoader] @@ -58,8 +104,18 @@ namespace osu.Game.Graphics public override bool HandleMouseInput => true; - private void updateTime() => Text = date.Humanize(); + // if date's format is specified + private void updateTime() => Text = dateFormat != "" ? + // format it as requested in a passed argument + String.Format(dateFormat, date) : + // otherwise, humanize it (for example: 2 hours ago) + date.Humanize(); - public string TooltipText => date.ToString(); + // if we know that the tooltip format exists + public string TooltipText => tooltipFormat != "" ? + // then we format the tooltip text using that format + String.Format(tooltipFormat, date) : + // but otherwise, simply convert the date to string + date.ToString(); } } From 8e9dde97ce15e8ba3ec1920849eb9777a635fca3 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Wed, 23 May 2018 03:24:37 +0200 Subject: [PATCH 002/190] Better match join and last seen texts and tooltips with osu-web --- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4c411b3210..1b7335bf81 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -364,12 +364,12 @@ namespace osu.Game.Overlays.Profile else { infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableDate(user.JoinDate), boldItalic); + infoTextLeft.AddText(new DrawableDate("{0:MMMM yyyy}", user.JoinDate, "{0:d MMMM yyyy}"), boldItalic); } infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); - infoTextLeft.AddText(new DrawableDate(user.LastVisit), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.LastVisit, "{0:d MMMM yyyy H:mm \"UTC\"z}"), boldItalic); infoTextLeft.NewParagraph(); if (user.PlayStyle?.Length > 0) From 10bc3917b531925a53c1bdadce68e8783f397aaf Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Wed, 23 May 2018 11:17:13 +0200 Subject: [PATCH 003/190] Apply suggested changes --- osu.Game/Graphics/DrawableDate.cs | 72 +++++----------------- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 +- 2 files changed, 16 insertions(+), 60 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index c38deba007..ede5213772 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -13,61 +13,23 @@ namespace osu.Game.Graphics public class DrawableDate : OsuSpriteText, IHasTooltip { private readonly DateTimeOffset date; - private readonly String dateFormat; - private readonly String tooltipFormat; + private readonly string dateFormat; + private readonly string tooltipFormat; - public DrawableDate(DateTimeOffset date) + public DrawableDate(DateTimeOffset date, string dateFormat = null, string tooltipFormat = null) { AutoSizeAxes = Axes.Both; Font = "Exo2.0-RegularItalic"; this.date = date.ToLocalTime(); - // if date's format is not specified, set it to an empty string, - // so that later we will know to humanize it - dateFormat = ""; - // if tooltip's format is not specified, set it to an empty string - // so later we will know to default to a default time format - tooltipFormat = ""; - } - - public DrawableDate(string dateFormat, DateTimeOffset date) - { - AutoSizeAxes = Axes.Both; - Font = "Exo2.0-RegularItalic"; - - this.date = date.ToLocalTime(); - // set a date format for later from an argument + // The string to format the date text with. + // May be null if the humanized format should be used. this.dateFormat = dateFormat; - // if tooltip's format is not specified, set it to an empty string, - // so later we will know to default to a default time format - tooltipFormat = ""; - } - - public DrawableDate(DateTimeOffset date, string tooltipFormat) - { - AutoSizeAxes = Axes.Both; - Font = "Exo2.0-RegularItalic"; - - this.date = date.ToLocalTime(); - // if date's format is not specified, set it to an empty string, - // so that later we will know to humanize it - dateFormat = ""; - // set a tooltip format for later from an argument + // The string to format the tooltip text with. + // May be null if the default format should be used. this.tooltipFormat = tooltipFormat; } - - public DrawableDate(string dateFormat, DateTimeOffset date, string tooltipFormat) - { - AutoSizeAxes = Axes.Both; - Font = "Exo2.0-RegularItalic"; - - this.date = date.ToLocalTime(); - // set a date format for text generator from an argument - this.dateFormat = dateFormat; - // set a tooltip format for tooltip generator from an argument - this.tooltipFormat = tooltipFormat; - } - + [BackgroundDependencyLoader] private void load() { @@ -104,18 +66,12 @@ namespace osu.Game.Graphics public override bool HandleMouseInput => true; - // if date's format is specified - private void updateTime() => Text = dateFormat != "" ? - // format it as requested in a passed argument - String.Format(dateFormat, date) : - // otherwise, humanize it (for example: 2 hours ago) - date.Humanize(); + private void updateTime() => Text = string.IsNullOrEmpty(dateFormat) ? + date.Humanize() : + string.Format(dateFormat, date); - // if we know that the tooltip format exists - public string TooltipText => tooltipFormat != "" ? - // then we format the tooltip text using that format - String.Format(tooltipFormat, date) : - // but otherwise, simply convert the date to string - date.ToString(); + public string TooltipText => string.IsNullOrEmpty(tooltipFormat) ? + date.ToString() : + string.Format(tooltipFormat, date); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 1b7335bf81..dedfb294e2 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -364,12 +364,12 @@ namespace osu.Game.Overlays.Profile else { infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableDate("{0:MMMM yyyy}", user.JoinDate, "{0:d MMMM yyyy}"), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.JoinDate, "{0:MMMM yyyy}", "{0:d MMMM yyyy}"), boldItalic); } infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); - infoTextLeft.AddText(new DrawableDate(user.LastVisit, "{0:d MMMM yyyy H:mm \"UTC\"z}"), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.LastVisit, null, "{0:d MMMM yyyy H:mm \"UTC\"z}"), boldItalic); infoTextLeft.NewParagraph(); if (user.PlayStyle?.Length > 0) From cf5232586e4ab299b63f2de09888d9527a0649fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Zgierski?= Date: Wed, 23 May 2018 11:27:11 +0200 Subject: [PATCH 004/190] Trim whitespace that I couldn't remove in VS? --- osu.Game/Graphics/DrawableDate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index ede5213772..0132a1b82c 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -29,7 +29,7 @@ namespace osu.Game.Graphics // May be null if the default format should be used. this.tooltipFormat = tooltipFormat; } - + [BackgroundDependencyLoader] private void load() { From 29de8e5e2d6a1384c8ffccefdc76939092ed04b0 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Wed, 23 May 2018 12:07:28 +0200 Subject: [PATCH 005/190] Document parameters more properly --- osu.Game/Graphics/DrawableDate.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index ede5213772..a2b811be92 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -16,20 +16,20 @@ namespace osu.Game.Graphics private readonly string dateFormat; private readonly string tooltipFormat; + /// The string to format the date text with. + /// May be null if the humanized format should be used. + /// The string to format the tooltip text with. + /// May be null if the default format should be used. public DrawableDate(DateTimeOffset date, string dateFormat = null, string tooltipFormat = null) { AutoSizeAxes = Axes.Both; Font = "Exo2.0-RegularItalic"; this.date = date.ToLocalTime(); - // The string to format the date text with. - // May be null if the humanized format should be used. this.dateFormat = dateFormat; - // The string to format the tooltip text with. - // May be null if the default format should be used. this.tooltipFormat = tooltipFormat; } - + [BackgroundDependencyLoader] private void load() { From 961702aadff5955ad1844278b96bf6ee4c206d33 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 13:05:41 +0200 Subject: [PATCH 006/190] Apply the format fix to the tooltip text across the board --- osu.Game/Graphics/DrawableDate.cs | 10 ++-------- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index a2b811be92..a6c2587397 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -14,20 +14,16 @@ namespace osu.Game.Graphics { private readonly DateTimeOffset date; private readonly string dateFormat; - private readonly string tooltipFormat; /// The string to format the date text with. /// May be null if the humanized format should be used. - /// The string to format the tooltip text with. - /// May be null if the default format should be used. - public DrawableDate(DateTimeOffset date, string dateFormat = null, string tooltipFormat = null) + public DrawableDate(DateTimeOffset date, string dateFormat = null) { AutoSizeAxes = Axes.Both; Font = "Exo2.0-RegularItalic"; this.date = date.ToLocalTime(); this.dateFormat = dateFormat; - this.tooltipFormat = tooltipFormat; } [BackgroundDependencyLoader] @@ -70,8 +66,6 @@ namespace osu.Game.Graphics date.Humanize() : string.Format(dateFormat, date); - public string TooltipText => string.IsNullOrEmpty(tooltipFormat) ? - date.ToString() : - string.Format(tooltipFormat, date); + public string TooltipText => string.Format("{0:d MMMM yyyy H:mm \"UTC\"z}", date); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index dedfb294e2..e4739abcf4 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -364,12 +364,12 @@ namespace osu.Game.Overlays.Profile else { infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableDate(user.JoinDate, "{0:MMMM yyyy}", "{0:d MMMM yyyy}"), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.JoinDate, "{0:MMMM yyyy}"), boldItalic); } infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); - infoTextLeft.AddText(new DrawableDate(user.LastVisit, null, "{0:d MMMM yyyy H:mm \"UTC\"z}"), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.LastVisit, null), boldItalic); infoTextLeft.NewParagraph(); if (user.PlayStyle?.Length > 0) From 05b0564381d110304b064667d7121ce726313f11 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 13:30:29 +0200 Subject: [PATCH 007/190] Create DrawableJoinDate somehow and remove dateFormat argument --- osu.Game/Graphics/DrawableDate.cs | 2 +- osu.Game/Graphics/DrawableJoinDate.cs | 14 ++++++++++++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Graphics/DrawableJoinDate.cs diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index a6c2587397..387711c45a 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -17,7 +17,7 @@ namespace osu.Game.Graphics /// The string to format the date text with. /// May be null if the humanized format should be used. - public DrawableDate(DateTimeOffset date, string dateFormat = null) + public DrawableDate(DateTimeOffset date) { AutoSizeAxes = Axes.Both; Font = "Exo2.0-RegularItalic"; diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs new file mode 100644 index 0000000000..1921c9473d --- /dev/null +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace osu.Game.Graphics +{ + public class DrawableJoinDate : DrawableDate + { + public DrawableJoinDate(DateTimeOffset date) : base(date) + { + + } + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index e4739abcf4..4c411b3210 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -364,12 +364,12 @@ namespace osu.Game.Overlays.Profile else { infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableDate(user.JoinDate, "{0:MMMM yyyy}"), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.JoinDate), boldItalic); } infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); - infoTextLeft.AddText(new DrawableDate(user.LastVisit, null), boldItalic); + infoTextLeft.AddText(new DrawableDate(user.LastVisit), boldItalic); infoTextLeft.NewParagraph(); if (user.PlayStyle?.Length > 0) From a446b627da0decbb477efefbb0e63be4c1aa686f Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 13:31:12 +0200 Subject: [PATCH 008/190] Make TooltipText virtual --- osu.Game/Graphics/DrawableDate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 387711c45a..5ca28f17b9 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -66,6 +66,6 @@ namespace osu.Game.Graphics date.Humanize() : string.Format(dateFormat, date); - public string TooltipText => string.Format("{0:d MMMM yyyy H:mm \"UTC\"z}", date); + public virtual string TooltipText => string.Format("{0:d MMMM yyyy H:mm \"UTC\"z}", date); } } From 3efb51e4646c332cd8687081987d8093216b10cb Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 14:00:32 +0200 Subject: [PATCH 009/190] Create Format(), override TooltipText.. --- osu.Game/Graphics/DrawableDate.cs | 8 +++----- osu.Game/Graphics/DrawableJoinDate.cs | 8 +++++++- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 5ca28f17b9..7e16575ed5 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -13,7 +13,6 @@ namespace osu.Game.Graphics public class DrawableDate : OsuSpriteText, IHasTooltip { private readonly DateTimeOffset date; - private readonly string dateFormat; /// The string to format the date text with. /// May be null if the humanized format should be used. @@ -23,7 +22,6 @@ namespace osu.Game.Graphics Font = "Exo2.0-RegularItalic"; this.date = date.ToLocalTime(); - this.dateFormat = dateFormat; } [BackgroundDependencyLoader] @@ -62,9 +60,9 @@ namespace osu.Game.Graphics public override bool HandleMouseInput => true; - private void updateTime() => Text = string.IsNullOrEmpty(dateFormat) ? - date.Humanize() : - string.Format(dateFormat, date); + protected virtual string Format() => Text = date.Humanize(); + + private void updateTime() => Format(); public virtual string TooltipText => string.Format("{0:d MMMM yyyy H:mm \"UTC\"z}", date); } diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs index 1921c9473d..1472eddd8f 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -6,9 +6,15 @@ namespace osu.Game.Graphics { public class DrawableJoinDate : DrawableDate { + private readonly DateTimeOffset date; + public DrawableJoinDate(DateTimeOffset date) : base(date) { - + this.date = date; } + + protected override string Format() => Text = string.Format("{0:MMMM yyyy}", date); + + public override string TooltipText => string.Format("{0:d MMMM yyyy}", date); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4c411b3210..996c6384c9 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -364,7 +364,7 @@ namespace osu.Game.Overlays.Profile else { infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableDate(user.JoinDate), boldItalic); + infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); } infoTextLeft.NewLine(); From e3ebc849c5a1be4005aba98568774c021292cbbe Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 14:04:12 +0200 Subject: [PATCH 010/190] Remove not removed comment --- osu.Game/Graphics/DrawableDate.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 7e16575ed5..43287202ae 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -13,9 +13,7 @@ namespace osu.Game.Graphics public class DrawableDate : OsuSpriteText, IHasTooltip { private readonly DateTimeOffset date; - - /// The string to format the date text with. - /// May be null if the humanized format should be used. + public DrawableDate(DateTimeOffset date) { AutoSizeAxes = Axes.Both; From 29fbdf4d926f6e6a3594a14276ed91a9f715d6ba Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 14:05:50 +0200 Subject: [PATCH 011/190] Remove horizontal white space --- osu.Game/Graphics/DrawableDate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 43287202ae..7a264f58a5 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -13,7 +13,7 @@ namespace osu.Game.Graphics public class DrawableDate : OsuSpriteText, IHasTooltip { private readonly DateTimeOffset date; - + public DrawableDate(DateTimeOffset date) { AutoSizeAxes = Axes.Both; From 71c04f4605dac87271db2c5199a0fb397b976630 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 14:10:54 +0200 Subject: [PATCH 012/190] Add license header to the new file --- osu.Game/Graphics/DrawableJoinDate.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs index 1472eddd8f..7860774a69 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections.Generic; using System.Text; From 39224931f8f20fd4aedf3f8f435a970702d65cf5 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 14:25:12 +0200 Subject: [PATCH 013/190] Try satisfying AppVeyor --- osu.Game/Graphics/DrawableDate.cs | 2 +- osu.Game/Graphics/DrawableJoinDate.cs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 7a264f58a5..df6aa72c37 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -62,6 +62,6 @@ namespace osu.Game.Graphics private void updateTime() => Format(); - public virtual string TooltipText => string.Format("{0:d MMMM yyyy H:mm \"UTC\"z}", date); + public virtual string TooltipText => string.Format($"{date:d MMMM yyyy H:mm \"UTC\"z}"); } } diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs index 7860774a69..713bd4e44f 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; -using System.Text; namespace osu.Game.Graphics { @@ -16,8 +14,8 @@ namespace osu.Game.Graphics this.date = date; } - protected override string Format() => Text = string.Format("{0:MMMM yyyy}", date); + protected override string Format() => Text = string.Format($"{date:MMMM yyyy}"); - public override string TooltipText => string.Format("{0:d MMMM yyyy}", date); + public override string TooltipText => string.Format($"{date:d MMMM yyyy}"); } } From 7f0cb0bbf61cb10b61ec768ec1504ecf128bf4e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 12:06:50 +0900 Subject: [PATCH 014/190] Add key bindings for scroll speed Closes #2689. - [ ] Depends on ppy/osu-framework#1569 being fixed. --- .../Input/Bindings/GlobalActionContainer.cs | 12 +++++-- .../UI/Scrolling/ScrollingPlayfield.cs | 32 ++++++++++--------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index fced2e5d95..83ffd415ae 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -45,7 +45,9 @@ namespace osu.Game.Input.Bindings public IEnumerable InGameKeyBindings => new[] { new KeyBinding(InputKey.Space, GlobalAction.SkipCutscene), - new KeyBinding(InputKey.Tilde, GlobalAction.QuickRetry) + new KeyBinding(InputKey.Tilde, GlobalAction.QuickRetry), + new KeyBinding(new[] { InputKey.Control, InputKey.Plus }, GlobalAction.IncreaseScrollSpeed), + new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed), }; protected override IEnumerable KeyBindingInputQueue => @@ -85,6 +87,12 @@ namespace osu.Game.Input.Bindings ToggleGameplayMouseButtons, [Description("Go back")] - Back + Back, + + [Description("Increase scroll speed")] + IncreaseScrollSpeed, + + [Description("Decrease scroll speed")] + DecreaseScrollSpeed, } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 6f86d20295..e8b0a53f92 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -4,30 +4,33 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; -using OpenTK.Input; namespace osu.Game.Rulesets.UI.Scrolling { /// /// A type of specialized towards scrolling s. /// - public abstract class ScrollingPlayfield : Playfield + public abstract class ScrollingPlayfield : Playfield, IKeyBindingHandler { /// /// The default span of time visible by the length of the scrolling axes. /// This is clamped between and . /// private const double time_span_default = 1500; + /// /// The minimum span of time that may be visible by the length of the scrolling axes. /// private const double time_span_min = 50; + /// /// The maximum span of time that may be visible by the length of the scrolling axes. /// private const double time_span_max = 10000; + /// /// The step increase/decrease of the span of time visible by the length of the scrolling axes. /// @@ -78,27 +81,26 @@ namespace osu.Game.Rulesets.UI.Scrolling HitObjects.TimeRange.BindTo(VisibleTimeRange); } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer(direction); + + public bool OnPressed(GlobalAction action) { if (!UserScrollSpeedAdjustment) return false; - if (state.Keyboard.ControlPressed) + switch (action) { - switch (args.Key) - { - case Key.Minus: - this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint); - break; - case Key.Plus: - this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint); - break; - } + case GlobalAction.IncreaseScrollSpeed: + this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint); + return true; + case GlobalAction.DecreaseScrollSpeed: + this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint); + return true; } return false; } - protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer(direction); + public bool OnReleased(GlobalAction action) => false; } } From 792d3b82159c9adfde092def00ac583ae9c50dfd Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 9 Jun 2018 09:14:52 +0200 Subject: [PATCH 015/190] allow "go back" keybind in play --- osu.Game/Screens/Play/FailOverlay.cs | 16 +++++++------ osu.Game/Screens/Play/PauseContainer.cs | 30 +++++++++++++------------ osu.Game/Screens/Play/Player.cs | 2 -- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 7b555776f7..8c3ab8f235 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,16 +1,16 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Input; -using OpenTK.Input; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; using System.Linq; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class FailOverlay : GameplayMenuOverlay + public class FailOverlay : GameplayMenuOverlay, IKeyBindingHandler { public override string Header => "failed"; public override string Description => "you're dead, try again?"; @@ -21,16 +21,18 @@ namespace osu.Game.Screens.Play AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + + public bool OnPressed(GlobalAction action) { - if (!args.Repeat && args.Key == Key.Escape) + if (action == GlobalAction.Back) { InternalButtons.Children.Last().TriggerOnClick(); return true; } - return base.OnKeyDown(state, args); + return false; } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index 6262f71ddc..d814bb46a2 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -6,11 +6,11 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Framework.Timing; using osu.Game.Graphics; +using osu.Game.Input.Bindings; using OpenTK.Graphics; -using OpenTK.Input; namespace osu.Game.Screens.Play { @@ -131,24 +131,13 @@ namespace osu.Game.Screens.Play base.Update(); } - public class PauseOverlay : GameplayMenuOverlay + public class PauseOverlay : GameplayMenuOverlay, IKeyBindingHandler { public Action OnResume; public override string Header => "paused"; public override string Description => "you're not going to do what i think you're going to do, are ya?"; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (!args.Repeat && args.Key == Key.Escape) - { - InternalButtons.Children.First().TriggerOnClick(); - return true; - } - - return base.OnKeyDown(state, args); - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -156,6 +145,19 @@ namespace osu.Game.Screens.Play AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } + + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + InternalButtons.Children.First().TriggerOnClick(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fe77f85a50..739dcdf066 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -49,8 +49,6 @@ namespace osu.Game.Screens.Play public bool AllowLeadIn { get; set; } = true; public bool AllowResults { get; set; } = true; - protected override bool AllowBackButton => false; - private Bindable mouseWheelDisabled; private Bindable userAudioOffset; From b9b04c1b6e2fe5154e39e0d6dcba0c810c776868 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 9 Jun 2018 09:28:02 +0200 Subject: [PATCH 016/190] move back logic into GameplayMenuOverlay --- osu.Game/Screens/Play/FailOverlay.cs | 22 +++++-------------- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 23 +++++++++++++++++++- osu.Game/Screens/Play/PauseContainer.cs | 18 +-------------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 8c3ab8f235..1295df2da0 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,38 +1,26 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; -using System.Linq; -using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class FailOverlay : GameplayMenuOverlay, IKeyBindingHandler + public class FailOverlay : GameplayMenuOverlay { public override string Header => "failed"; public override string Description => "you're dead, try again?"; + protected override Action DefaultBackAction => () => InternalButtons.Children.Last().TriggerOnClick(); + [BackgroundDependencyLoader] private void load(OsuColour colours) { AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } - - public bool OnPressed(GlobalAction action) - { - if (action == GlobalAction.Back) - { - InternalButtons.Children.Last().TriggerOnClick(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index db099cd16c..a72fca2532 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -15,10 +15,13 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Shapes; using OpenTK.Input; using System.Collections.Generic; +using System.Linq; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public abstract class GameplayMenuOverlay : OverlayContainer + public abstract class GameplayMenuOverlay : OverlayContainer, IKeyBindingHandler { private const int transition_duration = 200; private const int button_height = 70; @@ -31,6 +34,11 @@ namespace osu.Game.Screens.Play public Action OnRetry; public Action OnQuit; + /// + /// Action that is invoked if is triggered. + /// + protected virtual Action DefaultBackAction => () => InternalButtons.Children.First().TriggerOnClick(); + public abstract string Header { get; } public abstract string Description { get; } @@ -219,6 +227,19 @@ namespace osu.Game.Screens.Play return base.OnKeyDown(state, args); } + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + DefaultBackAction.Invoke(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; + private void buttonSelectionChanged(DialogButton button, bool isSelected) { if (!isSelected) diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index d814bb46a2..494e28a78e 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -2,14 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Bindings; using osu.Framework.Timing; using osu.Game.Graphics; -using osu.Game.Input.Bindings; using OpenTK.Graphics; namespace osu.Game.Screens.Play @@ -131,7 +128,7 @@ namespace osu.Game.Screens.Play base.Update(); } - public class PauseOverlay : GameplayMenuOverlay, IKeyBindingHandler + public class PauseOverlay : GameplayMenuOverlay { public Action OnResume; @@ -145,19 +142,6 @@ namespace osu.Game.Screens.Play AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); } - - public bool OnPressed(GlobalAction action) - { - if (action == GlobalAction.Back) - { - InternalButtons.Children.First().TriggerOnClick(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; } } } From f486bcfee1610cad4329f6910c1c8d4594175921 Mon Sep 17 00:00:00 2001 From: clayton Date: Sat, 9 Jun 2018 17:38:17 -0700 Subject: [PATCH 017/190] Add judgements to catch --- .../Judgements/CatchBananaJudgement.cs | 24 +++++++++++++++++ .../Judgements/CatchBananaShowerJudgement.cs | 20 ++++++++++++++ .../Judgements/CatchDropletJudgement.cs | 22 ++++++++++++++++ .../Judgements/CatchJudgement.cs | 19 +++++++++++++- .../Judgements/CatchTinyDropletJudgement.cs | 24 +++++++++++++++++ .../Objects/Drawable/DrawableBanana.cs | 25 ++++++++++++++++++ .../Objects/Drawable/DrawableBananaShower.cs | 4 +-- .../Drawable/DrawableCatchHitObject.cs | 8 +++--- .../Objects/Drawable/DrawableDroplet.cs | 10 +++++++ .../Objects/Drawable/DrawableTinyDroplet.cs | 26 +++++++++++++++++++ .../Scoring/CatchScoreProcessor.cs | 18 ++++++++++--- .../UI/CatchRulesetContainer.cs | 8 +++--- 12 files changed, 194 insertions(+), 14 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs create mode 100644 osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs create mode 100644 osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs create mode 100644 osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs new file mode 100644 index 0000000000..ea51de0118 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Judgements +{ + public class CatchBananaJudgement : CatchJudgement + { + public override bool AffectsCombo => false; + + protected override int NumericResultFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 1100; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs new file mode 100644 index 0000000000..75c79d9a6a --- /dev/null +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Judgements +{ + public class CatchBananaShowerJudgement : CatchJudgement + { + public override bool AffectsCombo => false; + + public CatchBananaShowerJudgement() + { + Result = HitResult.Perfect; + } + + protected override int NumericResultFor(HitResult result) => 0; + } +} diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs new file mode 100644 index 0000000000..8464313300 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Judgements +{ + public class CatchDropletJudgement : CatchJudgement + { + protected override int NumericResultFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 30; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index bb2786f14f..c6ad605f09 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -2,11 +2,28 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements { public class CatchJudgement : Judgement { - // todo: wangs + public override HitResult MaxResult => HitResult.Perfect; + + /// + /// The positional hit offset. + /// + public float PositionOffset; + + protected override int NumericResultFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 300; + } + } } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs new file mode 100644 index 0000000000..97a24cfc64 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Judgements +{ + public class CatchTinyDropletJudgement : CatchJudgement + { + public override bool AffectsCombo => false; + + protected override int NumericResultFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 10; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs new file mode 100644 index 0000000000..6b7b5e0310 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Game.Rulesets.Catch.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableBanana : DrawableFruit + { + public DrawableBanana(BananaShower.Banana h) + : base(h) + { + } + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (CheckPosition == null) return; + + if (timeOffset >= 0) + AddJudgement(new CatchBananaJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index 739cc6a59b..546ded5a1a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -5,7 +5,7 @@ using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (timeOffset >= 0) - AddJudgement(new Judgement { Result = NestedHitObjects.Cast().Any(n => n.Judgements.Any(j => j.IsHit)) ? HitResult.Perfect : HitResult.Miss }); + AddJudgement(new CatchBananaShowerJudgement()); } protected override void AddNested(DrawableHitObject h) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 3dbda708e5..7af1456015 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -2,14 +2,14 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK; +using OpenTK.Graphics; using osu.Framework.Graphics; -using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; -using OpenTK; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable if (CheckPosition == null) return; if (timeOffset >= 0) - AddJudgement(new Judgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); + AddJudgement(new CatchJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); } protected override void SkinChanged(ISkinSource skin, bool allowFallback) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index a19d67ebbe..cb451c61c0 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -6,6 +6,8 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; +using osu.Game.Rulesets.Catch.Judgements; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -21,6 +23,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Masking = false; } + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (CheckPosition == null) return; + + if (timeOffset >= 0) + AddJudgement(new CatchDropletJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); + } + [BackgroundDependencyLoader] private void load() { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs new file mode 100644 index 0000000000..7a3972da51 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Game.Rulesets.Catch.Judgements; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableTinyDroplet : DrawableDroplet + { + public DrawableTinyDroplet(Droplet h) + : base(h) + { + Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 8; + } + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (CheckPosition == null) return; + + if (timeOffset >= 0) + AddJudgement(new CatchTinyDropletJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index ce1aee5c34..1d7cd5cbc8 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -24,13 +24,23 @@ namespace osu.Game.Rulesets.Catch.Scoring switch (obj) { case JuiceStream stream: - foreach (var _ in stream.NestedHitObjects.Cast()) - AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + foreach (var nestedObject in stream.NestedHitObjects) + switch (nestedObject) + { + case TinyDroplet _: + AddJudgement(new CatchTinyDropletJudgement { Result = HitResult.Perfect }); + break; + case Droplet _: + AddJudgement(new CatchDropletJudgement { Result = HitResult.Perfect }); + break; + case Fruit _: + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + break; + } break; case BananaShower shower: foreach (var _ in shower.NestedHitObjects.Cast()) - AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); - AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + AddJudgement(new CatchBananaJudgement { Result = HitResult.Perfect }); break; case Fruit _: AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 52763e09af..c1cb0627e5 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -38,14 +38,16 @@ namespace osu.Game.Rulesets.Catch.UI { switch (h) { + case BananaShower.Banana banana: + return new DrawableBanana(banana); case Fruit fruit: return new DrawableFruit(fruit); case JuiceStream stream: return new DrawableJuiceStream(stream, GetVisualRepresentation); - case BananaShower banana: - return new DrawableBananaShower(banana, GetVisualRepresentation); + case BananaShower shower: + return new DrawableBananaShower(shower, GetVisualRepresentation); case TinyDroplet tiny: - return new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }; + return new DrawableTinyDroplet(tiny); case Droplet droplet: return new DrawableDroplet(droplet); } From 808118e4d422811393a6284021a86be26e64a62b Mon Sep 17 00:00:00 2001 From: clayton Date: Sat, 9 Jun 2018 17:39:17 -0700 Subject: [PATCH 018/190] Add health drain to catch --- .../Judgements/CatchBananaJudgement.cs | 11 +++++++++ .../Judgements/CatchBananaShowerJudgement.cs | 1 + .../Judgements/CatchDropletJudgement.cs | 11 +++++++++ .../Judgements/CatchJudgement.cs | 21 ++++++++++++++++ .../Judgements/CatchTinyDropletJudgement.cs | 11 +++++++++ .../Scoring/CatchScoreProcessor.cs | 24 ++++++++++++++++++- 6 files changed, 78 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index ea51de0118..f6d90df0a9 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -20,5 +20,16 @@ namespace osu.Game.Rulesets.Catch.Judgements return 1100; } } + + protected override float HealthIncreaseFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 8; + } + } } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs index 75c79d9a6a..7903aba7c1 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs @@ -16,5 +16,6 @@ namespace osu.Game.Rulesets.Catch.Judgements } protected override int NumericResultFor(HitResult result) => 0; + protected override float HealthIncreaseFor(HitResult result) => 0; } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs index 8464313300..5fce996f6e 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -18,5 +18,16 @@ namespace osu.Game.Rulesets.Catch.Judgements return 30; } } + + protected override float HealthIncreaseFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 7; + } + } } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index c6ad605f09..82d54c6095 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -25,5 +25,26 @@ namespace osu.Game.Rulesets.Catch.Judgements return 300; } } + + /// + /// The base health increase for the result achieved. + /// + public float HealthIncrease => HealthIncreaseFor(Result); + + /// + /// Convert a to a base health increase. + /// + /// The value to convert. + /// The base health increase. + protected virtual float HealthIncreaseFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 10.2f; + } + } } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs index 97a24cfc64..99ddb72f7e 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs @@ -20,5 +20,16 @@ namespace osu.Game.Rulesets.Catch.Judgements return 10; } } + + protected override float HealthIncreaseFor(HitResult result) + { + switch (result) + { + default: + return 0; + case HitResult.Perfect: + return 4; + } + } } } diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 1d7cd5cbc8..54263c2268 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -1,10 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -17,8 +19,12 @@ namespace osu.Game.Rulesets.Catch.Scoring { } + private float hpDrainRate; + protected override void SimulateAutoplay(Beatmap beatmap) { + hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate; + foreach (var obj in beatmap.HitObjects) { switch (obj) @@ -47,8 +53,24 @@ namespace osu.Game.Rulesets.Catch.Scoring break; } } + } - base.SimulateAutoplay(beatmap); + private const double harshness = 0.01; + + protected override void OnNewJudgement(Judgement judgement) + { + base.OnNewJudgement(judgement); + + if (judgement.Result == HitResult.Miss) + { + if (judgement.AffectsCombo) + Health.Value -= hpDrainRate * (harshness * 2); + return; + } + + var catchJudgement = judgement as CatchJudgement; + + Health.Value += Math.Max(catchJudgement.HealthIncrease - hpDrainRate, 0) * harshness; } } } From fbc0cd6f5f2e363358922c97bfcff80e07d335e4 Mon Sep 17 00:00:00 2001 From: Crusensis Date: Sat, 9 Jun 2018 18:14:33 -0700 Subject: [PATCH 019/190] Split AffectsCombo into IsBonus --- .../Judgements/CatchBananaJudgement.cs | 1 + .../Judgements/CatchBananaShowerJudgement.cs | 1 + .../Judgements/HoldNoteJudgement.cs | 2 ++ .../Judgements/HoldNoteTickJudgement.cs | 1 + .../Judgements/OsuSliderTailJudgement.cs | 2 ++ .../Judgements/TaikoDrumRollTickJudgement.cs | 1 + .../Judgements/TaikoStrongHitJudgement.cs | 1 + osu.Game/Rulesets/Judgements/Judgement.cs | 6 +++- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 28 +++++++++++++------ 9 files changed, 33 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index f6d90df0a9..40696d4837 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Catch.Judgements public class CatchBananaJudgement : CatchJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) { diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs index 7903aba7c1..36a4fef80c 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Catch.Judgements public class CatchBananaShowerJudgement : CatchJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; public CatchBananaShowerJudgement() { diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs index 9630ba9273..9c78360911 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs @@ -8,6 +8,8 @@ namespace osu.Game.Rulesets.Mania.Judgements public class HoldNoteJudgement : ManiaJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; + protected override int NumericResultFor(HitResult result) => 0; } } diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 6eb5a79200..5d38e70d01 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mania.Judgements public class HoldNoteTickJudgement : ManiaJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) => 20; } diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs index c4e265aac9..fc85ec8764 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs @@ -8,6 +8,8 @@ namespace osu.Game.Rulesets.Osu.Judgements public class OsuSliderTailJudgement : OsuJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; + protected override int NumericResultFor(HitResult result) => 0; } } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index 446dd0d11b..17bd2d9608 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoDrumRollTickJudgement : TaikoJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) { diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs index 288ad236aa..dbfd38e6f9 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs @@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoStrongHitJudgement : TaikoJudgement { public override bool AffectsCombo => false; + public override bool IsBonus => true; public TaikoStrongHitJudgement() { diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 587f2c8d15..3d70b23773 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -46,10 +46,14 @@ namespace osu.Game.Rulesets.Judgements /// /// Whether the should affect the combo portion of the score. - /// If false, the will be considered for the bonus portion of the score. /// public virtual bool AffectsCombo => true; + /// + /// Whether the should be counted as base or bonus score. + /// + public virtual bool IsBonus => false; + /// /// The numeric representation for the result achieved. /// diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 345930ed04..1fba936032 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -256,13 +256,19 @@ namespace osu.Game.Rulesets.Scoring break; } - baseScore += judgement.NumericResult; - rollingMaxBaseScore += judgement.MaxNumericResult; - JudgedHits++; } - else if (judgement.IsHit) - bonusScore += judgement.NumericResult; + + if (judgement.IsBonus) + { + if (judgement.IsHit) + bonusScore += judgement.NumericResult; + } + else + { + baseScore += judgement.NumericResult; + rollingMaxBaseScore += judgement.MaxNumericResult; + } } /// @@ -275,14 +281,18 @@ namespace osu.Game.Rulesets.Scoring HighestCombo.Value = judgement.HighestComboAtJudgement; if (judgement.AffectsCombo) + JudgedHits--; + + if (judgement.IsBonus) + { + if (judgement.IsHit) + bonusScore -= judgement.NumericResult; + } + else { baseScore -= judgement.NumericResult; rollingMaxBaseScore -= judgement.MaxNumericResult; - - JudgedHits--; } - else if (judgement.IsHit) - bonusScore -= judgement.NumericResult; } private void updateScore() From 3e6e2ac09a41050cac7ea2a86c215c930beebdb2 Mon Sep 17 00:00:00 2001 From: clayton Date: Sat, 9 Jun 2018 18:23:05 -0700 Subject: [PATCH 020/190] Add CatchBananaShowerJudgements in simulated autoplays --- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 54263c2268..386da17c59 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -47,6 +47,7 @@ namespace osu.Game.Rulesets.Catch.Scoring case BananaShower shower: foreach (var _ in shower.NestedHitObjects.Cast()) AddJudgement(new CatchBananaJudgement { Result = HitResult.Perfect }); + AddJudgement(new CatchBananaShowerJudgement()); break; case Fruit _: AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); From e44e08201beed3fda4c11a1e047280282d3a6add Mon Sep 17 00:00:00 2001 From: clayton Date: Mon, 11 Jun 2018 12:43:01 -0700 Subject: [PATCH 021/190] Remove unnecessary usings and move Banana out of BananaShower --- osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs | 2 +- .../Judgements/CatchBananaJudgement.cs | 1 - .../Judgements/CatchBananaShowerJudgement.cs | 1 - .../Judgements/CatchDropletJudgement.cs | 1 - .../Judgements/CatchTinyDropletJudgement.cs | 1 - osu.Game.Rulesets.Catch/Objects/Banana.cs | 10 ++++++++++ osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 5 ----- .../Objects/Drawable/DrawableBanana.cs | 3 +-- .../Objects/Drawable/DrawableBananaShower.cs | 3 +-- osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs | 4 ++-- osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs | 2 +- 11 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Banana.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs index e77dd76353..5c41e4136c 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Tests private DrawableFruit createDrawable(int index) { Fruit fruit = index == 5 - ? new BananaShower.Banana + ? new Banana { StartTime = 1000000000000, IndexInBeatmap = index, diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index 40696d4837..393e3994a1 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs index 36a4fef80c..a3a9aa4f04 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs index 5fce996f6e..0df2305339 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs index 99ddb72f7e..8b77351027 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs new file mode 100644 index 0000000000..f7c60a7a47 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs @@ -0,0 +1,10 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class Banana : Fruit + { + public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana; + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index a6aba42f03..e4e5820e7e 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -39,10 +39,5 @@ namespace osu.Game.Rulesets.Catch.Objects public double EndTime => StartTime + Duration; public double Duration { get; set; } - - public class Banana : Fruit - { - public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana; - } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs index 6b7b5e0310..dc2fa18ad4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Scoring; @@ -9,7 +8,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableBanana : DrawableFruit { - public DrawableBanana(BananaShower.Banana h) + public DrawableBanana(Banana h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index 546ded5a1a..182adab6e1 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable InternalChild = bananaContainer = new Container { RelativeSizeAxes = Axes.Both }; - foreach (var b in s.NestedHitObjects.Cast()) + foreach (var b in s.NestedHitObjects.Cast()) AddNested(getVisualRepresentation?.Invoke(b)); } diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index 936ab6a9d3..23b620248f 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Catch.Replays return; } - if (h is BananaShower.Banana) + if (h is Banana) { // auto bananas unrealistically warp to catch 100% combo. Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X)); @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Catch.Replays { switch (nestedObj) { - case BananaShower.Banana _: + case Banana _: case TinyDroplet _: case Droplet _: case Fruit _: diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index c1cb0627e5..1ac052de4d 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Catch.UI { switch (h) { - case BananaShower.Banana banana: + case Banana banana: return new DrawableBanana(banana); case Fruit fruit: return new DrawableFruit(fruit); From d3ada7914c908a1149205fe38ad510e67606433d Mon Sep 17 00:00:00 2001 From: clayton Date: Mon, 11 Jun 2018 13:29:36 -0700 Subject: [PATCH 022/190] Fix condition for dropping health on miss --- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 386da17c59..3e548de2cf 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Catch.Scoring if (judgement.Result == HitResult.Miss) { - if (judgement.AffectsCombo) + if (!judgement.IsBonus) Health.Value -= hpDrainRate * (harshness * 2); return; } From 785c24b11ba650440c42938a9bd50dcd7a921281 Mon Sep 17 00:00:00 2001 From: clayton Date: Mon, 11 Jun 2018 13:30:30 -0700 Subject: [PATCH 023/190] Check for null CatchJudgement --- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 3e548de2cf..dfe8bba184 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -69,9 +69,8 @@ namespace osu.Game.Rulesets.Catch.Scoring return; } - var catchJudgement = judgement as CatchJudgement; - - Health.Value += Math.Max(catchJudgement.HealthIncrease - hpDrainRate, 0) * harshness; + if (judgement is CatchJudgement catchJudgement) + Health.Value += Math.Max(catchJudgement.HealthIncrease - hpDrainRate, 0) * harshness; } } } From 99e28b6efa5a9bcfb6b6491ba58ffcc8da767a1d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 17:38:43 +0900 Subject: [PATCH 024/190] No reason for beatmap conversion tests to be internal --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 4 ++-- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 4 ++-- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 4 ++-- osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 5b34e46247..14d913cffa 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { - internal class CatchBeatmapConversionTest : BeatmapConversionTest + public class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override Ruleset CreateRuleset() => new CatchRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 5ae899f6d6..f9e6531119 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - internal class ManiaBeatmapConversionTest : BeatmapConversionTest + public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override Ruleset CreateRuleset() => new ManiaRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 386ae5eb05..1383256352 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -13,7 +13,7 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { - internal class OsuBeatmapConversionTest : BeatmapConversionTest + public class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests protected override Ruleset CreateRuleset() => new OsuRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 11586e340b..fb0b2040f4 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - internal class TaikoBeatmapConversionTest : BeatmapConversionTest + public class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Tests protected override Ruleset CreateRuleset() => new TaikoRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. From e94518697833fc60837078492607acadfbab79aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 17:59:52 +0900 Subject: [PATCH 025/190] Expose the beatmap converter --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index cf4dda52a8..b95173e44d 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -25,6 +25,8 @@ namespace osu.Game.Tests.Beatmaps protected abstract string ResourceAssembly { get; } + protected IBeatmapConverter Converter { get; private set; } + protected void Test(string name) { var ourResult = convert(name); @@ -88,10 +90,11 @@ namespace osu.Game.Tests.Beatmaps var rulesetInstance = CreateRuleset(); beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); - var result = new ConvertResult(); - var converter = rulesetInstance.CreateBeatmapConverter(beatmap); + Converter = rulesetInstance.CreateBeatmapConverter(beatmap); - converter.ObjectConverted += (orig, converted) => + var result = new ConvertResult(); + + Converter.ObjectConverted += (orig, converted) => { converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); @@ -103,7 +106,7 @@ namespace osu.Game.Tests.Beatmaps result.Mappings.Add(mapping); }; - IBeatmap convertedBeatmap = converter.Convert(); + IBeatmap convertedBeatmap = Converter.Convert(); rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess(); return result; From 47ae962099fdb248c6fc547ecb85bd2ee01b6398 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 18:20:28 +0900 Subject: [PATCH 026/190] Output only one mapping failure per mapping --- .../Tests/Beatmaps/BeatmapConversionTest.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index b95173e44d..ff57ef41c5 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -43,14 +43,22 @@ namespace osu.Game.Tests.Beatmaps Assert.Fail($"A conversion did not generate any hitobjects, but should have, for hitobject at time: {expectedResult.Mappings[mappingCounter].StartTime}\n"); else if (mappingCounter >= expectedResult.Mappings.Count) Assert.Fail($"A conversion generated hitobjects, but should not have, for hitobject at time: {ourResult.Mappings[mappingCounter].StartTime}\n"); + else if (!expectedResult.Mappings[mappingCounter].Equals(ourResult.Mappings[mappingCounter])) + { + var expectedMapping = expectedResult.Mappings[mappingCounter]; + var ourMapping = ourResult.Mappings[mappingCounter]; + + Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n" + + $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n" + + $"Received: {JsonConvert.SerializeObject(ourMapping)}\n"); + } else { - var counter = mappingCounter; + var ourMapping = ourResult.Mappings[mappingCounter]; + var expectedMapping = expectedResult.Mappings[mappingCounter]; + Assert.Multiple(() => { - var ourMapping = ourResult.Mappings[counter]; - var expectedMapping = expectedResult.Mappings[counter]; - int objectCounter = 0; while (true) { @@ -62,10 +70,6 @@ namespace osu.Game.Tests.Beatmaps else if (objectCounter >= expectedMapping.Objects.Count) Assert.Fail($"The conversion generated a hitobject, but should not have, for hitobject at time: {ourMapping.StartTime}:\n" + $"Received: {JsonConvert.SerializeObject(ourMapping.Objects[objectCounter])}\n"); - else if (!expectedMapping.Equals(ourMapping)) - Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n" - + $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n" - + $"Received: {JsonConvert.SerializeObject(ourMapping)}\n"); else if (!expectedMapping.Objects[objectCounter].Equals(ourMapping.Objects[objectCounter])) { Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}:\n" From afbf35b81416ec5e76c6425971ec6ca7677abf74 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:48:36 +0900 Subject: [PATCH 027/190] Add rng components to mania conversion tests --- .../ManiaBeatmapConversionTest.cs | 30 ++++++++++++++++++- .../MathUtils/FastRandom.cs | 18 ++++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index f9e6531119..c13319ace9 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.MathUtils; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -12,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - public class ManiaBeatmapConversionTest : BeatmapConversionTest + public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -33,9 +35,35 @@ namespace osu.Game.Rulesets.Mania.Tests }; } + protected override ManiaConvertMapping CreateConvertMapping() => new ManiaConvertMapping(Converter); + protected override Ruleset CreateRuleset() => new ManiaRuleset(); } + public class ManiaConvertMapping : ConvertMapping, IEquatable + { + public uint RandomW; + public uint RandomX; + public uint RandomY; + public uint RandomZ; + + public ManiaConvertMapping() + { + } + + public ManiaConvertMapping(IBeatmapConverter converter) + { + var maniaConverter = (ManiaBeatmapConverter)converter; + RandomW = maniaConverter.Random.W; + RandomX = maniaConverter.Random.X; + RandomY = maniaConverter.Random.Y; + RandomZ = maniaConverter.Random.Z; + } + + public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ; + public override bool Equals(ConvertMapping other) => base.Equals(other) && Equals(other as ManiaConvertMapping); + } + public struct ConvertValue : IEquatable { /// diff --git a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs index a3efd5c2bd..785cd5ab06 100644 --- a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs +++ b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs @@ -15,11 +15,15 @@ namespace osu.Game.Rulesets.Mania.MathUtils private const uint y = 842502087; private const uint z = 3579807591; private const uint w = 273326509; - private uint _x, _y = y, _z = z, _w = w; + + internal uint X { get; private set; } + internal uint Y { get; private set; } = y; + internal uint Z { get; private set; } = z; + internal uint W { get; private set; } = w; public FastRandom(int seed) { - _x = (uint)seed; + X = (uint)seed; } public FastRandom() @@ -33,11 +37,11 @@ namespace osu.Game.Rulesets.Mania.MathUtils /// The random value. public uint NextUInt() { - uint t = _x ^ _x << 11; - _x = _y; - _y = _z; - _z = _w; - return _w = _w ^ _w >> 19 ^ t ^ t >> 8; + uint t = X ^ X << 11; + X = Y; + Y = Z; + Z = W; + return W = W ^ W >> 19 ^ t ^ t >> 8; } /// From 481546ec7a76ba80a6e5753f9e40f1c6d94a2b45 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:49:11 +0900 Subject: [PATCH 028/190] Fix drain time not being rounded to the second --- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 930597c1ad..8ef942c683 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -103,17 +103,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy HitObject lastObject = OriginalBeatmap.HitObjects.LastOrDefault(); HitObject firstObject = OriginalBeatmap.HitObjects.FirstOrDefault(); - double drainTime = (lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0); - drainTime -= OriginalBeatmap.TotalBreakTime; + // Drain time in seconds + int drainTime = (int)(((lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0) - OriginalBeatmap.TotalBreakTime) / 1000); if (drainTime == 0) - drainTime = 10000000; - - // We need this in seconds - drainTime /= 1000; + drainTime = 100000; BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty; - conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15; + conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + (double)OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15; conversionDifficulty = Math.Min(conversionDifficulty.Value, 12); return conversionDifficulty.Value; From fe9aaf000c97abd7029a129331b14dc62b6bbc62 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:50:36 +0900 Subject: [PATCH 029/190] Fix missing conditional --- .../Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index b4160dc98b..1ea2863520 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8) convertType |= PatternType.Mirror; - else + else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) convertType |= PatternType.Gathered; } } From c1f7db80f17a013ba313aa3640fe4f21e2d9a604 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:52:09 +0900 Subject: [PATCH 030/190] Forgot to commit random change --- .../Beatmaps/ManiaBeatmapConverter.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 19fef9eb54..d76ae4f081 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -28,8 +28,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps public int TargetColumns; public readonly bool IsForCurrentRuleset; + // Internal for testing purposes + internal FastRandom Random { get; private set; } + private Pattern lastPattern = new Pattern(); - private FastRandom random; private ManiaBeatmap beatmap; @@ -62,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); - random = new FastRandom(seed); + Random = new FastRandom(seed); return base.ConvertBeatmap(original); } @@ -115,7 +117,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// The hit objects generated. private IEnumerable generateSpecific(HitObject original, IBeatmap originalBeatmap) { - var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); + var generator = new SpecificBeatmapPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); Pattern newPattern = generator.Generate(); lastPattern = newPattern; @@ -138,14 +140,17 @@ namespace osu.Game.Rulesets.Mania.Beatmaps Patterns.PatternGenerator conversion = null; if (distanceData != null) - conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); + { + var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); + conversion = generator; + } else if (endTimeData != null) - conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, originalBeatmap); + conversion = new EndTimeObjectPatternGenerator(Random, original, beatmap, originalBeatmap); else if (positionData != null) { computeDensity(original.StartTime); - conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair, originalBeatmap); + conversion = new HitObjectPatternGenerator(Random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair, originalBeatmap); recordNote(original.StartTime, positionData.Position); } From e51f96e181d1996d1da4ac4ce62e0e126e8c68e0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:52:36 +0900 Subject: [PATCH 031/190] Fix some notes not being recorded --- .../Beatmaps/ManiaBeatmapConverter.cs | 12 +++++ .../Legacy/DistanceObjectPatternGenerator.cs | 47 ++++++++++--------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index d76ae4f081..bc2c9943db 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -136,6 +136,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var endTimeData = original as IHasEndTime; var distanceData = original as IHasDistance; var positionData = original as IHasPosition; + var repeatsData = original as IHasRepeats; Patterns.PatternGenerator conversion = null; @@ -143,9 +144,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); conversion = generator; + + for (double time = original.StartTime; time <= generator.EndTime; time += generator.SegmentDuration) + { + recordNote(time, positionData?.Position ?? Vector2.Zero); + computeDensity(time); + } } else if (endTimeData != null) + { conversion = new EndTimeObjectPatternGenerator(Random, original, beatmap, originalBeatmap); + + recordNote(endTimeData.EndTime, new Vector2(256, 192)); + computeDensity(endTimeData.EndTime); + } else if (positionData != null) { computeDensity(original.StartTime); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index f60958d581..a4275be504 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -24,8 +24,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// private const float osu_base_scoring_distance = 100; - private readonly double endTime; - private readonly double segmentDuration; + public readonly double EndTime; + public readonly double SegmentDuration; + private readonly int spanCount; private PatternType convertType; @@ -52,8 +53,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy // The duration of the osu! hit object double osuDuration = distance / osuVelocity; - endTime = hitObject.StartTime + osuDuration; - segmentDuration = (endTime - HitObject.StartTime) / spanCount; + EndTime = hitObject.StartTime + osuDuration; + SegmentDuration = (EndTime - HitObject.StartTime) / spanCount; } public override Pattern Generate() @@ -61,44 +62,44 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (TotalColumns == 1) { var pattern = new Pattern(); - addToPattern(pattern, 0, HitObject.StartTime, endTime); + addToPattern(pattern, 0, HitObject.StartTime, EndTime); return pattern; } if (spanCount > 1) { - if (segmentDuration <= 90) + if (SegmentDuration <= 90) return generateRandomHoldNotes(HitObject.StartTime, 1); - if (segmentDuration <= 120) + if (SegmentDuration <= 120) { convertType |= PatternType.ForceNotStack; return generateRandomNotes(HitObject.StartTime, spanCount + 1); } - if (segmentDuration <= 160) + if (SegmentDuration <= 160) return generateStair(HitObject.StartTime); - if (segmentDuration <= 200 && ConversionDifficulty > 3) + if (SegmentDuration <= 200 && ConversionDifficulty > 3) return generateRandomMultipleNotes(HitObject.StartTime); - double duration = endTime - HitObject.StartTime; + double duration = EndTime - HitObject.StartTime; if (duration >= 4000) return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0); - if (segmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart) + if (SegmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart) return generateTiledHoldNotes(HitObject.StartTime); return generateHoldAndNormalNotes(HitObject.StartTime); } - if (segmentDuration <= 110) + if (SegmentDuration <= 110) { if (PreviousPattern.ColumnWithObjects < TotalColumns) convertType |= PatternType.ForceNotStack; else convertType &= ~PatternType.ForceNotStack; - return generateRandomNotes(HitObject.StartTime, segmentDuration < 80 ? 1 : 2); + return generateRandomNotes(HitObject.StartTime, SegmentDuration < 80 ? 1 : 2); } if (ConversionDifficulty > 6.5) @@ -148,7 +149,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column nextColumn = Random.Next(RandomStart, TotalColumns); - addToPattern(pattern, nextColumn, startTime, endTime); + addToPattern(pattern, nextColumn, startTime, EndTime); } // This is can't be combined with the above loop due to RNG @@ -156,7 +157,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { while (pattern.ColumnHasObject(nextColumn)) nextColumn = Random.Next(RandomStart, TotalColumns); - addToPattern(pattern, nextColumn, startTime, endTime); + addToPattern(pattern, nextColumn, startTime, EndTime); } return pattern; @@ -193,7 +194,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy nextColumn = Random.Next(RandomStart, TotalColumns); lastColumn = nextColumn; - startTime += segmentDuration; + startTime += SegmentDuration; } return pattern; @@ -223,7 +224,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy for (int i = 0; i <= spanCount; i++) { addToPattern(pattern, column, startTime, startTime); - startTime += segmentDuration; + startTime += SegmentDuration; // Check if we're at the borders of the stage, and invert the pattern if so if (increasing) @@ -284,7 +285,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy addToPattern(pattern, nextColumn, startTime, startTime); nextColumn = Random.Next(RandomStart, TotalColumns); - startTime += segmentDuration; + startTime += SegmentDuration; } return pattern; @@ -372,8 +373,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy while (pattern.ColumnHasObject(nextColumn)) nextColumn = Random.Next(RandomStart, TotalColumns); - addToPattern(pattern, nextColumn, startTime, endTime); - startTime += segmentDuration; + addToPattern(pattern, nextColumn, startTime, EndTime); + startTime += SegmentDuration; } return pattern; @@ -402,7 +403,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy } // Create the hold note - addToPattern(pattern, holdColumn, startTime, endTime); + addToPattern(pattern, holdColumn, startTime, EndTime); int nextColumn = Random.Next(RandomStart, TotalColumns); int noteCount; @@ -434,7 +435,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy pattern.Add(rowPattern); rowPattern.Clear(); - startTime += segmentDuration; + startTime += SegmentDuration; } return pattern; @@ -452,7 +453,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (curveData == null) return HitObject.Samples; - double segmentTime = (endTime - HitObject.StartTime) / spanCount; + double segmentTime = (EndTime - HitObject.StartTime) / spanCount; int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime); return curveData.RepeatSamples[index]; From 5f5d797c1effc6ae2f9c96811ab6e5272ebdf347 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 21:06:35 +0900 Subject: [PATCH 032/190] Remove unused field --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index bc2c9943db..0f99f999da 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -136,7 +136,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var endTimeData = original as IHasEndTime; var distanceData = original as IHasDistance; var positionData = original as IHasPosition; - var repeatsData = original as IHasRepeats; Patterns.PatternGenerator conversion = null; From 53a6d01304a3540f8a9f3684e471f683ad4c14a3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 21:06:54 +0900 Subject: [PATCH 033/190] Fix stair type not being flipped correctly --- .../Legacy/HitObjectPatternGenerator.cs | 199 +++++++++--------- 1 file changed, 100 insertions(+), 99 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 1ea2863520..2210c76788 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -89,120 +89,121 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public override Pattern Generate() { - if (TotalColumns == 1) + var pattern = new Pattern(); + + try { - var pattern = new Pattern(); - addToPattern(pattern, 0); - return pattern; - } - - int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0; - - if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any()) - { - // Generate a new pattern by copying the last hit objects in reverse-column order - var pattern = new Pattern(); - - for (int i = RandomStart; i < TotalColumns; i++) - if (PreviousPattern.ColumnHasObject(i)) - addToPattern(pattern, RandomStart + TotalColumns - i - 1); - - return pattern; - } - - if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 - // If we convert to 7K + 1, let's not overload the special key - && (TotalColumns != 8 || lastColumn != 0) - // Make sure the last column was not the centre column - && (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2)) - { - // Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object) - var pattern = new Pattern(); - - int column = RandomStart + TotalColumns - lastColumn - 1; - addToPattern(pattern, column); - - return pattern; - } - - if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any()) - { - // Generate a new pattern by placing on the already filled columns - var pattern = new Pattern(); - - for (int i = RandomStart; i < TotalColumns; i++) - if (PreviousPattern.ColumnHasObject(i)) - addToPattern(pattern, i); - - return pattern; - } - - if ((convertType & PatternType.Stair) > 0 && PreviousPattern.HitObjects.Count() == 1) - { - // Generate a new pattern by placing on the next column, cycling back to the start if there is no "next" - var pattern = new Pattern(); - - int targetColumn = lastColumn + 1; - if (targetColumn == TotalColumns) + if (TotalColumns == 1) { - targetColumn = RandomStart; - StairType = PatternType.ReverseStair; + addToPattern(pattern, 0); + return pattern; } - addToPattern(pattern, targetColumn); - return pattern; - } + int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0; - if ((convertType & PatternType.ReverseStair) > 0 && PreviousPattern.HitObjects.Count() == 1) - { - // Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous" - var pattern = new Pattern(); - - int targetColumn = lastColumn - 1; - if (targetColumn == RandomStart - 1) + if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any()) { - targetColumn = TotalColumns - 1; - StairType = PatternType.Stair; + // Generate a new pattern by copying the last hit objects in reverse-column order + for (int i = RandomStart; i < TotalColumns; i++) + if (PreviousPattern.ColumnHasObject(i)) + addToPattern(pattern, RandomStart + TotalColumns - i - 1); + + return pattern; } - addToPattern(pattern, targetColumn); - return pattern; - } + if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 + // If we convert to 7K + 1, let's not overload the special key + && (TotalColumns != 8 || lastColumn != 0) + // Make sure the last column was not the centre column + && (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2)) + { + // Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object) + int column = RandomStart + TotalColumns - lastColumn - 1; + addToPattern(pattern, column); - if ((convertType & PatternType.KeepSingle) > 0) - return generateRandomNotes(1); + return pattern; + } + + if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any()) + { + // Generate a new pattern by placing on the already filled columns + for (int i = RandomStart; i < TotalColumns; i++) + if (PreviousPattern.ColumnHasObject(i)) + addToPattern(pattern, i); + + return pattern; + } + + if (PreviousPattern.HitObjects.Count() == 1) + { + if ((convertType & PatternType.Stair) > 0) + { + // Generate a new pattern by placing on the next column, cycling back to the start if there is no "next" + int targetColumn = lastColumn + 1; + if (targetColumn == TotalColumns) + targetColumn = RandomStart; + + addToPattern(pattern, targetColumn); + return pattern; + } + + if ((convertType & PatternType.ReverseStair) > 0) + { + // Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous" + int targetColumn = lastColumn - 1; + if (targetColumn == RandomStart - 1) + targetColumn = TotalColumns - 1; + + addToPattern(pattern, targetColumn); + return pattern; + } + } + + if ((convertType & PatternType.KeepSingle) > 0) + return pattern = generateRandomNotes(1); + + if ((convertType & PatternType.Mirror) > 0) + { + if (ConversionDifficulty > 6.5) + return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12); + if (ConversionDifficulty > 4) + return pattern = generateRandomPatternWithMirrored(0.12, 0.17, 0); + return pattern = generateRandomPatternWithMirrored(0.12, 0, 0); + } - if ((convertType & PatternType.Mirror) > 0) - { if (ConversionDifficulty > 6.5) - return generateRandomPatternWithMirrored(0.12, 0.38, 0.12); + { + if ((convertType & PatternType.LowProbability) > 0) + return pattern = generateRandomPattern(0.78, 0.42, 0, 0); + return pattern = generateRandomPattern(1, 0.62, 0, 0); + } + if (ConversionDifficulty > 4) - return generateRandomPatternWithMirrored(0.12, 0.17, 0); - return generateRandomPatternWithMirrored(0.12, 0, 0); - } + { + if ((convertType & PatternType.LowProbability) > 0) + return pattern = generateRandomPattern(0.35, 0.08, 0, 0); + return pattern = generateRandomPattern(0.52, 0.15, 0, 0); + } - if (ConversionDifficulty > 6.5) + if (ConversionDifficulty > 2) + { + if ((convertType & PatternType.LowProbability) > 0) + return pattern = generateRandomPattern(0.18, 0, 0, 0); + return pattern = generateRandomPattern(0.45, 0, 0, 0); + } + + return pattern = generateRandomPattern(0, 0, 0, 0); + } + finally { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.78, 0.42, 0, 0); - return generateRandomPattern(1, 0.62, 0, 0); + foreach (var obj in pattern.HitObjects) + { + if ((convertType & PatternType.Stair) > 0 && obj.Column == TotalColumns - 1) + StairType = PatternType.ReverseStair; + if ((convertType & PatternType.ReverseStair) > 0 && obj.Column == RandomStart) + StairType = PatternType.Stair; + } } - - if (ConversionDifficulty > 4) - { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.35, 0.08, 0, 0); - return generateRandomPattern(0.52, 0.15, 0, 0); - } - - if (ConversionDifficulty > 2) - { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.18, 0, 0, 0); - return generateRandomPattern(0.45, 0, 0, 0); - } - - return generateRandomPattern(0, 0, 0, 0); } /// From f0fbc04d92cbafae7a9a71a8f017cc4794448978 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 15 Jun 2018 14:11:21 +0200 Subject: [PATCH 034/190] Adjust formats to be EN-UK --- osu.Game/Graphics/DrawableDate.cs | 2 +- osu.Game/Graphics/DrawableJoinDate.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index df6aa72c37..d846ccbc4a 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -62,6 +62,6 @@ namespace osu.Game.Graphics private void updateTime() => Format(); - public virtual string TooltipText => string.Format($"{date:d MMMM yyyy H:mm \"UTC\"z}"); + public virtual string TooltipText => string.Format($"{date:MMMM d, yyyy h:mm tt \"UTC\"z}"); } } diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs index 713bd4e44f..46de28be8a 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -16,6 +16,6 @@ namespace osu.Game.Graphics protected override string Format() => Text = string.Format($"{date:MMMM yyyy}"); - public override string TooltipText => string.Format($"{date:d MMMM yyyy}"); + public override string TooltipText => string.Format($"{date:MMMM d, yyyy}"); } } From d122547c1ea1c97d9e9b2bc9312784fe37c74ad4 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 15 Jun 2018 14:28:49 +0200 Subject: [PATCH 035/190] DrawableJoinDate handles "Here since the beginning" text --- osu.Game/Graphics/DrawableJoinDate.cs | 4 +++- osu.Game/Overlays/Profile/ProfileHeader.cs | 9 +++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs index 46de28be8a..763aea60ba 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -14,7 +14,9 @@ namespace osu.Game.Graphics this.date = date; } - protected override string Format() => Text = string.Format($"{date:MMMM yyyy}"); + protected override string Format() => Text = date.ToUniversalTime().Year < 2008 ? + "Here since the beginning" : + string.Format($"{date:MMMM yyyy}"); public override string TooltipText => string.Format($"{date:MMMM d, yyyy}"); } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 996c6384c9..43482c147f 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -357,16 +357,13 @@ namespace osu.Game.Overlays.Profile infoTextLeft.NewParagraph(); - if (user.JoinDate.ToUniversalTime().Year < 2008) - { - infoTextLeft.AddText("Here since the beginning", boldItalic); - } - else + if (user.JoinDate.ToUniversalTime().Year >= 2008) { infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); } + infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); + infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); infoTextLeft.AddText(new DrawableDate(user.LastVisit), boldItalic); From 38feb7651cf32af4e323eb190dd40b84b8c24532 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 15 Jun 2018 14:34:01 +0200 Subject: [PATCH 036/190] Set text at updateTime --- osu.Game/Graphics/DrawableDate.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index d846ccbc4a..b725f46e76 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -58,9 +58,9 @@ namespace osu.Game.Graphics public override bool HandleMouseInput => true; - protected virtual string Format() => Text = date.Humanize(); + protected virtual string Format() => date.Humanize(); - private void updateTime() => Format(); + private void updateTime() => Text = Format(); public virtual string TooltipText => string.Format($"{date:MMMM d, yyyy h:mm tt \"UTC\"z}"); } From 6938adc148c9a99e8fbc8e2a1399e4600cc6f15e Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 15 Jun 2018 15:00:41 +0200 Subject: [PATCH 037/190] Unify join time text's visual format with the web --- osu.Game/Overlays/Profile/ProfileHeader.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 43482c147f..29873b5a6a 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -357,12 +357,16 @@ namespace osu.Game.Overlays.Profile infoTextLeft.NewParagraph(); - if (user.JoinDate.ToUniversalTime().Year >= 2008) + if (user.JoinDate.ToUniversalTime().Year < 2008) + { + infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), lightText); + } + else { infoTextLeft.AddText("Joined ", lightText); + infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); } - infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); From faff7feef1e5491c07903935e9380d3cf735a135 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 15 Jun 2018 15:03:09 +0200 Subject: [PATCH 038/190] Remove unnecessary white space change --- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 29873b5a6a..0db145f64a 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -367,7 +367,6 @@ namespace osu.Game.Overlays.Profile infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); } - infoTextLeft.NewLine(); infoTextLeft.AddText("Last seen ", lightText); infoTextLeft.AddText(new DrawableDate(user.LastVisit), boldItalic); From 2d59ae9354249a2e39930db38f1a74e24175bcbb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 22:08:24 +0900 Subject: [PATCH 039/190] Commit forgotten variable --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 0f99f999da..536b1a8552 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps private double lastTime; private Vector2 lastPosition; - private PatternType lastStair; + private PatternType lastStair = PatternType.Stair; private void recordNote(double time, Vector2 position) { lastTime = time; From 55f0b3c42cc895ca859a3864c60714d973271647 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 22:10:57 +0900 Subject: [PATCH 040/190] Distance object generator should output a secondary pattern In osu!stable, only the hitobjects which ended at the distance object's EndTime would be considered for further pattern generation. Previously this generator was group _all_ objects including those that don't end at the object's EndTime, resulting in incorrect hitobject count for further pattern generation. --- .../Beatmaps/ManiaBeatmapConverter.cs | 29 +++++++++++++------ .../Legacy/DistanceObjectPatternGenerator.cs | 26 ++++++++++++++++- .../Legacy/EndTimeObjectPatternGenerator.cs | 7 ++++- .../Legacy/HitObjectPatternGenerator.cs | 8 ++++- .../Beatmaps/Patterns/PatternGenerator.cs | 7 +++-- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 536b1a8552..2c4c7b0f18 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -119,10 +119,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { var generator = new SpecificBeatmapPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); - Pattern newPattern = generator.Generate(); - lastPattern = newPattern; + foreach (var newPattern in generator.Generate()) + { + lastPattern = newPattern; - return newPattern.HitObjects; + foreach (var obj in newPattern.HitObjects) + yield return obj; + } } /// @@ -167,14 +170,17 @@ namespace osu.Game.Rulesets.Mania.Beatmaps } if (conversion == null) - return null; + yield break; - Pattern newPattern = conversion.Generate(); + foreach (var newPattern in conversion.Generate()) + { + lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern; + lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair; - lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern; - lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair; + foreach (var obj in newPattern.HitObjects) + yield return obj; - return newPattern.HitObjects; + } } /// @@ -187,7 +193,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { } - public override Pattern Generate() + public override IEnumerable Generate() + { + yield return generate(); + } + + private Pattern generate() { var endTimeData = HitObject as IHasEndTime; var positionData = HitObject as IHasXPosition; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index a4275be504..e33af44df2 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.MathUtils; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.MathUtils; @@ -57,7 +58,30 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy SegmentDuration = (EndTime - HitObject.StartTime) / spanCount; } - public override Pattern Generate() + public override IEnumerable Generate() + { + var originalPattern = generate(); + + // We need to split the intermediate pattern into two new patterns: + // 1. A pattern containing all objects that do not end at our EndTime. + // 2. A pattern containing all objects that end at our EndTime. This will be used for further pattern generation. + var intermediatePattern = new Pattern(); + var endTimePattern = new Pattern(); + + foreach (var obj in originalPattern.HitObjects) + { + if (!Precision.AlmostEquals(EndTime, (obj as IHasEndTime)?.EndTime ?? obj.StartTime)) + intermediatePattern.Add(obj); + else + endTimePattern.Add(obj); + } + + + yield return intermediatePattern; + yield return endTimePattern; + } + + private Pattern generate() { if (TotalColumns == 1) { diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 3f34afee85..0f170e8540 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -24,7 +24,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy endTime = endtimeData?.EndTime ?? 0; } - public override Pattern Generate() + public override IEnumerable Generate() + { + yield return generate(); + } + + private Pattern generate() { var pattern = new Pattern(); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 2210c76788..0e839d87a2 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.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 System.Linq; using OpenTK; using osu.Game.Audio; @@ -87,7 +88,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy } } - public override Pattern Generate() + public override IEnumerable Generate() + { + yield return generate(); + } + + private Pattern generate() { var pattern = new Pattern(); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index 2bfcd52b6a..a42d57cdd1 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.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.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns @@ -42,9 +43,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns } /// - /// Generates the pattern for , filled with hit objects. + /// Generates the patterns for , each filled with hit objects. /// - /// The containing the hit objects. - public abstract Pattern Generate(); + /// The s containing the hit objects. + public abstract IEnumerable Generate(); } } From 8529cece4a65bc006d4946fabee4cab9e98c48c5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 20:17:19 +0900 Subject: [PATCH 041/190] Fix precision error --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 2c4c7b0f18..e21738f8c8 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); conversion = generator; - for (double time = original.StartTime; time <= generator.EndTime; time += generator.SegmentDuration) + for (double time = original.StartTime; !Precision.DefinitelyBigger(time, generator.EndTime); time += generator.SegmentDuration) { recordNote(time, positionData?.Position ?? Vector2.Zero); computeDensity(time); From 0625bfda301f8dfea9531d9c14c765bf9c66a855 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 20:17:49 +0900 Subject: [PATCH 042/190] Don't split single hitobject into multiple patterns --- .../Patterns/Legacy/DistanceObjectPatternGenerator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index e33af44df2..e96ba19c80 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -62,6 +62,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { var originalPattern = generate(); + if (originalPattern.HitObjects.Count() == 1) + { + yield return originalPattern; + yield break; + } + // We need to split the intermediate pattern into two new patterns: // 1. A pattern containing all objects that do not end at our EndTime. // 2. A pattern containing all objects that end at our EndTime. This will be used for further pattern generation. @@ -76,7 +82,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy endTimePattern.Add(obj); } - yield return intermediatePattern; yield return endTimePattern; } From f090e82b638a2dc0a6f82f76e803d79039028e43 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 21:06:09 +0900 Subject: [PATCH 043/190] Fix inverted conditional --- .../Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index e96ba19c80..280c2f45d4 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -359,7 +359,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH; + bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH; bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0; canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample); From a623155b9fbe87236acbafbcc0d302ac30cfde63 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 19 Jun 2018 13:51:53 +0900 Subject: [PATCH 044/190] Fix missing using --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index e21738f8c8..c15b303048 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -5,6 +5,7 @@ using osu.Game.Rulesets.Mania.Objects; using System; using System.Linq; using System.Collections.Generic; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; From 6cd9a22e265ad31688eadc4d41247a1b851c2a19 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 19 Jun 2018 13:52:14 +0900 Subject: [PATCH 045/190] Update testcase --- .../ManiaBeatmapConversionTest.cs | 1 - .../Beatmaps/basic-expected-conversion.json | 229 ++++++++++-------- 2 files changed, 129 insertions(+), 101 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index c13319ace9..33ac1e00e4 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -18,7 +18,6 @@ namespace osu.Game.Rulesets.Mania.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; - [NonParallelizable] [TestCase("basic")] public new void Test(string name) { diff --git a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json index d593b2b052..753db99856 100644 --- a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json +++ b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json @@ -1,103 +1,132 @@ { "Mappings": [{ - "StartTime": 500, - "Objects": [{ - "StartTime": 500, - "EndTime": 2500, - "Column": 0 - }, - { - "StartTime": 1500, - "EndTime": 2500, - "Column": 1 - } - ] - }, - { - "StartTime": 3000, - "Objects": [{ - "StartTime": 3000, - "EndTime": 4000, - "Column": 2 - }] - }, - { - "StartTime": 4500, - "Objects": [{ - "StartTime": 4500, - "EndTime": 5500, - "Column": 4 - }] - }, - { - "StartTime": 6000, - "Objects": [{ - "StartTime": 6000, - "EndTime": 6500, - "Column": 2 - }] - }, - { - "StartTime": 7000, - "Objects": [{ - "StartTime": 7000, - "EndTime": 8000, - "Column": 2 - }] - }, - { - "StartTime": 8500, - "Objects": [{ - "StartTime": 8500, - "EndTime": 11000, - "Column": 0 - }] - }, - { - "StartTime": 11500, - "Objects": [{ - "StartTime": 11500, - "EndTime": 12000, - "Column": 1 - }] - }, - { - "StartTime": 12500, - "Objects": [{ - "StartTime": 12500, - "EndTime": 16500, - "Column": 4 - }] - }, - { - "StartTime": 17000, - "Objects": [{ - "StartTime": 17000, - "EndTime": 18000, - "Column": 2 - }] - }, - { - "StartTime": 18500, - "Objects": [{ - "StartTime": 18500, - "EndTime": 19450, - "Column": 0 - }] - }, - { - "StartTime": 19875, - "Objects": [{ - "StartTime": 19875, - "EndTime": 23875, - "Column": 1 - }, - { - "StartTime": 19875, - "EndTime": 23875, - "Column": 0 - } - ] - } - ] + "RandomW": 2659373485, + "RandomX": 3579807591, + "RandomY": 273326509, + "RandomZ": 272969173, + "StartTime": 500.0, + "Objects": [{ + "StartTime": 500.0, + "EndTime": 2500.0, + "Column": 0 + }, { + "StartTime": 1500.0, + "EndTime": 2500.0, + "Column": 1 + }] + }, { + "RandomW": 3083803045, + "RandomX": 273326509, + "RandomY": 272969173, + "RandomZ": 2659373485, + "StartTime": 3000.0, + "Objects": [{ + "StartTime": 3000.0, + "EndTime": 4000.0, + "Column": 2 + }] + }, { + "RandomW": 4073554232, + "RandomX": 272969173, + "RandomY": 2659373485, + "RandomZ": 3083803045, + "StartTime": 4500.0, + "Objects": [{ + "StartTime": 4500.0, + "EndTime": 5500.0, + "Column": 4 + }] + }, { + "RandomW": 3420401969, + "RandomX": 2659373485, + "RandomY": 3083803045, + "RandomZ": 4073554232, + "StartTime": 6000.0, + "Objects": [{ + "StartTime": 6000.0, + "EndTime": 6500.0, + "Column": 2 + }] + }, { + "RandomW": 1129881182, + "RandomX": 3083803045, + "RandomY": 4073554232, + "RandomZ": 3420401969, + "StartTime": 7000.0, + "Objects": [{ + "StartTime": 7000.0, + "EndTime": 8000.0, + "Column": 2 + }] + }, { + "RandomW": 315568458, + "RandomX": 3420401969, + "RandomY": 1129881182, + "RandomZ": 2358617505, + "StartTime": 8500.0, + "Objects": [{ + "StartTime": 8500.0, + "EndTime": 11000.0, + "Column": 0 + }] + }, { + "RandomW": 548134043, + "RandomX": 1129881182, + "RandomY": 2358617505, + "RandomZ": 315568458, + "StartTime": 11500.0, + "Objects": [{ + "StartTime": 11500.0, + "EndTime": 12000.0, + "Column": 1 + }] + }, { + "RandomW": 3979422122, + "RandomX": 548134043, + "RandomY": 2810584254, + "RandomZ": 2250186050, + "StartTime": 12500.0, + "Objects": [{ + "StartTime": 12500.0, + "EndTime": 16500.0, + "Column": 4 + }] + }, { + "RandomW": 2466283411, + "RandomX": 2810584254, + "RandomY": 2250186050, + "RandomZ": 3979422122, + "StartTime": 17000.0, + "Objects": [{ + "StartTime": 17000.0, + "EndTime": 18000.0, + "Column": 2 + }] + }, { + "RandomW": 83157665, + "RandomX": 2250186050, + "RandomY": 3979422122, + "RandomZ": 2466283411, + "StartTime": 18500.0, + "Objects": [{ + "StartTime": 18500.0, + "EndTime": 19450.0, + "Column": 0 + }] + }, { + "RandomW": 2383087700, + "RandomX": 83157665, + "RandomY": 2055150192, + "RandomZ": 510071020, + "StartTime": 19875.0, + "Objects": [{ + "StartTime": 19875.0, + "EndTime": 23875.0, + "Column": 1 + }, { + "StartTime": 19875.0, + "EndTime": 23875.0, + "Column": 0 + }] + }] } \ No newline at end of file From b95042e370bcb946cf75ec2eb5e6c4e4ec438e0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 20 Jun 2018 12:43:48 +0900 Subject: [PATCH 046/190] Fix background screens not supporting early-exit condition Closes #2681. --- osu.Game/Screens/BackgroundScreen.cs | 11 +++++++++-- osu.Game/Screens/OsuScreen.cs | 9 ++++----- osu.Game/osu.Game.csproj | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index 5e9863f642..61277439c1 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -37,10 +37,17 @@ namespace osu.Game.Screens } // Make sure the in-progress loading is complete before pushing the screen. - while (screen.LoadState < LoadState.Ready) + while (screen.LoadState != LoadState.Ready) Thread.Sleep(1); - base.Push(screen); + try + { + base.Push(screen); + } + catch (InvalidOperationException) + { + // screen may have exited before the push was successful. + } } protected override void Update() diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 61018f9e08..865b4c9070 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -195,11 +195,10 @@ namespace osu.Game.Screens if (Background != null && !Background.Equals(nextOsu?.Background)) { - if (nextOsu != null) - //We need to use MakeCurrent in case we are jumping up multiple game screens. - nextOsu.Background?.MakeCurrent(); - else - Background.Exit(); + Background.Exit(); + + //We need to use MakeCurrent in case we are jumping up multiple game screens. + nextOsu?.Background?.MakeCurrent(); } if (base.OnExiting(next)) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f0bc330994..21ba229543 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From a2fa55c4267f783459b855a58457ef77828a1eb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Jun 2018 16:47:05 +0900 Subject: [PATCH 047/190] Fix dialog overlay playing double samples on show/hide --- .../Containers/OsuFocusedOverlayContainer.cs | 12 ++++++++---- osu.Game/Overlays/DialogOverlay.cs | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 0528f7b3ae..e270b5efbe 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -17,6 +17,8 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; + protected virtual bool PlaySamplesOnStateChange => true; + protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] @@ -28,7 +30,7 @@ namespace osu.Game.Graphics.Containers samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); - StateChanged += onStateChanged; + StateChanged += OnStateChanged; } /// @@ -51,18 +53,20 @@ namespace osu.Game.Graphics.Containers return base.OnClick(state); } - private void onStateChanged(Visibility visibility) + protected virtual void OnStateChanged(Visibility visibility) { switch (visibility) { case Visibility.Visible: if (OverlayActivationMode != OverlayActivation.Disabled) - samplePopIn?.Play(); + { + if (PlaySamplesOnStateChange) samplePopIn?.Play(); + } else State = Visibility.Hidden; break; case Visibility.Hidden: - samplePopOut?.Play(); + if (PlaySamplesOnStateChange) samplePopOut?.Play(); break; } } diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index 7caab0dd6c..e26a3cba2f 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -30,6 +30,8 @@ namespace osu.Game.Overlays State = Visibility.Visible; } + protected override bool PlaySamplesOnStateChange => false; + private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v) { if (v != Visibility.Hidden) return; From e180d49304356b0d54fe0003467ecd43b70d24e3 Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sat, 23 Jun 2018 16:37:58 +0200 Subject: [PATCH 048/190] preload BASS --- .vscode/launch.json | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ed67fa92cc..2c781363af 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,12 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tests (Debug)", - "env": {}, + "linux": { + "env": { + "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/libbass.so", + "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/", + }, + }, "console": "internalConsole" }, { @@ -24,7 +29,12 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tests (Release)", - "env": {}, + "linux": { + "env": { + "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/libbass.so", + "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/", + }, + }, "console": "internalConsole" }, { @@ -37,7 +47,12 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Debug)", - "env": {}, + "linux": { + "env": { + "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/libbass.so", + "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/", + }, + }, "console": "internalConsole" }, { @@ -50,7 +65,12 @@ ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Release)", - "env": {}, + "linux": { + "env": { + "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/libbass.so", + "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/", + }, + }, "console": "internalConsole" } ] From 2a72062c338dab4845b706bcca22dd142f1adfca Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Tue, 26 Jun 2018 00:53:31 +0300 Subject: [PATCH 049/190] Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs | 2 +- osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index c7c9f4a01a..8223855b14 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; - double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectN.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + double stackThreshold = objectI.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 999e33e51a..e04b4d45f6 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI private void loadBarLines() { TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1]; - double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime; + double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime); var timingPoints = Beatmap.ControlPointInfo.TimingPoints.ToList(); diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index f13d96b35e..6a1b3f8502 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Replays //a button is in a pressed state IsImportant(currentDirection > 0 ? CurrentFrame : NextFrame) && //the next frame is within an allowable time span - Math.Abs(CurrentTime - NextFrame?.Time ?? 0) <= sixty_frame_time * 1.2; + Math.Abs(CurrentTime - (NextFrame?.Time ?? 0)) <= sixty_frame_time * 1.2; protected virtual bool IsImportant(TFrame frame) => false; From b0a1b25983d32a9cd2882292173039ab7d93ed15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 16:32:20 +0900 Subject: [PATCH 050/190] Privatise game ruleset and access via DI Also decouples the bindable at SongSelect, where it is debounced in line with the carousel being updated. --- osu.Game/OsuGame.cs | 11 ++++++----- osu.Game/Overlays/Direct/FilterControl.cs | 6 ++---- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 6 +++--- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 6 +++--- osu.Game/Screens/OsuScreen.cs | 14 ++++++++------ osu.Game/Screens/Select/BeatmapInfoWedge.cs | 6 +++--- osu.Game/Screens/Select/FilterControl.cs | 6 +++--- .../Screens/Select/Leaderboards/Leaderboard.cs | 10 ++++------ osu.Game/Screens/Select/SongSelect.cs | 11 +++++++---- 9 files changed, 39 insertions(+), 37 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ba8685b5b2..e92c1c495b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -85,7 +85,7 @@ namespace osu.Game private OnScreenDisplay onscreenDisplay; private Bindable configRuleset; - public Bindable Ruleset = new Bindable(); + private readonly Bindable ruleset = new Bindable(); private Bindable configSkin; @@ -146,11 +146,12 @@ namespace osu.Game } dependencies.CacheAs(this); + dependencies.CacheAs(ruleset); // bind config int to database RulesetInfo configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); - Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); - Ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; + ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); + ruleset.ValueChanged += r => configRuleset.Value = r.ID ?? 0; // bind config int to database SkinInfo configSkin = LocalConfig.GetBindable(OsuSetting.Skin); @@ -216,7 +217,7 @@ namespace osu.Game return; } - Ruleset.Value = s.Ruleset; + ruleset.Value = s.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap); Beatmap.Value.Mods.Value = s.Mods; @@ -550,7 +551,7 @@ namespace osu.Game // the use case for not applying is in visual/unit tests. bool applyRestrictions = !currentScreen?.AllowBeatmapRulesetChange ?? false; - Ruleset.Disabled = applyRestrictions; + ruleset.Disabled = applyRestrictions; Beatmap.Disabled = applyRestrictions; mainContent.Padding = new MarginPadding { Top = ToolbarOffset }; diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 4f4348c131..df98cc3c32 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -35,15 +35,13 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader(true)] - private void load(OsuGame game, RulesetStore rulesets, OsuColour colours) + private void load(RulesetStore rulesets, OsuColour colours, Bindable ruleset) { DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; - Ruleset.Value = game?.Ruleset.Value ?? rulesets.GetRuleset(0); + Ruleset.Value = ruleset ?? rulesets.GetRuleset(0); foreach (var r in rulesets.AvailableRulesets) - { modeButtons.Add(new RulesetToggleButton(Ruleset, r)); - } } private class RulesetToggleButton : OsuClickableContainer diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index f1624721da..48b7907572 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Mods } [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, OsuGame osu, RulesetStore rulesets, AudioManager audio) + private void load(OsuColour colours, Bindable ruleset, RulesetStore rulesets, AudioManager audio) { SelectedMods.ValueChanged += selectedModsChanged; @@ -60,8 +60,8 @@ namespace osu.Game.Overlays.Mods HighMultiplierColour = colours.Green; UnrankedLabel.Colour = colours.Blue; - if (osu != null) - Ruleset.BindTo(osu.Ruleset); + if (ruleset != null) + Ruleset.BindTo(ruleset); else Ruleset.Value = rulesets.AvailableRulesets.First(); diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 3078c44844..4a9af50467 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Toolbar } [BackgroundDependencyLoader(true)] - private void load(RulesetStore rulesets, OsuGame game) + private void load(RulesetStore rulesets, Bindable parentRuleset) { this.rulesets = rulesets; foreach (var r in rulesets.AvailableRulesets) @@ -83,8 +83,8 @@ namespace osu.Game.Overlays.Toolbar ruleset.ValueChanged += rulesetChanged; ruleset.DisabledChanged += disabledChanged; - if (game != null) - ruleset.BindTo(game.Ruleset); + if (ruleset != null) + ruleset.BindTo(parentRuleset); else ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 61018f9e08..bf650dd514 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -82,22 +82,24 @@ namespace osu.Game.Screens private SampleChannel sampleExit; [BackgroundDependencyLoader(true)] - private void load(BindableBeatmap beatmap, OsuGame osuGame, AudioManager audio) + private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable ruleset) { if (beatmap != null) Beatmap.BindTo(beatmap); - if (osuGame != null) + if (ruleset != null) + Ruleset.BindTo(ruleset); + + if (osu != null) { - Ruleset.BindTo(osuGame.Ruleset); - OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); + OverlayActivationMode.BindTo(osu.OverlayActivationMode); updateOverlayStates = () => { if (HideOverlaysOnEnter) - osuGame.CloseAllOverlays(); + osu.CloseAllOverlays(); else - osuGame.Toolbar.State = Visibility.Visible; + osu.Toolbar.State = Visibility.Visible; }; } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 7950018554..27089311f2 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -53,10 +53,10 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader(true)] - private void load([CanBeNull] OsuGame osuGame) + private void load([CanBeNull] Bindable parentRuleset) { - if (osuGame != null) - ruleset.BindTo(osuGame.Ruleset); + if (parentRuleset != null) + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += _ => updateDisplay(); } diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index f9f3db3827..abf14a653b 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -170,15 +170,15 @@ namespace osu.Game.Screens.Select public readonly Box Background; [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, OsuGame osu, OsuConfigManager config) + private void load(OsuColour colours, Bindable parentRuleset, OsuConfigManager config) { sortTabs.AccentColour = colours.GreenLight; showConverted = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); showConverted.ValueChanged += val => updateCriteria(); - if (osu != null) - ruleset.BindTo(osu.Ruleset); + if (parentRuleset != null) + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += val => updateCriteria(); ruleset.TriggerChange(); } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 9dae8fb273..605cf46ce6 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -174,7 +174,6 @@ namespace osu.Game.Screens.Select.Leaderboards private APIAccess api; private BeatmapInfo beatmap; - private OsuGame osuGame; private ScheduledDelegate pendingBeatmapSwitch; @@ -195,15 +194,14 @@ namespace osu.Game.Screens.Select.Leaderboards } [BackgroundDependencyLoader(permitNulls: true)] - private void load(APIAccess api, OsuGame osuGame) + private void load(APIAccess api, Bindable parentRuleset) { this.api = api; - this.osuGame = osuGame; - if (osuGame != null) - ruleset.BindTo(osuGame.Ruleset); + if (parentRuleset != null) + ruleset.BindTo(parentRuleset); - ruleset.ValueChanged += r => updateScores(); + ruleset.ValueChanged += _ => updateScores(); if (api != null) api.OnStateChange += handleApiStateChange; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 70b473bcd9..d9ee72a0d3 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -17,6 +18,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; +using osu.Game.Rulesets; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Edit; using osu.Game.Screens.Menu; @@ -62,6 +64,8 @@ namespace osu.Game.Screens.Select private SampleChannel sampleChangeDifficulty; private SampleChannel sampleChangeBeatmap; + protected new readonly Bindable Ruleset = new Bindable(); + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); @@ -176,8 +180,9 @@ namespace osu.Game.Screens.Select } } + [BackgroundDependencyLoader(true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours) { dependencies.CacheAs(this); @@ -192,9 +197,6 @@ namespace osu.Game.Screens.Select if (this.beatmaps == null) this.beatmaps = beatmaps; - if (osu != null) - Ruleset.BindTo(osu.Ruleset); - this.beatmaps.ItemAdded += onBeatmapSetAdded; this.beatmaps.ItemRemoved += onBeatmapSetRemoved; this.beatmaps.BeatmapHidden += onBeatmapHidden; @@ -280,6 +282,7 @@ namespace osu.Game.Screens.Select bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); + Ruleset.Value = base.Ruleset.Value; ensurePlayingSelected(preview); } From 388ca5d5727fa5055d439ace6c4bbd37e5c9fcff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 16:33:22 +0900 Subject: [PATCH 051/190] Move leaderboard update scheduling to a more central method --- .../Select/Leaderboards/Leaderboard.cs | 92 ++++++++++--------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 605cf46ce6..bb3ff3fc76 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -175,7 +175,7 @@ namespace osu.Game.Screens.Select.Leaderboards private APIAccess api; private BeatmapInfo beatmap; - private ScheduledDelegate pendingBeatmapSwitch; + private ScheduledDelegate pendingUpdateScores; public BeatmapInfo Beatmap { @@ -188,8 +188,7 @@ namespace osu.Game.Screens.Select.Leaderboards beatmap = value; Scores = null; - pendingBeatmapSwitch?.Cancel(); - pendingBeatmapSwitch = Schedule(updateScores); + updateScores(); } } @@ -229,51 +228,58 @@ namespace osu.Game.Screens.Select.Leaderboards private void updateScores() { - if (Scope == LeaderboardScope.Local) - { - // TODO: get local scores from wherever here. - PlaceholderState = PlaceholderState.NoScores; - return; - } + getScoresRequest?.Cancel(); + getScoresRequest = null; - if (Beatmap?.OnlineBeatmapID == null) + pendingUpdateScores?.Cancel(); + pendingUpdateScores = Schedule(() => { - PlaceholderState = PlaceholderState.Unavailable; - return; - } - - if (api?.IsLoggedIn != true) - { - PlaceholderState = PlaceholderState.NotLoggedIn; - return; - } - - if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter) - { - PlaceholderState = PlaceholderState.NotSupporter; - return; - } - - PlaceholderState = PlaceholderState.Retrieving; - loading.Show(); - - getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope); - getScoresRequest.Success += r => Schedule(() => - { - Scores = r.Scores; - PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; - }); - - getScoresRequest.Failure += e => Schedule(() => - { - if (e is OperationCanceledException) + if (Scope == LeaderboardScope.Local) + { + // TODO: get local scores from wherever here. + PlaceholderState = PlaceholderState.NoScores; return; + } - PlaceholderState = PlaceholderState.NetworkFailure; - Logger.Error(e, @"Couldn't fetch beatmap scores!"); + if (Beatmap?.OnlineBeatmapID == null) + { + PlaceholderState = PlaceholderState.Unavailable; + return; + } + + if (api?.IsLoggedIn != true) + { + PlaceholderState = PlaceholderState.NotLoggedIn; + return; + } + + if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter) + { + PlaceholderState = PlaceholderState.NotSupporter; + return; + } + + PlaceholderState = PlaceholderState.Retrieving; + loading.Show(); + + getScoresRequest = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope); + getScoresRequest.Success += r => Schedule(() => + { + Scores = r.Scores; + PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; + }); + + getScoresRequest.Failure += e => Schedule(() => + { + if (e is OperationCanceledException) + return; + + PlaceholderState = PlaceholderState.NetworkFailure; + Logger.Error(e, @"Couldn't fetch beatmap scores!"); + }); + + api.Queue(getScoresRequest); }); - - api.Queue(getScoresRequest); } private Placeholder currentPlaceholder; From 13480feb4fbf709c7e90be2dfed21dcf9fe333dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 16:38:19 +0900 Subject: [PATCH 052/190] Remove error logging Already logged to network.log with ample detail. --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index bb3ff3fc76..5f5d7c213d 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -275,7 +275,6 @@ namespace osu.Game.Screens.Select.Leaderboards return; PlaceholderState = PlaceholderState.NetworkFailure; - Logger.Error(e, @"Couldn't fetch beatmap scores!"); }); api.Queue(getScoresRequest); From 4dd12cedadfa865cdb975d549e872ea22137422f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 17:01:40 +0900 Subject: [PATCH 053/190] Fix review issues --- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 2 +- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 1 - osu.Game/Screens/Select/SongSelect.cs | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 4a9af50467..6926502d9b 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Toolbar ruleset.ValueChanged += rulesetChanged; ruleset.DisabledChanged += disabledChanged; - if (ruleset != null) + if (parentRuleset != null) ruleset.BindTo(parentRuleset); else ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 5f5d7c213d..c2a76c14c9 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -19,7 +19,6 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using System.Linq; using osu.Framework.Configuration; -using osu.Framework.Logging; using osu.Game.Rulesets; namespace osu.Game.Screens.Select.Leaderboards diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d9ee72a0d3..42005681fc 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -185,6 +185,7 @@ namespace osu.Game.Screens.Select private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours) { dependencies.CacheAs(this); + dependencies.CacheAs(Ruleset); if (Footer != null) { From 4bcc05a7fcc3917228eeaeddea72b0ca9ce701bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 18:24:34 +0900 Subject: [PATCH 054/190] Remove null checks on ruleset Add a default ruleset to `OsuTestCase` to cover testing scenarios. --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 13 ++++--------- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 8 ++------ osu.Game/Screens/OsuScreen.cs | 7 ++----- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 3 +-- osu.Game/Screens/Select/FilterControl.cs | 8 +++++--- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 5 ++--- osu.Game/Tests/Visual/OsuTestCase.cs | 11 ++++++++++- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 48b7907572..7e4c986810 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -51,8 +51,8 @@ namespace osu.Game.Overlays.Mods refreshSelectedMods(); } - [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, Bindable ruleset, RulesetStore rulesets, AudioManager audio) + [BackgroundDependencyLoader] + private void load(OsuColour colours, Bindable ruleset, AudioManager audio) { SelectedMods.ValueChanged += selectedModsChanged; @@ -60,13 +60,8 @@ namespace osu.Game.Overlays.Mods HighMultiplierColour = colours.Green; UnrankedLabel.Colour = colours.Blue; - if (ruleset != null) - Ruleset.BindTo(ruleset); - else - Ruleset.Value = rulesets.AvailableRulesets.First(); - - Ruleset.ValueChanged += rulesetChanged; - Ruleset.TriggerChange(); + Ruleset.BindTo(ruleset); + Ruleset.BindValueChanged(rulesetChanged, true); sampleOn = audio.Sample.Get(@"UI/check-on"); sampleOff = audio.Sample.Get(@"UI/check-off"); diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 6926502d9b..dae4f84b1a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Toolbar }; } - [BackgroundDependencyLoader(true)] + [BackgroundDependencyLoader] private void load(RulesetStore rulesets, Bindable parentRuleset) { this.rulesets = rulesets; @@ -82,11 +82,7 @@ namespace osu.Game.Overlays.Toolbar ruleset.ValueChanged += rulesetChanged; ruleset.DisabledChanged += disabledChanged; - - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); - else - ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); + ruleset.BindTo(parentRuleset); } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index bf650dd514..8f7ab14937 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -84,11 +84,8 @@ namespace osu.Game.Screens [BackgroundDependencyLoader(true)] private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable ruleset) { - if (beatmap != null) - Beatmap.BindTo(beatmap); - - if (ruleset != null) - Ruleset.BindTo(ruleset); + Beatmap.BindTo(beatmap); + Ruleset.BindTo(ruleset); if (osu != null) { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 27089311f2..d26702fcf9 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -55,8 +55,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load([CanBeNull] Bindable parentRuleset) { - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += _ => updateDisplay(); } diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index abf14a653b..fca6ee23d1 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -29,6 +29,7 @@ namespace osu.Game.Screens.Select private readonly TabControl groupTabs; private SortMode sort = SortMode.Title; + public SortMode Sort { get { return sort; } @@ -43,6 +44,7 @@ namespace osu.Game.Screens.Select } private GroupMode group = GroupMode.All; + public GroupMode Group { get { return group; } @@ -69,7 +71,8 @@ namespace osu.Game.Screens.Select private readonly SearchTextBox searchTextBox; - public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => base.ReceiveMouseInputAt(screenSpacePos) || groupTabs.ReceiveMouseInputAt(screenSpacePos) || sortTabs.ReceiveMouseInputAt(screenSpacePos); + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => + base.ReceiveMouseInputAt(screenSpacePos) || groupTabs.ReceiveMouseInputAt(screenSpacePos) || sortTabs.ReceiveMouseInputAt(screenSpacePos); public FilterControl() { @@ -177,8 +180,7 @@ namespace osu.Game.Screens.Select showConverted = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); showConverted.ValueChanged += val => updateCriteria(); - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += val => updateCriteria(); ruleset.TriggerChange(); } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index c2a76c14c9..560fd4e375 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -41,6 +41,7 @@ namespace osu.Game.Screens.Select.Leaderboards private ScheduledDelegate showScoresDelegate; private IEnumerable scores; + public IEnumerable Scores { get { return scores; } @@ -196,9 +197,7 @@ namespace osu.Game.Screens.Select.Leaderboards { this.api = api; - if (parentRuleset != null) - ruleset.BindTo(parentRuleset); - + ruleset.BindTo(parentRuleset); ruleset.ValueChanged += _ => updateScores(); if (api != null) diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 1740658da6..a877ce2333 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -1,10 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Configuration; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Rulesets; namespace osu.Game.Tests.Visual { @@ -13,6 +16,8 @@ namespace osu.Game.Tests.Visual private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); protected BindableBeatmap Beatmap => beatmap; + private readonly Bindable ruleset = new Bindable(); + protected DependencyContainer Dependencies { get; private set; } protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) @@ -22,13 +27,17 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(beatmap); Dependencies.CacheAs(beatmap); + Dependencies.CacheAs(ruleset); + return Dependencies; } [BackgroundDependencyLoader] - private void load(AudioManager audioManager) + private void load(AudioManager audioManager, RulesetStore rulesets) { beatmap.SetAudioManager(audioManager); + + ruleset.Value = rulesets.AvailableRulesets.First(); } protected override void Dispose(bool isDisposing) From 018dcc98b40304437a9440c925b233679a65ad40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 18:59:13 +0900 Subject: [PATCH 055/190] Fix failing tests --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 8 +++++--- osu.Game/Tests/Visual/OsuTestCase.cs | 6 +++--- osu.Game/Tests/Visual/TestCasePlayer.cs | 6 +++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index f52fecfd02..ee66f53ddc 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -65,17 +65,19 @@ namespace osu.Game.Tests.Visual foreach (var rulesetInfo in rulesets.AvailableRulesets) { - var ruleset = rulesetInfo.CreateInstance(); + var instance = rulesetInfo.CreateInstance(); var testBeatmap = createTestBeatmap(rulesetInfo); beatmaps.Add(testBeatmap); + AddStep("set ruleset", () => Ruleset.Value = rulesetInfo); + selectBeatmap(testBeatmap); - testBeatmapLabels(ruleset); + testBeatmapLabels(instance); // TODO: adjust cases once more info is shown for other gamemodes - switch (ruleset) + switch (instance) { case OsuRuleset _: testInfoLabels(5); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index a877ce2333..b3e523b63c 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); protected BindableBeatmap Beatmap => beatmap; - private readonly Bindable ruleset = new Bindable(); + protected readonly Bindable Ruleset = new Bindable(); protected DependencyContainer Dependencies { get; private set; } @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(beatmap); Dependencies.CacheAs(beatmap); - Dependencies.CacheAs(ruleset); + Dependencies.CacheAs(Ruleset); return Dependencies; } @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual { beatmap.SetAudioManager(audioManager); - ruleset.Value = rulesets.AvailableRulesets.First(); + Ruleset.Value = rulesets.AvailableRulesets.First(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 20c9646aa3..9afb1dd6cd 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -86,7 +86,11 @@ namespace osu.Game.Tests.Visual private readonly WeakList workingWeakReferences = new WeakList(); private readonly WeakList playerWeakReferences = new WeakList(); - private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); + private Player loadPlayerFor(RulesetInfo ri) + { + Ruleset.Value = ri; + return loadPlayerFor(ri.CreateInstance()); + } private Player loadPlayerFor(Ruleset r) { From 0866dd11bd2eafe83e9303caf1417cde6f262e75 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Jun 2018 12:57:26 +0900 Subject: [PATCH 056/190] DefaultBackAction -> BackAction, defaults to last button The last button is more commonly the escape condition. --- osu.Game/Screens/Play/FailOverlay.cs | 4 ---- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 6 +++--- osu.Game/Screens/Play/PauseContainer.cs | 3 +++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 1295df2da0..bbed0c8843 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Linq; using osu.Game.Graphics; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -14,8 +12,6 @@ namespace osu.Game.Screens.Play public override string Header => "failed"; public override string Description => "you're dead, try again?"; - protected override Action DefaultBackAction => () => InternalButtons.Children.Last().TriggerOnClick(); - [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index a72fca2532..52c08bb351 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -35,9 +35,9 @@ namespace osu.Game.Screens.Play public Action OnQuit; /// - /// Action that is invoked if is triggered. + /// Action that is invoked when is triggered. /// - protected virtual Action DefaultBackAction => () => InternalButtons.Children.First().TriggerOnClick(); + protected virtual Action BackAction => () => InternalButtons.Children.Last().TriggerOnClick(); public abstract string Header { get; } public abstract string Description { get; } @@ -231,7 +231,7 @@ namespace osu.Game.Screens.Play { if (action == GlobalAction.Back) { - DefaultBackAction.Invoke(); + BackAction.Invoke(); return true; } diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index 494e28a78e..e2f133dde3 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -135,6 +136,8 @@ namespace osu.Game.Screens.Play public override string Header => "paused"; public override string Description => "you're not going to do what i think you're going to do, are ya?"; + protected override Action BackAction => () => InternalButtons.Children.First().TriggerOnClick(); + [BackgroundDependencyLoader] private void load(OsuColour colours) { From b88c4464cb7eee25ae7c6791b881df7ba192f898 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Jun 2018 16:02:49 +0900 Subject: [PATCH 057/190] Make virtual beatmap tracks approximate beatmap length --- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 +- .../WorkingBeatmap_VirtualBeatmapTrack.cs | 46 +++++++++++++++++++ .../Timelines/Summary/Parts/MarkerPart.cs | 2 - .../Timelines/Summary/Parts/TimelinePart.cs | 3 +- .../Edit/Screens/Compose/Timeline/Timeline.cs | 10 ++-- 6 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 71406c6034..d086064425 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -69,7 +69,7 @@ namespace osu.Game.Beatmaps } catch { - return new TrackVirtual(); + return null; } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 9b50aed077..1a65611a3d 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -19,7 +19,7 @@ using osu.Game.Skinning; namespace osu.Game.Beatmaps { - public abstract class WorkingBeatmap : IDisposable + public abstract partial class WorkingBeatmap : IDisposable { public readonly BeatmapInfo BeatmapInfo; @@ -145,7 +145,7 @@ namespace osu.Game.Beatmaps private Track populateTrack() { // we want to ensure that we always have a track, even if it's a fake one. - var t = GetTrack() ?? new TrackVirtual(); + var t = GetTrack() ?? new VirtualBeatmapTrack(Beatmap); applyRateAdjustments(t); return t; } diff --git a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs new file mode 100644 index 0000000000..1cadf9ee90 --- /dev/null +++ b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Framework.Audio.Track; +using osu.Game.Rulesets.Objects.Types; + +namespace osu.Game.Beatmaps +{ + public partial class WorkingBeatmap + { + private class VirtualBeatmapTrack : TrackVirtual + { + private readonly IBeatmap beatmap; + + public VirtualBeatmapTrack(IBeatmap beatmap) + { + this.beatmap = beatmap; + } + + protected override void UpdateState() + { + updateVirtualLength(); + base.UpdateState(); + } + + private void updateVirtualLength() + { + var lastObject = beatmap.HitObjects.LastOrDefault(); + + switch (lastObject) + { + case null: + Length = 1000; + break; + case IHasEndTime endTime: + Length = endTime.EndTime + 1000; + break; + default: + Length = lastObject.StartTime + 1000; + break; + } + } + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index d1fc8be005..0dc110951b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -52,8 +52,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts if (Beatmap.Value == null) return; - if (Beatmap.Value.Track.Length == double.PositiveInfinity) return; - float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); adjustableClock.Seek(markerPos / DrawWidth * Beatmap.Value.Track.Length); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 07d9398d38..5628630d0e 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -47,8 +47,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return; } - // Todo: This should be handled more gracefully - timeline.RelativeChildSize = Beatmap.Value.Track.Length == double.PositiveInfinity ? Vector2.One : new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); + timeline.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); } protected void Add(Drawable visualisation) => timeline.Add(visualisation); diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index e6a04bf1e7..d9b827ffec 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -118,18 +117,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private void seekTrackToCurrent() { - var track = Beatmap.Value.Track; - if (track is TrackVirtual || !track.IsLoaded) + if (!Beatmap.Value.TrackLoaded) return; - if (!(Beatmap.Value.Track is TrackVirtual)) - adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); } private void scrollToTrackTime() { - var track = Beatmap.Value.Track; - if (track is TrackVirtual || !track.IsLoaded) + if (!Beatmap.Value.TrackLoaded) return; ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); From b4b28f8ae805bdb520420cb9ebf49909a50aa5bc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Jun 2018 16:07:18 +0900 Subject: [PATCH 058/190] Make GetWaveform() not hard bail if errors occur --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index d086064425..43ae30f780 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -73,7 +73,18 @@ namespace osu.Game.Beatmaps } } - protected override Waveform GetWaveform() => new Waveform(store.GetStream(getPathForFile(Metadata.AudioFile))); + protected override Waveform GetWaveform() + { + try + { + var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); + return trackData == null ? null : new Waveform(trackData); + } + catch + { + return null; + } + } protected override Storyboard GetStoryboard() { From 5640385f480c6bdbca0ba1bbb0fc030c1a552c60 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Jun 2018 16:12:49 +0900 Subject: [PATCH 059/190] Update the length once during construction --- osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs index 1cadf9ee90..fb3c0027f7 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs @@ -9,6 +9,9 @@ namespace osu.Game.Beatmaps { public partial class WorkingBeatmap { + /// + /// A type of which provides a valid length based on the s of an . + /// private class VirtualBeatmapTrack : TrackVirtual { private readonly IBeatmap beatmap; @@ -16,6 +19,7 @@ namespace osu.Game.Beatmaps public VirtualBeatmapTrack(IBeatmap beatmap) { this.beatmap = beatmap; + updateVirtualLength(); } protected override void UpdateState() From 1ed6a672f20987336683f354f313400ce1f52c95 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 27 Jun 2018 18:43:29 +0900 Subject: [PATCH 060/190] Update volme control Use IMouseWheelBindingHandler for volume VolumeControlReceptor. VolumeMeter is no longer an IKeyBindingHandler because it is unused. --- osu.Game/OsuGame.cs | 3 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 2 +- .../Overlays/Volume/VolumeControlReceptor.cs | 4 +- osu.Game/Overlays/Volume/VolumeMeter.cs | 62 +++++-------------- osu.Game/Overlays/VolumeOverlay.cs | 6 +- 5 files changed, 23 insertions(+), 54 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ba8685b5b2..bc680193bc 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -247,7 +247,8 @@ namespace osu.Game new VolumeControlReceptor { RelativeSizeAxes = Axes.Both, - ActionRequested = action => volume.Adjust(action) + ActionRequested = action => volume.Adjust(action), + WheelActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise), }, mainContent = new Container { RelativeSizeAxes = Axes.Both }, overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue }, diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index a12f9dee7e..d537a68486 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -186,7 +186,7 @@ namespace osu.Game.Overlays.KeyBinding { if (bindTarget.IsHovered) { - bindTarget.UpdateKeyCombination(new KeyCombination(KeyCombination.FromInputState(state).Keys.Append(state.Mouse.ScrollDelta.Y > 0 ? InputKey.MouseWheelUp : InputKey.MouseWheelDown))); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state, state.Mouse.ScrollDelta)); finalise(); return true; } diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 572b3f0c27..bb9aadb888 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -9,11 +9,13 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Volume { - public class VolumeControlReceptor : Container, IKeyBindingHandler, IHandleGlobalInput + public class VolumeControlReceptor : Container, IMouseWheelBindingHandler, IHandleGlobalInput { public Func ActionRequested; + public Func WheelActionRequested; public bool OnPressed(GlobalAction action) => ActionRequested?.Invoke(action) ?? false; + public bool OnMouseWheel(GlobalAction action, float amount, bool isPrecise) => WheelActionRequested?.Invoke(action, amount, isPrecise) ?? false; public bool OnReleased(GlobalAction action) => false; } } diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 1d392e6ee8..9aeca1f35f 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -12,17 +12,15 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; -using osu.Framework.Input.Bindings; using osu.Framework.MathUtils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Input.Bindings; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Overlays.Volume { - public class VolumeMeter : Container, IKeyBindingHandler + public class VolumeMeter : Container { private CircularProgress volumeCircle; private CircularProgress volumeCircleGlow; @@ -226,59 +224,27 @@ namespace osu.Game.Overlays.Volume private const float adjust_step = 0.05f; - public void Increase() => adjust(1); - public void Decrease() => adjust(-1); - - private void adjust(int direction) - { - float amount = adjust_step * direction; - - // handle the case where the OnPressed action was actually a mouse wheel. - // this allows for precise wheel handling. - var state = GetContainingInputManager().CurrentState; - if (state.Mouse?.ScrollDelta.Y != 0) - { - OnScroll(state); - return; - } - - Volume += amount; - } - - public bool OnPressed(GlobalAction action) - { - if (!IsHovered) return false; - - switch (action) - { - case GlobalAction.DecreaseVolume: - Decrease(); - return true; - case GlobalAction.IncreaseVolume: - Increase(); - return true; - } - - return false; - } + public void Increase(double amount = 1, bool isPrecise = false) => adjust(amount, isPrecise); + public void Decrease(double amount = 1, bool isPrecise = false) => adjust(-amount, isPrecise); // because volume precision is set to 0.01, this local is required to keep track of more precise adjustments and only apply when possible. - private double scrollAmount; + private double adjustAccumulator; + + private void adjust(double delta, bool isPrecise) + { + adjustAccumulator += delta * adjust_step * (isPrecise ? 0.1 : 1); + if (Math.Abs(adjustAccumulator) < Bindable.Precision) + return; + Volume += adjustAccumulator; + adjustAccumulator = 0; + } protected override bool OnScroll(InputState state) { - scrollAmount += adjust_step * state.Mouse.ScrollDelta.Y * (state.Mouse.HasPreciseScroll ? 0.1f : 1); - - if (Math.Abs(scrollAmount) < Bindable.Precision) - return true; - - Volume += scrollAmount; - scrollAmount = 0; + adjust(state.Mouse.ScrollDelta.Y, state.Mouse.HasPreciseScroll); return true; } - public bool OnReleased(GlobalAction action) => false; - private const float transition_length = 500; protected override bool OnHover(InputState state) diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index 1c9c615bbb..e40597b2d4 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -93,7 +93,7 @@ namespace osu.Game.Overlays muteButton.Current.ValueChanged += _ => Show(); } - public bool Adjust(GlobalAction action) + public bool Adjust(GlobalAction action, float amount = 1, bool isPrecise = false) { if (!IsLoaded) return false; @@ -103,13 +103,13 @@ namespace osu.Game.Overlays if (State == Visibility.Hidden) Show(); else - volumeMeterMaster.Decrease(); + volumeMeterMaster.Decrease(amount, isPrecise); return true; case GlobalAction.IncreaseVolume: if (State == Visibility.Hidden) Show(); else - volumeMeterMaster.Increase(); + volumeMeterMaster.Increase(amount, isPrecise); return true; case GlobalAction.ToggleMute: Show(); From e197ebe4c52a91cd9ff58a7cdbc367172efae2c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 01:55:09 +0900 Subject: [PATCH 061/190] Fix slider heads displaying in incorrect colour --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index dfab123038..678ecd8461 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -93,6 +93,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.AccentColour = value; Body.AccentColour = AccentColour; Ball.AccentColour = AccentColour; + foreach (var drawableHitObject in NestedHitObjects) + drawableHitObject.AccentColour = AccentColour; } } From 8518fce4a9e3a636931dc0f5cfaf72e4ffa43f03 Mon Sep 17 00:00:00 2001 From: Joehu Date: Wed, 27 Jun 2018 17:57:55 -0700 Subject: [PATCH 062/190] Fix osu!supporter naming --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 4 ++-- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 50428cc5e6..e488dacf80 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -138,7 +138,7 @@ namespace osu.Game.Beatmaps PostNotification?.Invoke(new SimpleNotification { Icon = FontAwesome.fa_superpowers, - Text = "You gotta be a supporter to download for now 'yo" + Text = "You gotta be an osu!supporter to download for now 'yo" }); return; } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 046c1b1a33..fefb289d17 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -141,11 +141,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent break; case RecentActivityType.UserSupportFirst: - message = $"{userLinkTemplate()} has become an osu! supporter - thanks for your generosity!"; + message = $"{userLinkTemplate()} has become an osu!supporter - thanks for your generosity!"; break; case RecentActivityType.UserSupportGift: - message = $"{userLinkTemplate()} has received the gift of osu! supporter!"; + message = $"{userLinkTemplate()} has received the gift of osu!supporter!"; break; case RecentActivityType.UsernameChange: diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 9dae8fb273..cfb7104e16 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Select.Leaderboards replacePlaceholder(new MessagePlaceholder(@"Please sign in to view online leaderboards!")); break; case PlaceholderState.NotSupporter: - replacePlaceholder(new MessagePlaceholder(@"Please invest in a supporter tag to view this leaderboard!")); + replacePlaceholder(new MessagePlaceholder(@"Please invest in an osu!supporter tag to view this leaderboard!")); break; default: replacePlaceholder(null); From 5ad122bfec900566a9d3ec1ad5f910d5e77c3528 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 10:28:35 +0900 Subject: [PATCH 063/190] Fix beatmaps importing with -1 as online set ID --- osu.Game/Beatmaps/BeatmapSetInfo.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index ed8fbdbb26..ebebe42097 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -13,7 +13,13 @@ namespace osu.Game.Beatmaps [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } - public int? OnlineBeatmapSetID { get; set; } + private int? onlineBeatmapSetID; + + public int? OnlineBeatmapSetID + { + get { return onlineBeatmapSetID; } + set { onlineBeatmapSetID = value > 0 ? value : null; } + } public BeatmapMetadata Metadata { get; set; } From ac7ee59d50f133f8ec4b49d464b4bb0c0c63fb96 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 10:48:01 +0900 Subject: [PATCH 064/190] Add migration for previous incorrectly imported beatmaps --- ...628011956_RemoveNegativeSetIDs.Designer.cs | 376 ++++++++++++++++++ .../20180628011956_RemoveNegativeSetIDs.cs | 19 + 2 files changed, 395 insertions(+) create mode 100644 osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.Designer.cs create mode 100644 osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs diff --git a/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.Designer.cs b/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.Designer.cs new file mode 100644 index 0000000000..7eeacd56d7 --- /dev/null +++ b/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.Designer.cs @@ -0,0 +1,376 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using osu.Game.Database; + +namespace osu.Game.Migrations +{ + [DbContext(typeof(OsuDbContext))] + [Migration("20180628011956_RemoveNegativeSetIDs")] + partial class RemoveNegativeSetIDs + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.1.1-rtm-30846"); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("ApproachRate"); + + b.Property("CircleSize"); + + b.Property("DrainRate"); + + b.Property("OverallDifficulty"); + + b.Property("SliderMultiplier"); + + b.Property("SliderTickRate"); + + b.HasKey("ID"); + + b.ToTable("BeatmapDifficulty"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("AudioLeadIn"); + + b.Property("BaseDifficultyID"); + + b.Property("BeatDivisor"); + + b.Property("BeatmapSetInfoID"); + + b.Property("Countdown"); + + b.Property("DistanceSpacing"); + + b.Property("GridSize"); + + b.Property("Hash"); + + b.Property("Hidden"); + + b.Property("LetterboxInBreaks"); + + b.Property("MD5Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapID"); + + b.Property("Path"); + + b.Property("RulesetID"); + + b.Property("SpecialStyle"); + + b.Property("StackLeniency"); + + b.Property("StarDifficulty"); + + b.Property("StoredBookmarks"); + + b.Property("TimelineZoom"); + + b.Property("Version"); + + b.Property("WidescreenStoryboard"); + + b.HasKey("ID"); + + b.HasIndex("BaseDifficultyID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("Hash"); + + b.HasIndex("MD5Hash"); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapID") + .IsUnique(); + + b.HasIndex("RulesetID"); + + b.ToTable("BeatmapInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Artist"); + + b.Property("ArtistUnicode"); + + b.Property("AudioFile"); + + b.Property("AuthorString") + .HasColumnName("Author"); + + b.Property("BackgroundFile"); + + b.Property("PreviewTime"); + + b.Property("Source"); + + b.Property("Tags"); + + b.Property("Title"); + + b.Property("TitleUnicode"); + + b.HasKey("ID"); + + b.ToTable("BeatmapMetadata"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("BeatmapSetInfoID"); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.HasKey("ID"); + + b.HasIndex("BeatmapSetInfoID"); + + b.HasIndex("FileInfoID"); + + b.ToTable("BeatmapSetFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("DeletePending"); + + b.Property("Hash"); + + b.Property("MetadataID"); + + b.Property("OnlineBeatmapSetID"); + + b.Property("Protected"); + + b.HasKey("ID"); + + b.HasIndex("DeletePending"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("MetadataID"); + + b.HasIndex("OnlineBeatmapSetID") + .IsUnique(); + + b.ToTable("BeatmapSetInfo"); + }); + + modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntKey") + .HasColumnName("Key"); + + b.Property("RulesetID"); + + b.Property("StringValue") + .HasColumnName("Value"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("IntAction") + .HasColumnName("Action"); + + b.Property("KeysString") + .HasColumnName("Keys"); + + b.Property("RulesetID"); + + b.Property("Variant"); + + b.HasKey("ID"); + + b.HasIndex("IntAction"); + + b.HasIndex("RulesetID", "Variant"); + + b.ToTable("KeyBinding"); + }); + + modelBuilder.Entity("osu.Game.IO.FileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Hash"); + + b.Property("ReferenceCount"); + + b.HasKey("ID"); + + b.HasIndex("Hash") + .IsUnique(); + + b.HasIndex("ReferenceCount"); + + b.ToTable("FileInfo"); + }); + + modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Available"); + + b.Property("InstantiationInfo"); + + b.Property("Name"); + + b.Property("ShortName"); + + b.HasKey("ID"); + + b.HasIndex("Available"); + + b.HasIndex("ShortName") + .IsUnique(); + + b.ToTable("RulesetInfo"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("FileInfoID"); + + b.Property("Filename") + .IsRequired(); + + b.Property("SkinInfoID"); + + b.HasKey("ID"); + + b.HasIndex("FileInfoID"); + + b.HasIndex("SkinInfoID"); + + b.ToTable("SkinFileInfo"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b => + { + b.Property("ID") + .ValueGeneratedOnAdd(); + + b.Property("Creator"); + + b.Property("DeletePending"); + + b.Property("Name"); + + b.HasKey("ID"); + + b.ToTable("SkinInfo"); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty") + .WithMany() + .HasForeignKey("BaseDifficultyID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet") + .WithMany("Beatmaps") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("Beatmaps") + .HasForeignKey("MetadataID"); + + b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset") + .WithMany() + .HasForeignKey("RulesetID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo") + .WithMany("Files") + .HasForeignKey("BeatmapSetInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b => + { + b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata") + .WithMany("BeatmapSets") + .HasForeignKey("MetadataID"); + }); + + modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b => + { + b.HasOne("osu.Game.IO.FileInfo", "FileInfo") + .WithMany() + .HasForeignKey("FileInfoID") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("osu.Game.Skinning.SkinInfo") + .WithMany("Files") + .HasForeignKey("SkinInfoID") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs b/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs new file mode 100644 index 0000000000..c52288e598 --- /dev/null +++ b/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace osu.Game.Migrations +{ + public partial class RemoveNegativeSetIDs : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + // There was a change that baetmaps were being loaded with "-1" online IDs, which is completely incorrect. + // This ensures there will not be unique key conflicts as a result of these incorrectly imported beatmaps. + migrationBuilder.Sql("UPDATE BeatmapSetInfo SET OnlineBeatmapSetID = null WHERE OnlineBeatmapSetID < 0"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} From c0c94e24b9e5172f693b57514b6120dd3274b641 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 11:45:48 +0900 Subject: [PATCH 065/190] Use VirtualBeatmapTrack in testcases --- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- .../WorkingBeatmap_VirtualBeatmapTrack.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 19 +------------------ 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 265c6832b2..25a76b52a7 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -45,7 +45,7 @@ namespace osu.Game.Beatmaps protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4"); - protected override Track GetTrack() => new TrackVirtual(); + protected override Track GetTrack() => new TrackVirtual { Length = 1000 }; private class DummyRulesetInfo : RulesetInfo { diff --git a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs index fb3c0027f7..b3b3562dc4 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs @@ -12,7 +12,7 @@ namespace osu.Game.Beatmaps /// /// A type of which provides a valid length based on the s of an . /// - private class VirtualBeatmapTrack : TrackVirtual + protected class VirtualBeatmapTrack : TrackVirtual { private readonly IBeatmap beatmap; diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 37693c99e8..2f5c887726 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -1,12 +1,10 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Tests.Beatmaps { @@ -26,21 +24,6 @@ namespace osu.Game.Tests.Beatmaps private readonly IBeatmap beatmap; protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; - - protected override Track GetTrack() - { - var lastObject = beatmap.HitObjects.LastOrDefault(); - if (lastObject != null) - return new TestTrack(((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime) + 1000); - return new TrackVirtual(); - } - - private class TestTrack : TrackVirtual - { - public TestTrack(double length) - { - Length = length; - } - } + protected override Track GetTrack() => null; } } From 87e8074cd267f9f8676fa7f7f5ecc18ae3a56029 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 11:46:56 +0900 Subject: [PATCH 066/190] Use a const for excess length --- osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs index b3b3562dc4..4c37c0c4a0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs @@ -14,6 +14,8 @@ namespace osu.Game.Beatmaps /// protected class VirtualBeatmapTrack : TrackVirtual { + private const double excess_length = 1000; + private readonly IBeatmap beatmap; public VirtualBeatmapTrack(IBeatmap beatmap) @@ -35,13 +37,13 @@ namespace osu.Game.Beatmaps switch (lastObject) { case null: - Length = 1000; + Length = excess_length; break; case IHasEndTime endTime: - Length = endTime.EndTime + 1000; + Length = endTime.EndTime + excess_length; break; default: - Length = lastObject.StartTime + 1000; + Length = lastObject.StartTime + excess_length; break; } } From 2f2bd59844e65fa6a57ab05d81dc39907a3aeb23 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 11:47:41 +0900 Subject: [PATCH 067/190] Remove editor functionality from VirtualBeatmapTrack /shrug --- .../Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs index 4c37c0c4a0..0e0a9a3bb9 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap_VirtualBeatmapTrack.cs @@ -16,21 +16,7 @@ namespace osu.Game.Beatmaps { private const double excess_length = 1000; - private readonly IBeatmap beatmap; - public VirtualBeatmapTrack(IBeatmap beatmap) - { - this.beatmap = beatmap; - updateVirtualLength(); - } - - protected override void UpdateState() - { - updateVirtualLength(); - base.UpdateState(); - } - - private void updateVirtualLength() { var lastObject = beatmap.HitObjects.LastOrDefault(); From 01b90aaffe7affde478e989d15c0542d0fec06a7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 11:58:06 +0900 Subject: [PATCH 068/190] Fix CI not passing --- osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index d9b827ffec..28239533c8 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private void seekTrackToCurrent() { - if (!Beatmap.Value.TrackLoaded) + if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.Track.IsLoaded) return; adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); @@ -125,7 +125,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private void scrollToTrackTime() { - if (!Beatmap.Value.TrackLoaded) + if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.Track.IsLoaded) return; ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); From c44a81bdf569be9b793c6f649a6c90b4aac6509a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 13:04:39 +0900 Subject: [PATCH 069/190] Add word wrap support --- osu.Game.Tests/Visual/TestCaseLeaderboard.cs | 8 +++++ .../Containers/OsuTextFlowContainer.cs | 3 ++ .../Select/Leaderboards/Leaderboard.cs | 19 ------------ .../Select/Leaderboards/LeaderboardScope.cs | 10 ++++++ .../Select/Leaderboards/MessagePlaceholder.cs | 24 ++++---------- .../Select/Leaderboards/Placeholder.cs | 15 +++++++-- .../Select/Leaderboards/PlaceholderState.cs | 13 ++++++++ .../RetrievalFailurePlaceholder.cs | 31 ++++++------------- 8 files changed, 62 insertions(+), 61 deletions(-) create mode 100644 osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs create mode 100644 osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs diff --git a/osu.Game.Tests/Visual/TestCaseLeaderboard.cs b/osu.Game.Tests/Visual/TestCaseLeaderboard.cs index 7f5bce3b84..e8ac19e7fc 100644 --- a/osu.Game.Tests/Visual/TestCaseLeaderboard.cs +++ b/osu.Game.Tests/Visual/TestCaseLeaderboard.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using System.ComponentModel; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; @@ -17,6 +19,12 @@ namespace osu.Game.Tests.Visual [Description("PlaySongSelect leaderboard")] public class TestCaseLeaderboard : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] { + typeof(Placeholder), + typeof(MessagePlaceholder), + typeof(RetrievalFailurePlaceholder), + }; + private RulesetStore rulesets; private readonly FailableLeaderboard leaderboard; diff --git a/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs b/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs index 119af4d762..e77e075fe2 100644 --- a/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Sprites; @@ -16,6 +17,8 @@ namespace osu.Game.Graphics.Containers protected override SpriteText CreateSpriteText() => new OsuSpriteText(); + public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable); + public void AddIcon(FontAwesome icon, Action creationParameters = null) => AddText(((char)icon).ToString(), creationParameters); } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index cfb7104e16..9eca3802ae 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -331,23 +331,4 @@ namespace osu.Game.Screens.Select.Leaderboards } } } - - public enum LeaderboardScope - { - Local, - Country, - Global, - Friend, - } - - public enum PlaceholderState - { - Successful, - Retrieving, - NetworkFailure, - Unavailable, - NoScores, - NotLoggedIn, - NotSupporter, - } } diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs new file mode 100644 index 0000000000..4280f85473 --- /dev/null +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs @@ -0,0 +1,10 @@ +namespace osu.Game.Screens.Select.Leaderboards +{ + public enum LeaderboardScope + { + Local, + Country, + Global, + Friend, + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs b/osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs index ac2ac818d8..f01a55b662 100644 --- a/osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs +++ b/osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs @@ -2,10 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using OpenTK; namespace osu.Game.Screens.Select.Leaderboards { @@ -15,22 +12,13 @@ namespace osu.Game.Screens.Select.Leaderboards public MessagePlaceholder(string message) { - Direction = FillDirection.Horizontal; - AutoSizeAxes = Axes.Both; - Children = new Drawable[] + AddIcon(FontAwesome.fa_exclamation_circle, cp => { - new SpriteIcon - { - Icon = FontAwesome.fa_exclamation_circle, - Size = new Vector2(26), - Margin = new MarginPadding { Right = 10 }, - }, - new OsuSpriteText - { - Text = this.message = message, - TextSize = 22, - }, - }; + cp.TextSize = TEXT_SIZE; + cp.Padding = new MarginPadding { Right = 10 }; + }); + + AddText(this.message = message); } public override bool Equals(Placeholder other) => (other as MessagePlaceholder)?.message == message; diff --git a/osu.Game/Screens/Select/Leaderboards/Placeholder.cs b/osu.Game/Screens/Select/Leaderboards/Placeholder.cs index c56d279e6c..307986a299 100644 --- a/osu.Game/Screens/Select/Leaderboards/Placeholder.cs +++ b/osu.Game/Screens/Select/Leaderboards/Placeholder.cs @@ -3,16 +3,27 @@ using System; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Select.Leaderboards { - public abstract class Placeholder : FillFlowContainer, IEquatable + public abstract class Placeholder : OsuTextFlowContainer, IEquatable { + protected const float TEXT_SIZE = 22; + + public override bool HandleMouseInput => true; + protected Placeholder() + : base(cp => cp.TextSize = TEXT_SIZE) { Anchor = Anchor.Centre; Origin = Anchor.Centre; + TextAnchor = Anchor.TopCentre; + + Padding = new MarginPadding(20); + + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; } public virtual bool Equals(Placeholder other) => GetType() == other?.GetType(); diff --git a/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs b/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs new file mode 100644 index 0000000000..e98e094a96 --- /dev/null +++ b/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs @@ -0,0 +1,13 @@ +namespace osu.Game.Screens.Select.Leaderboards +{ + public enum PlaceholderState + { + Successful, + Retrieving, + NetworkFailure, + Unavailable, + NoScores, + NotLoggedIn, + NotSupporter, + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs b/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs index 174fbac120..99b0c53835 100644 --- a/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs +++ b/osu.Game/Screens/Select/Leaderboards/RetrievalFailurePlaceholder.cs @@ -3,11 +3,9 @@ using System; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using OpenTK; namespace osu.Game.Screens.Select.Leaderboards @@ -18,22 +16,13 @@ namespace osu.Game.Screens.Select.Leaderboards public RetrievalFailurePlaceholder() { - Direction = FillDirection.Horizontal; - AutoSizeAxes = Axes.Both; - Children = new Drawable[] + AddArbitraryDrawable(new RetryButton { - new RetryButton - { - Action = () => OnRetry?.Invoke(), - Margin = new MarginPadding { Right = 10 }, - }, - new OsuSpriteText - { - Anchor = Anchor.TopLeft, - Text = @"Couldn't retrieve scores!", - TextSize = 22, - }, - }; + Action = () => OnRetry?.Invoke(), + Padding = new MarginPadding { Right = 10 } + }); + + AddText(@"Couldn't retrieve scores!"); } public class RetryButton : OsuHoverContainer @@ -44,18 +33,16 @@ namespace osu.Game.Screens.Select.Leaderboards public RetryButton() { - Height = 26; - Width = 26; + AutoSizeAxes = Axes.Both; + Child = new OsuClickableContainer { AutoSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, Action = () => Action?.Invoke(), Child = icon = new SpriteIcon { Icon = FontAwesome.fa_refresh, - Size = new Vector2(26), + Size = new Vector2(TEXT_SIZE), Shadow = true, }, }; From 3b0c4ff16b39a93b8dbe842aca781178ded7dbb9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 14:08:15 +0900 Subject: [PATCH 070/190] Tidy code --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 28239533c8..8cb0fdd908 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -51,13 +52,11 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); Beatmap.BindTo(beatmap); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - Beatmap.BindValueChanged(b => waveform.Waveform = b.Waveform); - waveform.Waveform = Beatmap.Value.Waveform; + Beatmap.BindValueChanged(b => + { + waveform.Waveform = b.Waveform; + track = b.Track; + }, true); } /// @@ -80,6 +79,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline /// private bool trackWasPlaying; + private Track track; + protected override void Update() { base.Update(); @@ -117,18 +118,18 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private void seekTrackToCurrent() { - if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.Track.IsLoaded) + if (!track.IsLoaded) return; - adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + adjustableClock.Seek(Current / Content.DrawWidth * track.Length); } private void scrollToTrackTime() { - if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.Track.IsLoaded) + if (!track.IsLoaded) return; - ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + ScrollTo((float)(adjustableClock.CurrentTime / track.Length) * Content.DrawWidth, false); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From b1a3f012125a57be44cf3cd3ae2e096a6cab8458 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 16:36:42 +0900 Subject: [PATCH 071/190] Fix mania maps not being treated as mania maps in release builds --- osu.Game/Rulesets/RulesetStore.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 8d267f48e9..a7a9fea5f2 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -84,10 +84,11 @@ namespace osu.Game.Rulesets { try { - var instance = r.CreateInstance(); + var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo), (RulesetInfo)null)).RulesetInfo; - r.Name = instance.Description; - r.ShortName = instance.ShortName; + r.Name = instanceInfo.Name; + r.ShortName = instanceInfo.ShortName; + r.InstantiationInfo = instanceInfo.InstantiationInfo; r.Available = true; } From a377e87bf61c2b4fe33ee715db7fa489c9674ceb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 17:34:04 +0900 Subject: [PATCH 072/190] Add missing licence headers --- osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs | 7 +++++-- osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs index 4280f85473..761f53a5e8 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScope.cs @@ -1,4 +1,7 @@ -namespace osu.Game.Screens.Select.Leaderboards +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Screens.Select.Leaderboards { public enum LeaderboardScope { @@ -7,4 +10,4 @@ Global, Friend, } -} \ No newline at end of file +} diff --git a/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs b/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs index e98e094a96..33a56540f3 100644 --- a/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs +++ b/osu.Game/Screens/Select/Leaderboards/PlaceholderState.cs @@ -1,4 +1,7 @@ -namespace osu.Game.Screens.Select.Leaderboards +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Screens.Select.Leaderboards { public enum PlaceholderState { @@ -10,4 +13,4 @@ NotLoggedIn, NotSupporter, } -} \ No newline at end of file +} From 2882981f9c2494a84ddf8f055f860434437d0608 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 18:08:46 +0900 Subject: [PATCH 073/190] Implement and use equality comparers for ControlPoint --- .../Beatmaps/ControlPoints/ControlPoint.cs | 8 +- .../ControlPoints/DifficultyControlPoint.cs | 5 ++ .../ControlPoints/EffectControlPoint.cs | 6 ++ .../ControlPoints/SampleControlPoint.cs | 6 ++ .../ControlPoints/TimingControlPoint.cs | 6 ++ .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 81 ++++++++++++------- 6 files changed, 82 insertions(+), 30 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs index db9e712d86..e1e5affc78 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs @@ -14,6 +14,12 @@ namespace osu.Game.Beatmaps.ControlPoints public int CompareTo(ControlPoint other) => Time.CompareTo(other.Time); - public bool Equals(ControlPoint other) => Time.Equals(other?.Time); + public virtual bool Equals(ControlPoint other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return Time.Equals(other.Time); + } } } diff --git a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs index 9f717d21e3..9c6735a36a 100644 --- a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs @@ -17,5 +17,10 @@ namespace osu.Game.Beatmaps.ControlPoints } private double speedMultiplier = 1; + + public override bool Equals(ControlPoint other) + => base.Equals(other) + && other is DifficultyControlPoint difficulty + && SpeedMultiplier == difficulty.SpeedMultiplier; } } diff --git a/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs index 73d5232f44..6fdddc44bb 100644 --- a/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs @@ -14,5 +14,11 @@ namespace osu.Game.Beatmaps.ControlPoints /// Whether the first bar line of this control point is ignored. /// public bool OmitFirstBarLine; + + public override bool Equals(ControlPoint other) + => base.Equals(other) + && other is EffectControlPoint effect + && KiaiMode == effect.KiaiMode + && OmitFirstBarLine == effect.OmitFirstBarLine; } } diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 5d801a1163..69c00e463c 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -30,5 +30,11 @@ namespace osu.Game.Beatmaps.ControlPoints Name = sampleName, Volume = SampleVolume, }; + + public override bool Equals(ControlPoint other) + => base.Equals(other) + && other is SampleControlPoint sample + && SampleBank == sample.SampleBank + && SampleVolume == sample.SampleVolume; } } diff --git a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs index d20b1b87a6..cc1546675b 100644 --- a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs @@ -23,5 +23,11 @@ namespace osu.Game.Beatmaps.ControlPoints } private double beatLength = 1000; + + public override bool Equals(ControlPoint other) + => base.Equals(other) + && other is TimingControlPoint timing + && TimeSignature == timing.TimeSignature + && BeatLength == timing.beatLength; } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 581207607a..603de5949e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -314,13 +314,9 @@ namespace osu.Game.Beatmaps.Formats if (stringSampleSet == @"none") stringSampleSet = @"normal"; - DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(time); - SampleControlPoint samplePoint = beatmap.ControlPointInfo.SamplePointAt(time); - EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(time); - if (timingChange) { - beatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint + handleTimingControlPoint(new TimingControlPoint { Time = time, BeatLength = beatLength, @@ -328,41 +324,68 @@ namespace osu.Game.Beatmaps.Formats }); } - if (speedMultiplier != difficultyPoint.SpeedMultiplier) + handleDifficultyControlPoint(new DifficultyControlPoint { - beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == time); - beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint - { - Time = time, - SpeedMultiplier = speedMultiplier - }); - } + Time = time, + SpeedMultiplier = speedMultiplier + }); - if (stringSampleSet != samplePoint.SampleBank || sampleVolume != samplePoint.SampleVolume) + handleEffectControlPoint(new EffectControlPoint { - beatmap.ControlPointInfo.SamplePoints.Add(new SampleControlPoint - { - Time = time, - SampleBank = stringSampleSet, - SampleVolume = sampleVolume - }); - } + Time = time, + KiaiMode = kiaiMode, + OmitFirstBarLine = omitFirstBarSignature + }); - if (kiaiMode != effectPoint.KiaiMode || omitFirstBarSignature != effectPoint.OmitFirstBarLine) + handleSampleControlPoint(new LegacySampleControlPoint { - beatmap.ControlPointInfo.EffectPoints.Add(new EffectControlPoint - { - Time = time, - KiaiMode = kiaiMode, - OmitFirstBarLine = omitFirstBarSignature - }); - } + Time = time, + SampleBank = stringSampleSet, + SampleVolume = sampleVolume, + CustomSampleBank = customSampleBank + }); } catch (FormatException e) { } } + private void handleTimingControlPoint(TimingControlPoint newPoint) + { + beatmap.ControlPointInfo.TimingPoints.Add(newPoint); + } + + private void handleDifficultyControlPoint(DifficultyControlPoint newPoint) + { + var existing = beatmap.ControlPointInfo.DifficultyPointAt(newPoint.Time); + + if (newPoint.Equals(existing)) + return; + + beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == newPoint.Time); + beatmap.ControlPointInfo.DifficultyPoints.Add(newPoint); + } + + private void handleEffectControlPoint(EffectControlPoint newPoint) + { + var existing = beatmap.ControlPointInfo.EffectPointAt(newPoint.Time); + + if (newPoint.Equals(existing)) + return; + + beatmap.ControlPointInfo.EffectPoints.Add(newPoint); + } + + private void handleSampleControlPoint(SampleControlPoint newPoint) + { + var existing = beatmap.ControlPointInfo.SamplePointAt(newPoint.Time); + + if (newPoint.Equals(existing)) + return; + + beatmap.ControlPointInfo.SamplePoints.Add(newPoint); + } + private void handleHitObject(string line) { // If the ruleset wasn't specified, assume the osu!standard ruleset. From 781095b96bd781bc930ed65a571cadc42467fc64 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 18:20:29 +0900 Subject: [PATCH 074/190] Encapsulate the method to apply SampleControlPoints to SampleInfos --- .../Beatmaps/ControlPoints/SampleControlPoint.cs | 12 ++++++++++++ .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 13 ++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 69c00e463c..ae65e7ea42 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -31,6 +31,18 @@ namespace osu.Game.Beatmaps.ControlPoints Volume = SampleVolume, }; + /// + /// Applies and to a if necessary, returning the modified . + /// + /// The . This will not be modified. + /// The modified . This does not share a reference with . + public virtual SampleInfo ApplyTo(SampleInfo sampleInfo) => new SampleInfo + { + Bank = sampleInfo.Bank ?? SampleBank, + Name = sampleInfo.Name, + Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume + }; + public override bool Equals(ControlPoint other) => base.Equals(other) && other is SampleControlPoint sample diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 88990d435c..4892e20814 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -90,13 +90,12 @@ namespace osu.Game.Rulesets.Objects.Drawables if (HitObject.SampleControlPoint == null) throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - AddInternal(Samples = new SkinnableSound(samples.Select(s => new SampleInfo - { - Bank = s.Bank ?? HitObject.SampleControlPoint.SampleBank, - Name = s.Name, - Volume = s.Volume > 0 ? s.Volume : HitObject.SampleControlPoint.SampleVolume, - Namespace = SampleNamespace - }).ToArray())); + + samples = samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).ToArray(); + foreach (var s in samples) + s.Namespace = SampleNamespace; + + AddInternal(Samples = new SkinnableSound(samples)); } } From 3a9a82c80c5c2d6a2843fa5cb64432d2d0ce455b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 18:20:43 +0900 Subject: [PATCH 075/190] Add back legacy custom sample banks --- .../Formats/LegacyBeatmapDecoderTest.cs | 17 ++++++++++++++ osu.Game.Tests/Resources/custom-samples.osu | 16 ++++++++++++++ .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 ++--- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 22 +++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Tests/Resources/custom-samples.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 1628423fe8..a77730c453 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -8,6 +8,7 @@ using OpenTK.Graphics; using osu.Game.Tests.Resources; using System.Linq; using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Timing; @@ -211,5 +212,21 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)); } } + + [Test] + public void TestDecodeCustomSamples() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + using (var resStream = Resource.OpenResource("custom-samples.osu")) + using (var stream = new StreamReader(resStream)) + { + var hitObjects = decoder.Decode(stream).HitObjects; + + Assert.AreEqual(0, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[0].SampleControlPoint).CustomSampleBank); + Assert.AreEqual(1, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[1].SampleControlPoint).CustomSampleBank); + Assert.AreEqual(2, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[2].SampleControlPoint).CustomSampleBank); + Assert.AreEqual(0, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[3].SampleControlPoint).CustomSampleBank); + } + } } } diff --git a/osu.Game.Tests/Resources/custom-samples.osu b/osu.Game.Tests/Resources/custom-samples.osu new file mode 100644 index 0000000000..1e0e6f558e --- /dev/null +++ b/osu.Game.Tests/Resources/custom-samples.osu @@ -0,0 +1,16 @@ +osu file format v14 + +[General] +SampleSet: Normal + +[TimingPoints] +2170,468.75,4,1,0,40,1,0 +2638,-100,4,1,1,40,0,0 +3107,-100,4,1,2,40,0,0 +3576,-100,4,1,0,40,0,0 + +[HitObjects] +255,193,2170,1,0,0:0:0:0: +256,191,2638,5,0,0:0:0:0: +255,193,3107,1,0,0:0:0:0: +256,191,3576,1,0,0:0:0:0: diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 603de5949e..f33e963f08 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -289,9 +289,9 @@ namespace osu.Game.Beatmaps.Formats if (split.Length >= 4) sampleSet = (LegacySampleBank)int.Parse(split[3]); - //SampleBank sampleBank = SampleBank.Default; - //if (split.Length >= 5) - // sampleBank = (SampleBank)int.Parse(split[4]); + int customSampleBank = 0; + if (split.Length >= 5) + customSampleBank = int.Parse(split[4]); int sampleVolume = defaultSampleVolume; if (split.Length >= 6) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index e77efd8508..c207761866 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; using System.IO; using osu.Framework.Logging; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; using OpenTK.Graphics; namespace osu.Game.Beatmaps.Formats @@ -167,5 +169,25 @@ namespace osu.Game.Beatmaps.Formats Pass = 2, Foreground = 3 } + + internal class LegacySampleControlPoint : SampleControlPoint + { + public int CustomSampleBank; + + public override SampleInfo ApplyTo(SampleInfo sampleInfo) + { + var baseInfo = base.ApplyTo(sampleInfo); + + if (CustomSampleBank > 0) + baseInfo.Name += CustomSampleBank; + + return baseInfo; + } + + public override bool Equals(ControlPoint other) + => base.Equals(other) + && other is LegacySampleControlPoint legacy + && CustomSampleBank == legacy.CustomSampleBank; + } } } From 94f1b2eeb867d2ff457b66a6a4b26f1ca8a8ff72 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 18:27:33 +0900 Subject: [PATCH 076/190] Only custom sample banks > 1 modify the filename --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 11 +++++++---- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index a77730c453..4be6eeef0d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Objects; using osu.Game.Skinning; namespace osu.Game.Tests.Beatmaps.Formats @@ -222,11 +223,13 @@ namespace osu.Game.Tests.Beatmaps.Formats { var hitObjects = decoder.Decode(stream).HitObjects; - Assert.AreEqual(0, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[0].SampleControlPoint).CustomSampleBank); - Assert.AreEqual(1, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[1].SampleControlPoint).CustomSampleBank); - Assert.AreEqual(2, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[2].SampleControlPoint).CustomSampleBank); - Assert.AreEqual(0, ((LegacyDecoder.LegacySampleControlPoint)hitObjects[3].SampleControlPoint).CustomSampleBank); + Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[0]).Name); + Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[1]).Name); + Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name); + Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[3]).Name); } + + SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" }); } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index c207761866..60fff4bd7f 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -178,7 +178,7 @@ namespace osu.Game.Beatmaps.Formats { var baseInfo = base.ApplyTo(sampleInfo); - if (CustomSampleBank > 0) + if (CustomSampleBank > 1) baseInfo.Name += CustomSampleBank; return baseInfo; From 9fd9af22f0f2a2370177fe93568340a0d7e1fd49 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 28 Jun 2018 18:40:12 +0900 Subject: [PATCH 077/190] Remove unused using --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 4be6eeef0d..d3c61960bb 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -8,7 +8,6 @@ using OpenTK.Graphics; using osu.Game.Tests.Resources; using System.Linq; using osu.Game.Audio; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Timing; From 0ef5b8f464697d6bed9648acbeab67b2f3f0c4b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 19:19:00 +0900 Subject: [PATCH 078/190] Tidy up code, remove unnecessary string.Formats --- osu.Game/Graphics/DrawableDate.cs | 10 +++++----- osu.Game/Graphics/DrawableJoinDate.cs | 12 ++++-------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index b725f46e76..cf0a0fee37 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -12,14 +12,14 @@ namespace osu.Game.Graphics { public class DrawableDate : OsuSpriteText, IHasTooltip { - private readonly DateTimeOffset date; + protected readonly DateTimeOffset Date; public DrawableDate(DateTimeOffset date) { AutoSizeAxes = Axes.Both; Font = "Exo2.0-RegularItalic"; - this.date = date.ToLocalTime(); + this.Date = date.ToLocalTime(); } [BackgroundDependencyLoader] @@ -38,7 +38,7 @@ namespace osu.Game.Graphics { updateTime(); - var diffToNow = DateTimeOffset.Now.Subtract(date); + var diffToNow = DateTimeOffset.Now.Subtract(Date); double timeUntilNextUpdate = 1000; if (diffToNow.TotalSeconds > 60) @@ -58,10 +58,10 @@ namespace osu.Game.Graphics public override bool HandleMouseInput => true; - protected virtual string Format() => date.Humanize(); + protected virtual string Format() => Date.Humanize(); private void updateTime() => Text = Format(); - public virtual string TooltipText => string.Format($"{date:MMMM d, yyyy h:mm tt \"UTC\"z}"); + public virtual string TooltipText => string.Format($"{Date:MMMM d, yyyy h:mm tt \"UTC\"z}"); } } diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Graphics/DrawableJoinDate.cs index 763aea60ba..a0d28406d3 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Graphics/DrawableJoinDate.cs @@ -7,17 +7,13 @@ namespace osu.Game.Graphics { public class DrawableJoinDate : DrawableDate { - private readonly DateTimeOffset date; - - public DrawableJoinDate(DateTimeOffset date) : base(date) + public DrawableJoinDate(DateTimeOffset date) + : base(date) { - this.date = date; } - protected override string Format() => Text = date.ToUniversalTime().Year < 2008 ? - "Here since the beginning" : - string.Format($"{date:MMMM yyyy}"); + protected override string Format() => Text = Date.ToUniversalTime().Year < 2008 ? "Here since the beginning" : $"{Date:MMMM yyyy}"; - public override string TooltipText => string.Format($"{date:MMMM d, yyyy}"); + public override string TooltipText => $"{Date:MMMM d, yyyy}"; } } From 8ba2ac922f42d95b98d60b28cd5454eda674558d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 19:23:56 +0900 Subject: [PATCH 079/190] Move to local components namespace --- osu.Game/Graphics/DrawableDate.cs | 2 +- .../Profile/Components}/DrawableJoinDate.cs | 3 +- .../Overlays/Profile/Components/GradeBadge.cs | 50 +++++++++++++++++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 39 +-------------- 4 files changed, 54 insertions(+), 40 deletions(-) rename osu.Game/{Graphics => Overlays/Profile/Components}/DrawableJoinDate.cs (88%) create mode 100644 osu.Game/Overlays/Profile/Components/GradeBadge.cs diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index cf0a0fee37..406fc2ffd2 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -19,7 +19,7 @@ namespace osu.Game.Graphics AutoSizeAxes = Axes.Both; Font = "Exo2.0-RegularItalic"; - this.Date = date.ToLocalTime(); + Date = date.ToLocalTime(); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/DrawableJoinDate.cs b/osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs similarity index 88% rename from osu.Game/Graphics/DrawableJoinDate.cs rename to osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs index a0d28406d3..11ee329f33 100644 --- a/osu.Game/Graphics/DrawableJoinDate.cs +++ b/osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs @@ -2,8 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Game.Graphics; -namespace osu.Game.Graphics +namespace osu.Game.Overlays.Profile.Components { public class DrawableJoinDate : DrawableDate { diff --git a/osu.Game/Overlays/Profile/Components/GradeBadge.cs b/osu.Game/Overlays/Profile/Components/GradeBadge.cs new file mode 100644 index 0000000000..14a47e8d03 --- /dev/null +++ b/osu.Game/Overlays/Profile/Components/GradeBadge.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.Profile.Components +{ + public class GradeBadge : Container + { + private const float width = 50; + private readonly string grade; + private readonly Sprite badge; + private readonly SpriteText numberText; + + public int DisplayCount + { + set => numberText.Text = value.ToString(@"#,0"); + } + + public GradeBadge(string grade) + { + this.grade = grade; + Width = width; + Height = 41; + Add(badge = new Sprite + { + Width = width, + Height = 26 + }); + Add(numberText = new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + TextSize = 14, + Font = @"Exo2.0-Bold" + }); + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + badge.Texture = textures.Get($"Grades/{grade}"); + } + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 47763d4773..c72ff6131b 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Profile.Components; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; @@ -470,43 +471,5 @@ namespace osu.Game.Overlays.Profile infoTextRight.NewLine(); } - - private class GradeBadge : Container - { - private const float width = 50; - private readonly string grade; - private readonly Sprite badge; - private readonly SpriteText numberText; - - public int DisplayCount - { - set { numberText.Text = value.ToString(@"#,0"); } - } - - public GradeBadge(string grade) - { - this.grade = grade; - Width = width; - Height = 41; - Add(badge = new Sprite - { - Width = width, - Height = 26 - }); - Add(numberText = new OsuSpriteText - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - TextSize = 14, - Font = @"Exo2.0-Bold" - }); - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - badge.Texture = textures.Get($"Grades/{grade}"); - } - } } } From 0a945e47092f9b48517ee35a4f4c0cd16b7705bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 22:44:40 +0900 Subject: [PATCH 080/190] Check whether initialised first --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 678ecd8461..c8544d9cc1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -93,8 +93,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.AccentColour = value; Body.AccentColour = AccentColour; Ball.AccentColour = AccentColour; - foreach (var drawableHitObject in NestedHitObjects) - drawableHitObject.AccentColour = AccentColour; + if (HasNestedHitObjects) + foreach (var drawableHitObject in NestedHitObjects) + drawableHitObject.AccentColour = AccentColour; } } From 9d4bc7b63009460d8acde052781cf5a5a017c2f5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 01:34:47 +0900 Subject: [PATCH 081/190] Fix combo index being wrong --- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 4 +-- osu.Game.Rulesets.Osu/Objects/Slider.cs | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 54126b934f..befbc01f3c 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -54,9 +54,9 @@ namespace osu.Game.Rulesets.Osu.Objects public virtual bool NewCombo { get; set; } - public int IndexInCurrentCombo { get; set; } + public virtual int IndexInCurrentCombo { get; set; } - public int ComboIndex { get; set; } + public virtual int ComboIndex { get; set; } public bool LastInCombo { get; set; } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 2ebe5efd0f..698f9de787 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -26,6 +26,28 @@ namespace osu.Game.Rulesets.Osu.Objects public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t); public override Vector2 EndPosition => Position + this.CurvePositionAt(1); + public override int ComboIndex + { + get => base.ComboIndex; + set + { + base.ComboIndex = value; + foreach (var n in NestedHitObjects.OfType()) + n.ComboIndex = value; + } + } + + public override int IndexInCurrentCombo + { + get => base.IndexInCurrentCombo; + set + { + base.IndexInCurrentCombo = value; + foreach (var n in NestedHitObjects.OfType()) + n.IndexInCurrentCombo = value; + } + } + public SliderCurve Curve { get; } = new SliderCurve(); public List ControlPoints @@ -147,7 +169,8 @@ namespace osu.Game.Rulesets.Osu.Objects var distanceProgress = d / length; var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; - var firstSample = Samples.FirstOrDefault(s => s.Name == SampleInfo.HIT_NORMAL) ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933) + var firstSample = Samples.FirstOrDefault(s => s.Name == SampleInfo.HIT_NORMAL) + ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933) var sampleList = new List(); if (firstSample != null) From b0739023ce3353b3443997a5376be5d99911df27 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Thu, 28 Jun 2018 19:02:38 +0200 Subject: [PATCH 082/190] Add BeatmapInfo's stable defaults to fix compatibility with old maps --- osu.Game/Beatmaps/BeatmapInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3afc3c4d32..303a19aab3 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -66,8 +66,8 @@ namespace osu.Game.Beatmaps // General public int AudioLeadIn { get; set; } - public bool Countdown { get; set; } - public float StackLeniency { get; set; } + public bool Countdown { get; set; } = true; + public float StackLeniency { get; set; } = 0.7f; public bool SpecialStyle { get; set; } public int RulesetID { get; set; } From 8742f41b7d492fba91c3425bca6d31803ff2bf80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 11:34:33 +0900 Subject: [PATCH 083/190] Revert SharpCompress library to fix delta patching regression --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9668d40fd5..b4fccf0898 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -19,7 +19,7 @@ - + From 70a119dde7ee2a7b07c01fad9b10ac7bb091fe49 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 12:20:53 +0900 Subject: [PATCH 084/190] Remove unused/duplicate interface --- .../Rulesets/Objects/Types/IHasComboIndex.cs | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 osu.Game/Rulesets/Objects/Types/IHasComboIndex.cs diff --git a/osu.Game/Rulesets/Objects/Types/IHasComboIndex.cs b/osu.Game/Rulesets/Objects/Types/IHasComboIndex.cs deleted file mode 100644 index c5d0152ae7..0000000000 --- a/osu.Game/Rulesets/Objects/Types/IHasComboIndex.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Rulesets.Objects.Types -{ - /// - /// A HitObject that is part of a combo and has extended information about its position relative to other combo objects. - /// - public interface IHasComboIndex : IHasCombo - { - /// - /// The offset of this hitobject in the current combo. - /// - int IndexInCurrentCombo { get; set; } - - /// - /// The offset of this hitobject in the current combo. - /// - int ComboIndex { get; set; } - - /// - /// Whether this is the last object in the current combo. - /// - bool LastInCombo { get; set; } - } -} From 756cabd5d01a433413032bd5e500eec6c1aad4ba Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 12:45:48 +0900 Subject: [PATCH 085/190] Add a preprocess method to BeatmapProcessor --- .../Beatmaps/CatchBeatmapProcessor.cs | 79 ++++++++++--------- .../Beatmaps/OsuBeatmapProcessor.cs | 4 +- osu.Game/Beatmaps/BeatmapProcessor.cs | 32 +++++--- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +- 4 files changed, 73 insertions(+), 49 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 8473f5a36c..02395331dc 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -15,19 +15,26 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { public class CatchBeatmapProcessor : BeatmapProcessor { + public const int RNG_SEED = 1337; + public CatchBeatmapProcessor(IBeatmap beatmap) : base(beatmap) { } - public override void PostProcess() + public override void PreProcess() { - applyPositionOffsets(); + base.PreProcess(); initialiseHyperDash((List)Beatmap.HitObjects); + } + public override void PostProcess() + { base.PostProcess(); + applyPositionOffsets(); + int index = 0; foreach (var obj in Beatmap.HitObjects.OfType()) { @@ -37,41 +44,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } - public const int RNG_SEED = 1337; - - private void applyPositionOffsets() - { - var rng = new FastRandom(RNG_SEED); - // todo: HardRock displacement should be applied here - - foreach (var obj in Beatmap.HitObjects) - { - switch (obj) - { - case BananaShower bananaShower: - foreach (var nested in bananaShower.NestedHitObjects) - { - ((BananaShower.Banana)nested).X = (float)rng.NextDouble(); - rng.Next(); // osu!stable retrieved a random banana type - rng.Next(); // osu!stable retrieved a random banana rotation - rng.Next(); // osu!stable retrieved a random banana colour - } - break; - case JuiceStream juiceStream: - foreach (var nested in juiceStream.NestedHitObjects) - { - var hitObject = (CatchHitObject)nested; - if (hitObject is TinyDroplet) - hitObject.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; - else if (hitObject is Droplet) - rng.Next(); // osu!stable retrieved a random droplet rotation - hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1); - } - break; - } - } - } - private void initialiseHyperDash(List objects) { // todo: add difficulty adjust. @@ -115,5 +87,38 @@ namespace osu.Game.Rulesets.Catch.Beatmaps lastDirection = thisDirection; } } + + private void applyPositionOffsets() + { + var rng = new FastRandom(RNG_SEED); + // todo: HardRock displacement should be applied here + + foreach (var obj in Beatmap.HitObjects) + { + switch (obj) + { + case BananaShower bananaShower: + foreach (var nested in bananaShower.NestedHitObjects) + { + ((BananaShower.Banana)nested).X = (float)rng.NextDouble(); + rng.Next(); // osu!stable retrieved a random banana type + rng.Next(); // osu!stable retrieved a random banana rotation + rng.Next(); // osu!stable retrieved a random banana colour + } + break; + case JuiceStream juiceStream: + foreach (var nested in juiceStream.NestedHitObjects) + { + var hitObject = (CatchHitObject)nested; + if (hitObject is TinyDroplet) + hitObject.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; + else if (hitObject is Droplet) + rng.Next(); // osu!stable retrieved a random droplet rotation + hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1); + } + break; + } + } + } } } diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index c7c9f4a01a..6cea5df078 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -15,10 +15,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { } - public override void PostProcess() + public override void PreProcess() { + base.PreProcess(); applyStacking((Beatmap)Beatmap); - base.PostProcess(); } private void applyStacking(Beatmap beatmap) diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index bf1cd7d4ee..1fc22197fe 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -11,11 +11,27 @@ namespace osu.Game.Beatmaps IBeatmap Beatmap { get; } /// - /// Post-processes to add mode-specific components that aren't added during conversion. + /// Processes the converted prior to being invoked. /// - /// An example of such a usage is for combo colours. + /// Nested s generated during will not be present by this point, + /// and no mods will have been applied to the s. /// /// + /// + /// This can only be used to add alterations to s generated directly through the conversion process. + /// + void PreProcess(); + + /// + /// Processes the converted after has been invoked. + /// + /// Nested s generated during will be present by this point, + /// and mods will have been applied to all s. + /// + /// + /// + /// This should be used to add alterations to s while they are in their most playable state. + /// void PostProcess(); } @@ -32,13 +48,7 @@ namespace osu.Game.Beatmaps Beatmap = beatmap; } - /// - /// Post-processes a Beatmap to add mode-specific components that aren't added during conversion. - /// - /// An example of such a usage is for combo colours. - /// - /// - public virtual void PostProcess() + public virtual void PreProcess() { IHasComboInformation lastObj = null; @@ -62,5 +72,9 @@ namespace osu.Game.Beatmaps lastObj = obj; } } + + public virtual void PostProcess() + { + } } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 1a65611a3d..1dc90b3d6c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -116,6 +116,11 @@ namespace osu.Game.Beatmaps mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); } + IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted); + + // Pre-process + processor?.PreProcess(); + // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed foreach (var obj in converted.HitObjects) obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty); @@ -125,7 +130,7 @@ namespace osu.Game.Beatmaps mod.ApplyToHitObject(obj); // Post-process - rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess(); + processor?.PostProcess(); return converted; } From 99068debc41b68636402b866feab04700a01ef82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 13:07:00 +0900 Subject: [PATCH 086/190] Split out into separate interface + add xmldocs --- osu.Game/Beatmaps/BeatmapProcessor.cs | 32 +-------------------- osu.Game/Beatmaps/IBeatmapConverter.cs | 3 ++ osu.Game/Beatmaps/IBeatmapProcessor.cs | 40 ++++++++++++++++++++++++++ osu.Game/Rulesets/Ruleset.cs | 10 +++++++ 4 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 osu.Game/Beatmaps/IBeatmapProcessor.cs diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index 1fc22197fe..0173125e8b 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -6,39 +6,9 @@ using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps { - public interface IBeatmapProcessor - { - IBeatmap Beatmap { get; } - - /// - /// Processes the converted prior to being invoked. - /// - /// Nested s generated during will not be present by this point, - /// and no mods will have been applied to the s. - /// - /// - /// - /// This can only be used to add alterations to s generated directly through the conversion process. - /// - void PreProcess(); - - /// - /// Processes the converted after has been invoked. - /// - /// Nested s generated during will be present by this point, - /// and mods will have been applied to all s. - /// - /// - /// - /// This should be used to add alterations to s while they are in their most playable state. - /// - void PostProcess(); - } - /// - /// Processes a post-converted Beatmap. + /// Provides functionality to alter a after it has been converted. /// - /// The type of HitObject contained in the Beatmap. public class BeatmapProcessor : IBeatmapProcessor { public IBeatmap Beatmap { get; } diff --git a/osu.Game/Beatmaps/IBeatmapConverter.cs b/osu.Game/Beatmaps/IBeatmapConverter.cs index 00566093b8..cbf9d184ac 100644 --- a/osu.Game/Beatmaps/IBeatmapConverter.cs +++ b/osu.Game/Beatmaps/IBeatmapConverter.cs @@ -7,6 +7,9 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Beatmaps { + /// + /// Provides functionality to convert a for a . + /// public interface IBeatmapConverter { /// diff --git a/osu.Game/Beatmaps/IBeatmapProcessor.cs b/osu.Game/Beatmaps/IBeatmapProcessor.cs new file mode 100644 index 0000000000..282662373a --- /dev/null +++ b/osu.Game/Beatmaps/IBeatmapProcessor.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Beatmaps +{ + /// + /// Provides functionality to alter a after it has been converted. + /// + public interface IBeatmapProcessor + { + /// + /// The to process. This should already be converted to the applicable . + /// + IBeatmap Beatmap { get; } + + /// + /// Processes the converted prior to being invoked. + /// + /// Nested s generated during will not be present by this point, + /// and no mods will have been applied to the s. + /// + /// + /// + /// This can only be used to add alterations to s generated directly through the conversion process. + /// + void PreProcess(); + + /// + /// Processes the converted after has been invoked. + /// + /// Nested s generated during will be present by this point, + /// and mods will have been applied to all s. + /// + /// + /// + /// This should be used to add alterations to s while they are in their most playable state. + /// + void PostProcess(); + } +} diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f818523a3d..82d9945ef7 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -57,8 +57,18 @@ namespace osu.Game.Rulesets /// public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap); + /// + /// Creates a to convert a to one that is applicable for this . + /// + /// The to be converted. + /// The . public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap); + /// + /// Optionally creates a to alter a after it has been converted. + /// + /// The to be processed. + /// The . public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null; public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); From 4fb276bab7ebfdabec52023027d30eeb1ebd3f98 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 13:52:13 +0900 Subject: [PATCH 087/190] Move hyperdash init to PostProcess --- .../Beatmaps/CatchBeatmapProcessor.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 02395331dc..aa05e5a4d6 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -22,19 +22,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { } - public override void PreProcess() - { - base.PreProcess(); - - initialiseHyperDash((List)Beatmap.HitObjects); - } - public override void PostProcess() { base.PostProcess(); applyPositionOffsets(); + initialiseHyperDash((List)Beatmap.HitObjects); + int index = 0; foreach (var obj in Beatmap.HitObjects.OfType()) { From 3b262e0d1640eacf7f50b796bdd10b9272052fd3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 15:01:33 +0900 Subject: [PATCH 088/190] Use better casting --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 8473f5a36c..33fc838d35 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -49,9 +49,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps switch (obj) { case BananaShower bananaShower: - foreach (var nested in bananaShower.NestedHitObjects) + foreach (var banana in bananaShower.NestedHitObjects.OfType()) { - ((BananaShower.Banana)nested).X = (float)rng.NextDouble(); + banana.X = (float)rng.NextDouble(); rng.Next(); // osu!stable retrieved a random banana type rng.Next(); // osu!stable retrieved a random banana rotation rng.Next(); // osu!stable retrieved a random banana colour From f7fbf6130624c4bde66c84895c415bbe38ef0ce9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 15:27:02 +0900 Subject: [PATCH 089/190] Centralise judgement logic --- .../Objects/Drawable/DrawableBanana.cs | 9 +-------- .../Objects/Drawable/DrawableCatchHitObject.cs | 8 +++++++- .../Objects/Drawable/DrawableDroplet.cs | 9 +-------- .../Objects/Drawable/DrawableTinyDroplet.cs | 9 +-------- 4 files changed, 10 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs index dc2fa18ad4..dd027abbe0 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Rulesets.Catch.Judgements; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -13,12 +12,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { } - protected override void CheckForJudgements(bool userTriggered, double timeOffset) - { - if (CheckPosition == null) return; - - if (timeOffset >= 0) - AddJudgement(new CatchBananaJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); - } + protected override CatchJudgement CreateJudgement() => new CatchBananaJudgement(); } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 2f3e5f823e..6ce2e6a2ae 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -58,9 +58,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable if (CheckPosition == null) return; if (timeOffset >= 0) - AddJudgement(new CatchJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); + { + var judgement = CreateJudgement(); + judgement.Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss; + AddJudgement(judgement); + } } + protected virtual CatchJudgement CreateJudgement() => new CatchJudgement(); + protected override void SkinChanged(ISkinSource skin, bool allowFallback) { base.SkinChanged(skin, allowFallback); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index b4f914d21c..11d5ed1f92 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; using osu.Game.Rulesets.Catch.Judgements; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -25,13 +24,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Masking = false; } - protected override void CheckForJudgements(bool userTriggered, double timeOffset) - { - if (CheckPosition == null) return; - - if (timeOffset >= 0) - AddJudgement(new CatchDropletJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); - } + protected override CatchJudgement CreateJudgement() => new CatchDropletJudgement(); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs index 7a3972da51..2232bb81a7 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs @@ -3,7 +3,6 @@ using OpenTK; using osu.Game.Rulesets.Catch.Judgements; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -15,12 +14,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 8; } - protected override void CheckForJudgements(bool userTriggered, double timeOffset) - { - if (CheckPosition == null) return; - - if (timeOffset >= 0) - AddJudgement(new CatchTinyDropletJudgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); - } + protected override CatchJudgement CreateJudgement() => new CatchTinyDropletJudgement(); } } From f1a35f77d2581678eb6bf3ef3a3608c261f76eba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 16:49:01 +0900 Subject: [PATCH 090/190] Make bananas explode even on miss --- .../Judgements/CatchBananaJudgement.cs | 2 ++ .../Judgements/CatchBananaShowerJudgement.cs | 21 ------------------- .../Judgements/CatchJudgement.cs | 7 +++++++ .../Objects/Drawable/DrawableBananaShower.cs | 7 +------ .../Scoring/CatchScoreProcessor.cs | 1 - osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 ++-- 6 files changed, 12 insertions(+), 30 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index 393e3994a1..b0b00d8a42 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -10,6 +10,8 @@ namespace osu.Game.Rulesets.Catch.Judgements public override bool AffectsCombo => false; public override bool IsBonus => true; + public override bool ShouldExplode => true; + protected override int NumericResultFor(HitResult result) { switch (result) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs deleted file mode 100644 index a3a9aa4f04..0000000000 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaShowerJudgement.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Rulesets.Catch.Judgements -{ - public class CatchBananaShowerJudgement : CatchJudgement - { - public override bool AffectsCombo => false; - public override bool IsBonus => true; - - public CatchBananaShowerJudgement() - { - Result = HitResult.Perfect; - } - - protected override int NumericResultFor(HitResult result) => 0; - protected override float HealthIncreaseFor(HitResult result) => 0; - } -} diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index 82d54c6095..922471137c 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements @@ -31,6 +32,12 @@ namespace osu.Game.Rulesets.Catch.Judgements /// public float HealthIncrease => HealthIncreaseFor(Result); + /// + /// Whether fruit on the platter should explode or drop. + /// Note that this is only checked if the owning object is also + /// + public virtual bool ShouldExplode => IsHit; + /// /// Convert a to a base health increase. /// diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index 182adab6e1..f039504600 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable @@ -27,11 +26,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable AddNested(getVisualRepresentation?.Invoke(b)); } - protected override void CheckForJudgements(bool userTriggered, double timeOffset) - { - if (timeOffset >= 0) - AddJudgement(new CatchBananaShowerJudgement()); - } + protected override bool ProvidesJudgement => false; protected override void AddNested(DrawableHitObject h) { diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index dfe8bba184..5b69d836a3 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -47,7 +47,6 @@ namespace osu.Game.Rulesets.Catch.Scoring case BananaShower shower: foreach (var _ in shower.NestedHitObjects.Cast()) AddJudgement(new CatchBananaJudgement { Result = HitResult.Perfect }); - AddJudgement(new CatchBananaShowerJudgement()); break; case Fruit _: AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index ceb05d349f..9c376f340a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; using osu.Framework.MathUtils; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Replays; @@ -78,12 +79,11 @@ namespace osu.Game.Rulesets.Catch.UI if (!fruit.StaysOnPlate) runAfterLoaded(() => MovableCatcher.Explode(caughtFruit)); - } if (fruit.HitObject.LastInCombo) { - if (judgement.IsHit) + if (((CatchJudgement)judgement).ShouldExplode) runAfterLoaded(() => MovableCatcher.Explode()); else MovableCatcher.Drop(); From 750f5a86c34cd49606ab7aeb9eaf4bf24d8d0357 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 16:49:11 +0900 Subject: [PATCH 091/190] Fix catch test failing due to disabled bindable --- osu.Game/Screens/Play/Player.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a2ed01f5a7..a993b61e7b 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -158,7 +158,8 @@ namespace osu.Game.Screens.Play userAudioOffset.TriggerChange(); ScoreProcessor = RulesetContainer.CreateScoreProcessor(); - config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); + if (!ScoreProcessor.Mode.Disabled) + config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); Children = new Drawable[] { From cacabeb67e9d584688c014fa8bba3e9071aae80d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 17:00:41 +0900 Subject: [PATCH 092/190] Remove unused field --- osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs | 5 ----- osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs | 6 ------ .../Objects/Drawables/DrawableHitCircle.cs | 1 - osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 3 +-- 4 files changed, 1 insertion(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index 922471137c..51d7d3b5cd 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -11,11 +11,6 @@ namespace osu.Game.Rulesets.Catch.Judgements { public override HitResult MaxResult => HitResult.Perfect; - /// - /// The positional hit offset. - /// - public float PositionOffset; - protected override int NumericResultFor(HitResult result) { switch (result) diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs index b7c4470592..26becfdec9 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Scoring; @@ -12,11 +11,6 @@ namespace osu.Game.Rulesets.Osu.Judgements { public override HitResult MaxResult => HitResult.Great; - /// - /// The positional hit offset. - /// - public Vector2 PositionOffset; - protected override int NumericResultFor(HitResult result) { switch (result) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 9fe6dcd46c..421c93d485 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AddJudgement(new OsuJudgement { Result = result, - PositionOffset = Vector2.Zero //todo: set to correct value }); } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index f2d5631e93..04724931ae 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -11,7 +11,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.UI; using System.Linq; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.UI { @@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.UI DrawableOsuJudgement explosion = new DrawableOsuJudgement(judgement, judgedObject) { Origin = Anchor.Centre, - Position = ((OsuHitObject)judgedObject.HitObject).StackedEndPosition + ((OsuJudgement)judgement).PositionOffset + Position = ((OsuHitObject)judgedObject.HitObject).StackedEndPosition }; judgementLayer.Add(explosion); From c0b65a6a73c694825cbd6ec770ca01068c8da436 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 17:07:08 +0900 Subject: [PATCH 093/190] Change default IsBonus definition and remove unnecessary overrides --- osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs | 1 - osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs | 1 - osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs | 1 - osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs | 1 - .../Judgements/TaikoDrumRollTickJudgement.cs | 1 - osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs | 1 - osu.Game/Rulesets/Judgements/Judgement.cs | 2 +- 7 files changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index b0b00d8a42..c39e663d75 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Catch.Judgements public class CatchBananaJudgement : CatchJudgement { public override bool AffectsCombo => false; - public override bool IsBonus => true; public override bool ShouldExplode => true; diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs index 9c78360911..9055e48a4c 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Mania.Judgements public class HoldNoteJudgement : ManiaJudgement { public override bool AffectsCombo => false; - public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) => 0; } diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 5d38e70d01..6eb5a79200 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Mania.Judgements public class HoldNoteTickJudgement : ManiaJudgement { public override bool AffectsCombo => false; - public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) => 20; } diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs index fc85ec8764..d52de9f971 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Osu.Judgements public class OsuSliderTailJudgement : OsuJudgement { public override bool AffectsCombo => false; - public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) => 0; } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index 17bd2d9608..446dd0d11b 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoDrumRollTickJudgement : TaikoJudgement { public override bool AffectsCombo => false; - public override bool IsBonus => true; protected override int NumericResultFor(HitResult result) { diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs index dbfd38e6f9..288ad236aa 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs @@ -6,7 +6,6 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoStrongHitJudgement : TaikoJudgement { public override bool AffectsCombo => false; - public override bool IsBonus => true; public TaikoStrongHitJudgement() { diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 3d70b23773..0937757981 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Judgements /// /// Whether the should be counted as base or bonus score. /// - public virtual bool IsBonus => false; + public virtual bool IsBonus => !AffectsCombo; /// /// The numeric representation for the result achieved. From e12ce3c2a8351ddc8bed9c94c33f34c0008b80d7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 17:21:19 +0900 Subject: [PATCH 094/190] Adjust xmldoc --- osu.Game/Rulesets/Judgements/Judgement.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 0937757981..129dd07c3e 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -45,12 +45,12 @@ namespace osu.Game.Rulesets.Judgements public double TimeOffset { get; set; } /// - /// Whether the should affect the combo portion of the score. + /// Whether the should affect the current combo. /// public virtual bool AffectsCombo => true; /// - /// Whether the should be counted as base or bonus score. + /// Whether the should be counted as base (combo) or bonus score. /// public virtual bool IsBonus => !AffectsCombo; From 4212a9d0d765efd1527701cd9e90559e62ffe131 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 18:23:53 +0900 Subject: [PATCH 095/190] Fix incorrect migration conditional --- osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs b/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs index c52288e598..c38cd19b42 100644 --- a/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs +++ b/osu.Game/Migrations/20180628011956_RemoveNegativeSetIDs.cs @@ -8,7 +8,7 @@ namespace osu.Game.Migrations { // There was a change that baetmaps were being loaded with "-1" online IDs, which is completely incorrect. // This ensures there will not be unique key conflicts as a result of these incorrectly imported beatmaps. - migrationBuilder.Sql("UPDATE BeatmapSetInfo SET OnlineBeatmapSetID = null WHERE OnlineBeatmapSetID < 0"); + migrationBuilder.Sql("UPDATE BeatmapSetInfo SET OnlineBeatmapSetID = null WHERE OnlineBeatmapSetID <= 0"); } protected override void Down(MigrationBuilder migrationBuilder) From 1e696d247e84d8f94d3122e55f67dffd6170b143 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 18:33:28 +0900 Subject: [PATCH 096/190] Re-privatise --- osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 5f0190e7d7..323046f758 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.Containers samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); - StateChanged += OnStateChanged; + StateChanged += onStateChanged; } /// @@ -65,7 +65,7 @@ namespace osu.Game.Graphics.Containers return base.OnClick(state); } - protected virtual void OnStateChanged(Visibility visibility) + private void onStateChanged(Visibility visibility) { switch (visibility) { From 6d6fcc953b0fc3a81dcefd8a3240185579eb946e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 19:25:20 +0900 Subject: [PATCH 097/190] Trim lines --- osu.Game/Screens/Select/SongSelect.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 42005681fc..9d1e76bcd9 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -180,7 +180,6 @@ namespace osu.Game.Screens.Select } } - [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours) { From 182ac808817829d559143d44e050af80753214d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 19:25:28 +0900 Subject: [PATCH 098/190] Cache also as IBindable --- osu.Game/OsuGame.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e92c1c495b..501d8544ff 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -146,7 +146,9 @@ namespace osu.Game } dependencies.CacheAs(this); + dependencies.CacheAs(ruleset); + dependencies.CacheAs>(ruleset); // bind config int to database RulesetInfo configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); From 1c32951d4b9c14679af832dbd6a2dce8eb89dca5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 19:32:42 +0900 Subject: [PATCH 099/190] Ensure toolbar triggers updates to SongSelect's ruleset --- osu.Game/Screens/Select/SongSelect.cs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9d1e76bcd9..238ed40e6b 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -127,7 +127,7 @@ namespace osu.Game.Screens.Select Size = new Vector2(carousel_width, 1), Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - SelectionChanged = carouselSelectionChanged, + SelectionChanged = updateSelectedBeatmap, BeatmapSetsChanged = carouselBeatmapsLoaded, }, FilterControl = new FilterControl @@ -186,6 +186,8 @@ namespace osu.Game.Screens.Select dependencies.CacheAs(this); dependencies.CacheAs(Ruleset); + base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce); + if (Footer != null) { Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); @@ -252,9 +254,6 @@ namespace osu.Game.Screens.Select private ScheduledDelegate selectionChangedDebounce; - // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. - private BeatmapInfo beatmapNoDebounce; - private void workingBeatmapChanged(WorkingBeatmap beatmap) { if (beatmap is DummyWorkingBeatmap) return; @@ -268,11 +267,17 @@ namespace osu.Game.Screens.Select } } + // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. + private BeatmapInfo beatmapNoDebounce; + private RulesetInfo rulesetNoDebounce; + /// - /// selection has been changed as the result of interaction with the carousel. + /// selection has been changed as the result of a user interaction. /// - private void carouselSelectionChanged(BeatmapInfo beatmap) + private void updateSelectedBeatmap(BeatmapInfo beatmap) { + var ruleset = base.Ruleset.Value; + void performLoad() { // We may be arriving here due to another component changing the bindable Beatmap. @@ -282,19 +287,20 @@ namespace osu.Game.Screens.Select bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); - Ruleset.Value = base.Ruleset.Value; + Ruleset.Value = ruleset; ensurePlayingSelected(preview); } UpdateBeatmap(Beatmap.Value); } - if (beatmap?.Equals(beatmapNoDebounce) == true) + if (beatmap?.Equals(beatmapNoDebounce) == true && ruleset?.Equals(rulesetNoDebounce) == true) return; selectionChangedDebounce?.Cancel(); beatmapNoDebounce = beatmap; + rulesetNoDebounce = ruleset; if (beatmap == null) performLoad(); @@ -463,7 +469,7 @@ namespace osu.Game.Screens.Select { // in the case random selection failed, we want to trigger selectionChanged // to show the dummy beatmap (we have nothing else to display). - carouselSelectionChanged(null); + updateSelectedBeatmap(null); } } From 34fef3caba8b226859d8182d6be420acf816aef5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 20:13:29 +0900 Subject: [PATCH 100/190] Update exception type --- osu.Game/Screens/BackgroundScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index 61277439c1..d3192aa612 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens { base.Push(screen); } - catch (InvalidOperationException) + catch (ScreenAlreadyExitedException) { // screen may have exited before the push was successful. } From 0e649b8866bc932f532060f500dc9694289aa9fc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 20:16:24 +0900 Subject: [PATCH 101/190] Change logic --- osu.Game/Screens/BackgroundScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index d3192aa612..9d9432b2ce 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens } // Make sure the in-progress loading is complete before pushing the screen. - while (screen.LoadState != LoadState.Ready) + while (screen.LoadState < LoadState.Ready) Thread.Sleep(1); try From 06bd3d48151af534b9df05c9e784eca59f0914b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 20:28:28 +0900 Subject: [PATCH 102/190] Use IBindable where possible --- osu.Game/Screens/Select/FilterControl.cs | 9 ++++----- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index abf14a653b..39f1a523ea 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select Sort = sort, SearchText = searchTextBox.Text, AllowConvertedBeatmaps = showConverted, - Ruleset = ruleset + Ruleset = ruleset.Value }; public Action Exit; @@ -163,14 +163,14 @@ namespace osu.Game.Screens.Select searchTextBox.HoldFocus = true; } - private readonly Bindable ruleset = new Bindable(); + private readonly IBindable ruleset = new Bindable(); private Bindable showConverted; public readonly Box Background; [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, Bindable parentRuleset, OsuConfigManager config) + private void load(OsuColour colours, IBindable parentRuleset, OsuConfigManager config) { sortTabs.AccentColour = colours.GreenLight; @@ -179,8 +179,7 @@ namespace osu.Game.Screens.Select if (parentRuleset != null) ruleset.BindTo(parentRuleset); - ruleset.ValueChanged += val => updateCriteria(); - ruleset.TriggerChange(); + ruleset.BindValueChanged(val => updateCriteria(), true); } private void updateCriteria() => FilterChanged?.Invoke(CreateCriteria()); diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index f248cbd0f4..ac6154369d 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Select.Leaderboards private FillFlowContainer scrollFlow; - private readonly Bindable ruleset = new Bindable(); + private readonly IBindable ruleset = new Bindable(); public Action ScoreSelected; @@ -192,7 +192,7 @@ namespace osu.Game.Screens.Select.Leaderboards } [BackgroundDependencyLoader(permitNulls: true)] - private void load(APIAccess api, Bindable parentRuleset) + private void load(APIAccess api, IBindable parentRuleset) { this.api = api; From 9187eb8626b6e755e3605abc53cd361c5cf9d6d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 20:50:30 +0900 Subject: [PATCH 103/190] SongSelect needs to recache as IBindable --- osu.Game/Screens/Select/SongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 238ed40e6b..bdb586b274 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -185,6 +185,7 @@ namespace osu.Game.Screens.Select { dependencies.CacheAs(this); dependencies.CacheAs(Ruleset); + dependencies.CacheAs>(Ruleset); base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce); From 6d6436c8d34ffd625bfe15fa85cc15d77eecd833 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 29 Jun 2018 20:50:39 +0900 Subject: [PATCH 104/190] Fix ruleset not getting updated if changed --- osu.Game/Screens/Select/SongSelect.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bdb586b274..94c16f1797 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -288,10 +288,11 @@ namespace osu.Game.Screens.Select bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); - Ruleset.Value = ruleset; ensurePlayingSelected(preview); } + Ruleset.Value = ruleset; + UpdateBeatmap(Beatmap.Value); } From 6a80a21078d7ad2c9dbe3dd552fbdbbaadf5f7e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Jun 2018 16:06:26 +0900 Subject: [PATCH 105/190] Tidy up escape handling --- .../Graphics/UserInterface/FocusedTextBox.cs | 16 +++--------- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 25 +++++++++++++++---- .../Graphics/UserInterface/SearchTextBox.cs | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 3 --- osu.Game/Screens/Menu/ButtonSystem.cs | 13 +--------- osu.Game/Screens/Menu/ExitConfirmOverlay.cs | 18 ++++++------- osu.Game/Screens/OsuScreen.cs | 18 ++----------- 7 files changed, 37 insertions(+), 58 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 6500578de3..af5765a791 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK.Graphics; -using OpenTK.Input; using osu.Framework.Input; using System; @@ -26,6 +25,7 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) + //todo: replace with KillInput after ppy/osu-framework#1656 is merged. GetContainingInputManager().ChangeFocus(null); } } @@ -39,18 +39,10 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + protected override void KillFocus() { - if (!args.Repeat && args.Key == Key.Escape) - { - if (Text.Length > 0) - Text = string.Empty; - else - Exit?.Invoke(); - return true; - } - - return base.OnKeyDown(state, args); + base.KillFocus(); + Exit?.Invoke(); } public override bool RequestsFocus => HoldFocus; diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 6021af2028..f21491c257 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -9,10 +9,12 @@ using osu.Framework.Input; using osu.Game.Graphics.Sprites; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface { - public class OsuTextBox : TextBox + public class OsuTextBox : TextBox, IKeyBindingHandler { protected override Color4 BackgroundUnfocused => Color4.Black.Opacity(0.5f); protected override Color4 BackgroundFocused => OsuColour.Gray(0.3f).Opacity(0.8f); @@ -33,10 +35,7 @@ namespace osu.Game.Graphics.UserInterface TextContainer.Height = 0.5f; CornerRadius = 5; - Current.DisabledChanged += disabled => - { - Alpha = disabled ? 0.3f : 1; - }; + Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; }; } [BackgroundDependencyLoader] @@ -59,5 +58,21 @@ namespace osu.Game.Graphics.UserInterface } protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize }; + + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + if (Text.Length > 0) + Text = string.Empty; + else + KillFocus(); + return true; + } + + return true; + } + + public bool OnReleased(GlobalAction action) => false; } } diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index e50539e120..09f5968acd 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -34,7 +34,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (HandlePendingText(state)) return true; + if (HandlePendingText(state)) return false; if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed) { diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index a12f9dee7e..29eb1094cf 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -202,9 +202,6 @@ namespace osu.Game.Overlays.KeyBinding switch (args.Key) { - case Key.Escape: - finalise(); - return true; case Key.Delete: { if (state.Keyboard.ShiftPressed) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 81abc4cd3d..374877673f 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -148,8 +148,6 @@ namespace osu.Game.Screens.Menu case Key.Space: logo?.TriggerOnClick(state); return true; - case Key.Escape: - return goBack(); } return false; @@ -181,16 +179,7 @@ namespace osu.Game.Screens.Menu } } - public bool OnReleased(GlobalAction action) - { - switch (action) - { - case GlobalAction.Back: - return true; - default: - return false; - } - } + public bool OnReleased(GlobalAction action) => false; private void onPlay() { diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs index 62605da5a4..4ada46749c 100644 --- a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs +++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs @@ -1,34 +1,34 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; using osu.Game.Overlays; -using OpenTK.Input; namespace osu.Game.Screens.Menu { - public class ExitConfirmOverlay : HoldToConfirmOverlay + public class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler { - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(GlobalAction action) { - if (args.Key == Key.Escape && !args.Repeat) + if (action == GlobalAction.Back) { BeginConfirm(); return true; } - return base.OnKeyDown(state, args); + return false; } - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + public bool OnReleased(GlobalAction action) { - if (args.Key == Key.Escape) + if (action == GlobalAction.Back) { AbortConfirm(); return true; } - return base.OnKeyUp(state, args); + return false; } } } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 61018f9e08..510f7b9726 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -8,7 +8,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -17,7 +16,6 @@ using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; -using OpenTK.Input; using osu.Game.Overlays; using osu.Framework.Graphics.Containers; @@ -106,6 +104,8 @@ namespace osu.Game.Screens public bool OnPressed(GlobalAction action) { + if (!IsCurrentScreen) return false; + if (action == GlobalAction.Back && AllowBackButton) { Exit(); @@ -117,20 +117,6 @@ namespace osu.Game.Screens public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (args.Repeat || !IsCurrentScreen) return false; - - switch (args.Key) - { - case Key.Escape: - Exit(); - return true; - } - - return base.OnKeyDown(state, args); - } - protected override void OnResuming(Screen last) { sampleExit?.Play(); From cd47bd2cf8be75f18844d482643557592fe6f32c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 21:06:43 +0900 Subject: [PATCH 106/190] Update framework --- osu.Game/Graphics/UserInterface/SearchTextBox.cs | 2 -- osu.Game/osu.Game.csproj | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 09f5968acd..7d53c9e9d9 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -34,8 +34,6 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (HandlePendingText(state)) return false; - if (!state.Keyboard.ControlPressed && !state.Keyboard.ShiftPressed) { switch (args.Key) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b4fccf0898..56c33c47af 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From ad28f88498d8081372b0070f29509ef6cdb181de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 21:25:51 +0900 Subject: [PATCH 107/190] Fix protection change --- osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index d34d2b2a7c..07920865c0 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface { protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize); - public override bool AllowClipboardExport => false; + protected override bool AllowClipboardExport => false; private readonly CapsWarning warning; From 7c0547b4ee00f053b87124b55cc65ac1ed7d47e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 23:16:05 +0900 Subject: [PATCH 108/190] Replace todo --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index af5765a791..77b6d3f618 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -25,8 +25,7 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) - //todo: replace with KillInput after ppy/osu-framework#1656 is merged. - GetContainingInputManager().ChangeFocus(null); + KillFocus(); } } From fb90a4924b04e9fe2c19039dd0e6f789aa323110 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 23:28:15 +0900 Subject: [PATCH 109/190] Only clear text in FocusedTextBox --- .../Graphics/UserInterface/FocusedTextBox.cs | 16 ++++++++++++++++ osu.Game/Graphics/UserInterface/OsuTextBox.cs | 7 ++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 77b6d3f618..4b2f40b7ae 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -4,6 +4,7 @@ using OpenTK.Graphics; using osu.Framework.Input; using System; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface { @@ -18,6 +19,7 @@ namespace osu.Game.Graphics.UserInterface public Action Exit; private bool focus; + public bool HoldFocus { get { return focus; } @@ -38,6 +40,20 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } + public override bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + if (Text.Length > 0) + { + Text = string.Empty; + return true; + } + } + + return base.OnPressed(action); + } + protected override void KillFocus() { base.KillFocus(); diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index f21491c257..ca45d1087a 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -59,14 +59,11 @@ namespace osu.Game.Graphics.UserInterface protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), TextSize = CalculatedTextSize }; - public bool OnPressed(GlobalAction action) + public virtual bool OnPressed(GlobalAction action) { if (action == GlobalAction.Back) { - if (Text.Length > 0) - Text = string.Empty; - else - KillFocus(); + KillFocus(); return true; } From 754e072e015c4e613d86103eac82f9d38aaceada Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 23:35:14 +0900 Subject: [PATCH 110/190] Don't handle all actions --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index ca45d1087a..88b0543de0 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -67,7 +67,7 @@ namespace osu.Game.Graphics.UserInterface return true; } - return true; + return false; } public bool OnReleased(GlobalAction action) => false; From 00fd5c8dbca797a6b4069e57082b5f4dfe8c98e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 30 Jun 2018 23:51:27 +0900 Subject: [PATCH 111/190] Fix regression causing binding settings to fail --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 4b2f40b7ae..10509a4639 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -40,6 +40,13 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (!HasFocus) return false; + + return base.OnKeyDown(state, args); + } + public override bool OnPressed(GlobalAction action) { if (action == GlobalAction.Back) From 7028767e50cf248272d3b34f83d6df8f987a45f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 14:08:34 +0900 Subject: [PATCH 112/190] Fix regression in HoldFocus behaviour --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 10509a4639..dd45452944 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -27,7 +27,7 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) - KillFocus(); + base.KillFocus(); } } From b1403d837e7c0adc3c538b811ea6a9fccb7cdf6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 15:52:47 +0900 Subject: [PATCH 113/190] Add back support for closing focused overlays using back key --- .../Containers/OsuFocusedOverlayContainer.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 323046f758..39369350ef 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -8,12 +8,14 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using OpenTK; using osu.Framework.Configuration; +using osu.Framework.Input.Bindings; using osu.Game.Audio; +using osu.Game.Input.Bindings; using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { - public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner + public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler { private SampleChannel samplePopIn; private SampleChannel samplePopOut; @@ -65,6 +67,19 @@ namespace osu.Game.Graphics.Containers return base.OnClick(state); } + public bool OnPressed(GlobalAction action) + { + if (action == GlobalAction.Back) + { + State = Visibility.Hidden; + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; + private void onStateChanged(Visibility visibility) { switch (visibility) From 98fb2e03c0bcf3ebc47e65855d82ab6ada6bf04e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 18:03:15 +0900 Subject: [PATCH 114/190] Fix rulesets not loading in debug builds after running a release build --- osu.Game/Rulesets/RulesetStore.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index a7a9fea5f2..513173ef2f 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -84,7 +84,13 @@ namespace osu.Game.Rulesets { try { - var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo), (RulesetInfo)null)).RulesetInfo; + var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo, asm => + { + // for the time being, let's ignore the version being loaded. + // this allows for debug builds to successfully load rulesets (even though debug rulesets have a 0.0.0 version). + asm.Version = null; + return Assembly.Load(asm); + }, null), (RulesetInfo)null)).RulesetInfo; r.Name = instanceInfo.Name; r.ShortName = instanceInfo.ShortName; From 2c597874bf8340cde91856f931855a08d092b10b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 18:17:02 +0900 Subject: [PATCH 115/190] Fix leaderboard showing placeholder briefly when entering song select --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index ac6154369d..a0d447afed 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -40,6 +40,8 @@ namespace osu.Game.Screens.Select.Leaderboards private ScheduledDelegate showScoresDelegate; + private bool scoresLoadedOnce; + private IEnumerable scores; public IEnumerable Scores { @@ -48,6 +50,8 @@ namespace osu.Game.Screens.Select.Leaderboards { scores = value; + scoresLoadedOnce = true; + scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire(); scrollFlow = null; @@ -227,6 +231,10 @@ namespace osu.Game.Screens.Select.Leaderboards private void updateScores() { + // don't display any scores or placeholder until the first Scores_Set has been called. + // this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished. + if (!scoresLoadedOnce) return; + getScoresRequest?.Cancel(); getScoresRequest = null; From 6a459efd8f47aeba5a1c27a032eb038c3023db3b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 11:04:40 +0900 Subject: [PATCH 116/190] Don't allow Key.Escape --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index dd45452944..28d04c9a82 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -5,6 +5,7 @@ using OpenTK.Graphics; using osu.Framework.Input; using System; using osu.Game.Input.Bindings; +using OpenTK.Input; namespace osu.Game.Graphics.UserInterface { @@ -44,6 +45,9 @@ namespace osu.Game.Graphics.UserInterface { if (!HasFocus) return false; + if (args.Key == Key.Escape) + return false; // disable the framework-level handling of escape key for confority (we use GlobalAction.Back). + return base.OnKeyDown(state, args); } From f007e71c87369e7e07e65fe5c1fdb2dae23d6ba2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 12:31:41 +0900 Subject: [PATCH 117/190] Retrieve the mania key action through DI --- .../TestCaseColumn.cs | 6 ++-- .../TestCaseNotes.cs | 12 +++++-- .../TestCaseStage.cs | 4 +-- .../Objects/Drawables/DrawableHoldNote.cs | 22 ++++++------ .../Drawables/DrawableManiaHitObject.cs | 35 ++++++++++++------- .../Objects/Drawables/DrawableNote.cs | 6 ++-- osu.Game.Rulesets.Mania/UI/Column.cs | 25 ++++++------- .../UI/Components/ColumnBackground.cs | 10 +++--- .../UI/Components/ColumnKeyArea.cs | 11 +++--- .../UI/ManiaRulesetContainer.cs | 20 +++++------ osu.Game.Rulesets.Mania/UI/ManiaStage.cs | 2 +- 11 files changed, 83 insertions(+), 70 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs index 72f0b046b6..de2bfaed9c 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new Note { Column = i, StartTime = Time.Current + 2000 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - columns[i].Add(new DrawableNote(obj, columns[i].Action)); + columns[i].Add(new DrawableNote(obj)); } } @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - columns[i].Add(new DrawableHoldNote(obj, columns[i].Action)); + columns[i].Add(new DrawableHoldNote(obj)); } } @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.Tests Origin = Anchor.Centre, Height = 0.85f, AccentColour = Color4.OrangeRed, - Action = action, + Action = { Value = action }, VisibleTimeRange = { Value = 2000 } }; diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs index 4fdfac93b7..0f70ceece2 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -63,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Tests AutoSizeAxes = Axes.Both, Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLower()}") { - Child = new DrawableNote(note, ManiaAction.Key1) { AccentColour = Color4.OrangeRed } + Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed } } }; } @@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests AutoSizeAxes = Axes.Both, Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLower()}") { - Child = new DrawableHoldNote(note, ManiaAction.Key1) + Child = new DrawableHoldNote(note) { RelativeSizeAxes = Axes.Both, AccentColour = Color4.OrangeRed, @@ -136,6 +137,13 @@ namespace osu.Game.Rulesets.Mania.Tests }; } + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + dependencies.CacheAs>(new Bindable()); + return dependencies; + } + protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs index 9aff853ffd..8046c46fc1 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new Note { Column = i, StartTime = Time.Current + 2000 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - stage.Add(new DrawableNote(obj, stage.Columns[i].Action)); + stage.Add(new DrawableNote(obj)); } } } @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - stage.Add(new DrawableHoldNote(obj, stage.Columns[i].Action)); + stage.Add(new DrawableHoldNote(obj)); } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index ce0276f759..597450f223 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -38,8 +38,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly Container tickContainer; - public DrawableHoldNote(HoldNote hitObject, ManiaAction action) - : base(hitObject, action) + public DrawableHoldNote(HoldNote hitObject) + : base(hitObject) { RelativeSizeAxes = Axes.X; @@ -57,12 +57,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables HoldStartTime = () => holdStartTime }) }, - head = new DrawableHeadNote(this, action) + head = new DrawableHeadNote(this) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre }, - tail = new DrawableTailNote(this, action) + tail = new DrawableTailNote(this) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre @@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime) return false; - if (action != Action) + if (action != Action.Value) return false; // The user has pressed during the body of the hold note, after the head note and its hit windows have passed @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!holdStartTime.HasValue) return false; - if (action != Action) + if (action != Action.Value) return false; holdStartTime = null; @@ -154,8 +154,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { private readonly DrawableHoldNote holdNote; - public DrawableHeadNote(DrawableHoldNote holdNote, ManiaAction action) - : base(holdNote.HitObject.Head, action) + public DrawableHeadNote(DrawableHoldNote holdNote) + : base(holdNote.HitObject.Head) { this.holdNote = holdNote; } @@ -191,8 +191,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly DrawableHoldNote holdNote; - public DrawableTailNote(DrawableHoldNote holdNote, ManiaAction action) - : base(holdNote.HitObject.Tail, action) + public DrawableTailNote(DrawableHoldNote holdNote) + : base(holdNote.HitObject.Tail) { this.holdNote = holdNote; } @@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!holdNote.holdStartTime.HasValue) return false; - if (action != Action) + if (action != Action.Value) return false; UpdateJudgement(true); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 1271fae0c1..cb6196a890 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -10,30 +11,26 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.Objects.Drawables { - public abstract class DrawableManiaHitObject : DrawableHitObject - where TObject : ManiaHitObject + public abstract class DrawableManiaHitObject : DrawableHitObject { /// - /// The key that will trigger input for this hit object. + /// The which causes this to be hit. /// - protected ManiaAction Action { get; } - - public new TObject HitObject; + protected readonly IBindable Action = new Bindable(); protected readonly IBindable Direction = new Bindable(); - protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null) + protected DrawableManiaHitObject(ManiaHitObject hitObject) : base(hitObject) { - HitObject = hitObject; - - if (action != null) - Action = action.Value; } - [BackgroundDependencyLoader] - private void load(IScrollingInfo scrollingInfo) + [BackgroundDependencyLoader(true)] + private void load([CanBeNull] IBindable action, [NotNull] IScrollingInfo scrollingInfo) { + if (action != null) + Action.BindTo(action); + Direction.BindTo(scrollingInfo.Direction); Direction.BindValueChanged(OnDirectionChanged, true); } @@ -42,6 +39,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; } + } + + public abstract class DrawableManiaHitObject : DrawableManiaHitObject + where TObject : ManiaHitObject + { + public new readonly TObject HitObject; + + protected DrawableManiaHitObject(TObject hitObject) + : base(hitObject) + { + HitObject = hitObject; + } protected override void UpdateState(ArmedState state) { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index fb4aa74ad1..18084c4c08 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { private readonly NotePiece headPiece; - public DrawableNote(Note hitObject, ManiaAction action) - : base(hitObject, action) + public DrawableNote(Note hitObject) + : base(hitObject) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public virtual bool OnPressed(ManiaAction action) { - if (action != Action) + if (action != Action.Value) return false; return UpdateJudgement(true); diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index e731ce9195..a19a6fb5d4 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -7,6 +7,8 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.UI.Components; @@ -19,21 +21,7 @@ namespace osu.Game.Rulesets.Mania.UI private const float column_width = 45; private const float special_column_width = 70; - private ManiaAction action; - - public ManiaAction Action - { - get => action; - set - { - if (action == value) - return; - action = value; - - background.Action = value; - keyArea.Action = value; - } - } + public readonly Bindable Action = new Bindable(); private readonly ColumnBackground background; private readonly ColumnKeyArea keyArea; @@ -130,6 +118,13 @@ namespace osu.Game.Rulesets.Mania.UI } } + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + dependencies.CacheAs>(Action); + return dependencies; + } + /// /// Adds a DrawableHitObject to this Playfield. /// diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs index 9b744bd254..19cc8fffef 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components { public class ColumnBackground : CompositeDrawable, IKeyBindingHandler, IHasAccentColour { - public ManiaAction Action; + private readonly IBindable action = new Bindable(); private Box background; private Box backgroundOverlay; @@ -25,8 +25,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components private readonly IBindable direction = new Bindable(); [BackgroundDependencyLoader] - private void load(IScrollingInfo scrollingInfo) + private void load(IBindable action, IScrollingInfo scrollingInfo) { + this.action.BindTo(action); + InternalChildren = new[] { background = new Box @@ -91,14 +93,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components public bool OnPressed(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint); return false; } public bool OnReleased(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) backgroundOverlay.FadeTo(0, 250, Easing.OutQuint); return false; } diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs index 4ce1614310..e30a033831 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs @@ -21,15 +21,16 @@ namespace osu.Game.Rulesets.Mania.UI.Components private const float key_icon_size = 10; private const float key_icon_corner_radius = 3; - public ManiaAction Action; - + private readonly IBindable action = new Bindable(); private readonly IBindable direction = new Bindable(); private Container keyIcon; [BackgroundDependencyLoader] - private void load(IScrollingInfo scrollingInfo) + private void load(IBindable action, IScrollingInfo scrollingInfo) { + this.action.BindTo(action); + Drawable gradient; InternalChildren = new[] @@ -107,14 +108,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components public bool OnPressed(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint); return false; } public bool OnReleased(ManiaAction action) { - if (action == Action) + if (action == this.action.Value) keyIcon.ScaleTo(1f, 125, Easing.OutQuint); return false; } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index fa6fba0cd8..e6ebf43c67 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -101,17 +101,15 @@ namespace osu.Game.Rulesets.Mania.UI protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) { - ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action; - - var holdNote = h as HoldNote; - if (holdNote != null) - return new DrawableHoldNote(holdNote, action); - - var note = h as Note; - if (note != null) - return new DrawableNote(note, action); - - return null; + switch (h) + { + case HoldNote holdNote: + return new DrawableHoldNote(holdNote); + case Note note: + return new DrawableNote(note); + default: + return null; + } } protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs index 7b68582944..4c7deb4567 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.UI var column = new Column(direction) { IsSpecial = isSpecial, - Action = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ + Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ } }; AddColumn(column); From b7893bc9947780cd5517fc09ea5ab90d98f66607 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 13:05:09 +0900 Subject: [PATCH 118/190] Remove unnecessary comments --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 1dc90b3d6c..74da978d9c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -118,7 +118,6 @@ namespace osu.Game.Beatmaps IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted); - // Pre-process processor?.PreProcess(); // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed @@ -129,7 +128,6 @@ namespace osu.Game.Beatmaps foreach (var obj in converted.HitObjects) mod.ApplyToHitObject(obj); - // Post-process processor?.PostProcess(); return converted; From aea50e770b6a58f4e196cbf33bb2db1701248862 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 13:23:59 +0900 Subject: [PATCH 119/190] Use .Equals everywhere --- osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs | 2 +- osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs | 4 ++-- osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs | 4 ++-- osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs index 9c6735a36a..296dcf66b1 100644 --- a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs @@ -21,6 +21,6 @@ namespace osu.Game.Beatmaps.ControlPoints public override bool Equals(ControlPoint other) => base.Equals(other) && other is DifficultyControlPoint difficulty - && SpeedMultiplier == difficulty.SpeedMultiplier; + && SpeedMultiplier.Equals(difficulty.SpeedMultiplier); } } diff --git a/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs index 6fdddc44bb..e41fb3a1d3 100644 --- a/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs @@ -18,7 +18,7 @@ namespace osu.Game.Beatmaps.ControlPoints public override bool Equals(ControlPoint other) => base.Equals(other) && other is EffectControlPoint effect - && KiaiMode == effect.KiaiMode - && OmitFirstBarLine == effect.OmitFirstBarLine; + && KiaiMode.Equals(effect.KiaiMode) + && OmitFirstBarLine.Equals(effect.OmitFirstBarLine); } } diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index ae65e7ea42..c4d6ad24a0 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -46,7 +46,7 @@ namespace osu.Game.Beatmaps.ControlPoints public override bool Equals(ControlPoint other) => base.Equals(other) && other is SampleControlPoint sample - && SampleBank == sample.SampleBank - && SampleVolume == sample.SampleVolume; + && SampleBank.Equals(sample.SampleBank) + && SampleVolume.Equals(sample.SampleVolume); } } diff --git a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs index cc1546675b..3e4e2a0bb1 100644 --- a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs @@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps.ControlPoints public override bool Equals(ControlPoint other) => base.Equals(other) && other is TimingControlPoint timing - && TimeSignature == timing.TimeSignature - && BeatLength == timing.beatLength; + && TimeSignature.Equals(timing.TimeSignature) + && BeatLength.Equals(timing.BeatLength); } } From c78bfbfa55f9d49f0a20d1184820ede77259c964 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 13:24:09 +0900 Subject: [PATCH 120/190] Fix failing json conversion testcases --- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index b834be71f1..64bd563897 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -118,7 +118,11 @@ namespace osu.Game.Tests.Beatmaps.Formats public void TestParity(string beatmap) { var legacy = decode(beatmap, out Beatmap json); - json.WithDeepEqual(legacy).IgnoreProperty(r => r.DeclaringType == typeof(HitWindows)).Assert(); + json.WithDeepEqual(legacy) + .IgnoreProperty(r => r.DeclaringType == typeof(HitWindows) + // Todo: CustomSampleBank shouldn't exist going forward, we need a conversion mechanism + || r.Name == nameof(LegacyDecoder.LegacySampleControlPoint.CustomSampleBank)) + .Assert(); } /// From b664d3ef8176662bfe44855394fcba78a268955b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 13:33:59 +0900 Subject: [PATCH 121/190] Fix time being a part of controlpoint change comparisons --- osu.Game/Beatmaps/ControlPoints/ControlPoint.cs | 15 +++++++++------ .../ControlPoints/DifficultyControlPoint.cs | 4 ++-- .../Beatmaps/ControlPoints/EffectControlPoint.cs | 4 ++-- .../Beatmaps/ControlPoints/SampleControlPoint.cs | 4 ++-- .../Beatmaps/ControlPoints/TimingControlPoint.cs | 4 ++-- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 +++--- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 ++-- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs index e1e5affc78..cf6d9a3ccd 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs @@ -14,12 +14,15 @@ namespace osu.Game.Beatmaps.ControlPoints public int CompareTo(ControlPoint other) => Time.CompareTo(other.Time); - public virtual bool Equals(ControlPoint other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + /// + /// Whether this provides the same changes to gameplay as another . + /// + /// The to compare to. + /// Whether this provides the same changes to gameplay as . + public virtual bool ChangeEquals(ControlPoint other) => !ReferenceEquals(null, other); - return Time.Equals(other.Time); - } + public bool Equals(ControlPoint other) + => ChangeEquals(other) + && Time.Equals(other.Time); } } diff --git a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs index 296dcf66b1..f821ff11f4 100644 --- a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs @@ -18,8 +18,8 @@ namespace osu.Game.Beatmaps.ControlPoints private double speedMultiplier = 1; - public override bool Equals(ControlPoint other) - => base.Equals(other) + public override bool ChangeEquals(ControlPoint other) + => base.ChangeEquals(other) && other is DifficultyControlPoint difficulty && SpeedMultiplier.Equals(difficulty.SpeedMultiplier); } diff --git a/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs index e41fb3a1d3..0cbdf7fdf2 100644 --- a/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/EffectControlPoint.cs @@ -15,8 +15,8 @@ namespace osu.Game.Beatmaps.ControlPoints /// public bool OmitFirstBarLine; - public override bool Equals(ControlPoint other) - => base.Equals(other) + public override bool ChangeEquals(ControlPoint other) + => base.ChangeEquals(other) && other is EffectControlPoint effect && KiaiMode.Equals(effect.KiaiMode) && OmitFirstBarLine.Equals(effect.OmitFirstBarLine); diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index c4d6ad24a0..11de392d14 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -43,8 +43,8 @@ namespace osu.Game.Beatmaps.ControlPoints Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume }; - public override bool Equals(ControlPoint other) - => base.Equals(other) + public override bool ChangeEquals(ControlPoint other) + => base.ChangeEquals(other) && other is SampleControlPoint sample && SampleBank.Equals(sample.SampleBank) && SampleVolume.Equals(sample.SampleVolume); diff --git a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs index 3e4e2a0bb1..8fe3257786 100644 --- a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs @@ -24,8 +24,8 @@ namespace osu.Game.Beatmaps.ControlPoints private double beatLength = 1000; - public override bool Equals(ControlPoint other) - => base.Equals(other) + public override bool ChangeEquals(ControlPoint other) + => base.ChangeEquals(other) && other is TimingControlPoint timing && TimeSignature.Equals(timing.TimeSignature) && BeatLength.Equals(timing.BeatLength); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index f33e963f08..fe55d19908 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -359,7 +359,7 @@ namespace osu.Game.Beatmaps.Formats { var existing = beatmap.ControlPointInfo.DifficultyPointAt(newPoint.Time); - if (newPoint.Equals(existing)) + if (newPoint.ChangeEquals(existing)) return; beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == newPoint.Time); @@ -370,7 +370,7 @@ namespace osu.Game.Beatmaps.Formats { var existing = beatmap.ControlPointInfo.EffectPointAt(newPoint.Time); - if (newPoint.Equals(existing)) + if (newPoint.ChangeEquals(existing)) return; beatmap.ControlPointInfo.EffectPoints.Add(newPoint); @@ -380,7 +380,7 @@ namespace osu.Game.Beatmaps.Formats { var existing = beatmap.ControlPointInfo.SamplePointAt(newPoint.Time); - if (newPoint.Equals(existing)) + if (newPoint.ChangeEquals(existing)) return; beatmap.ControlPointInfo.SamplePoints.Add(newPoint); diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 60fff4bd7f..f5e3a34462 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -184,8 +184,8 @@ namespace osu.Game.Beatmaps.Formats return baseInfo; } - public override bool Equals(ControlPoint other) - => base.Equals(other) + public override bool ChangeEquals(ControlPoint other) + => base.ChangeEquals(other) && other is LegacySampleControlPoint legacy && CustomSampleBank == legacy.CustomSampleBank; } From 37495c34faa7a02852934d2d9db0dab9e2492a66 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Mon, 2 Jul 2018 13:51:47 +0900 Subject: [PATCH 122/190] Fix possible nullreference --- osu.Game/Beatmaps/ControlPoints/ControlPoint.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs index cf6d9a3ccd..90c0ded38f 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs @@ -23,6 +23,7 @@ namespace osu.Game.Beatmaps.ControlPoints public bool Equals(ControlPoint other) => ChangeEquals(other) + && !ReferenceEquals(null, other) && Time.Equals(other.Time); } } From 8b0c6a4c855509aa3de33ddd97e33b70525ab5d8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 14:17:19 +0900 Subject: [PATCH 123/190] Make SampleControlPoint clone the existing SampleInfo --- osu.Game/Audio/SampleInfo.cs | 2 ++ .../Beatmaps/ControlPoints/SampleControlPoint.cs | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index f635b74030..53b6e439f5 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -32,5 +32,7 @@ namespace osu.Game.Audio /// The sample volume. /// public int Volume; + + public SampleInfo Clone() => (SampleInfo)MemberwiseClone(); } } diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 11de392d14..77d42551c6 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -36,12 +36,14 @@ namespace osu.Game.Beatmaps.ControlPoints /// /// The . This will not be modified. /// The modified . This does not share a reference with . - public virtual SampleInfo ApplyTo(SampleInfo sampleInfo) => new SampleInfo + public virtual SampleInfo ApplyTo(SampleInfo sampleInfo) { - Bank = sampleInfo.Bank ?? SampleBank, - Name = sampleInfo.Name, - Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume - }; + var newSampleInfo = sampleInfo.Clone(); + newSampleInfo.Bank = sampleInfo.Bank ?? SampleBank; + newSampleInfo.Name = sampleInfo.Name; + newSampleInfo.Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume; + return newSampleInfo; + } public override bool ChangeEquals(ControlPoint other) => base.ChangeEquals(other) From 310c4a7d6c04213b93a38082a3a225533a3cdc0d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 14:18:41 +0900 Subject: [PATCH 124/190] Make SampleInfo choose its own lookup name --- osu.Game/Audio/SampleInfo.cs | 7 +++++++ osu.Game/Skinning/SkinnableSound.cs | 18 ++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 53b6e439f5..7906a6012f 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; namespace osu.Game.Audio { @@ -33,6 +34,12 @@ namespace osu.Game.Audio /// public int Volume; + public virtual IEnumerable LookupNames => new[] + { + $"{Namespace}/{Bank}-{Name}", + $"{Bank}-{Name}" // Without namespace as a fallback + }; + public SampleInfo Clone() => (SampleInfo)MemberwiseClone(); } } diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 1a11b0c03e..2fc9cff463 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -44,19 +44,17 @@ namespace osu.Game.Skinning private SampleChannel loadChannel(SampleInfo info, Func getSampleFunction) { - SampleChannel ch = null; + foreach (var lookup in info.LookupNames) + { + var ch = getSampleFunction($"Gameplay/{lookup}"); + if (ch == null) + continue; - if (info.Namespace != null) - ch = getSampleFunction($"Gameplay/{info.Namespace}/{info.Bank}-{info.Name}"); - - // try without namespace as a fallback. - if (ch == null) - ch = getSampleFunction($"Gameplay/{info.Bank}-{info.Name}"); - - if (ch != null) ch.Volume.Value = info.Volume / 100.0; + return ch; + } - return ch; + return null; } } } From 73fac2115a286570e8673d0be0194a45037c8e61 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 14:20:35 +0900 Subject: [PATCH 125/190] Implement hitobject sample files --- .../Objects/Legacy/ConvertHitObjectParser.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 9edd0f1f34..8a996cfe30 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -6,6 +6,7 @@ using osu.Game.Rulesets.Objects.Types; using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using osu.Game.Beatmaps.Formats; using osu.Game.Audio; using System.Linq; @@ -196,8 +197,7 @@ namespace osu.Game.Rulesets.Objects.Legacy var bank = (LegacyBeatmapDecoder.LegacySampleBank)Convert.ToInt32(split[0]); var addbank = (LegacyBeatmapDecoder.LegacySampleBank)Convert.ToInt32(split[1]); - // Let's not implement this for now, because this doesn't fit nicely into the bank structure - //string sampleFile = split2.Length > 4 ? split2[4] : string.Empty; + bankInfo.Filename = split.Length > 4 ? split[4] : null; string stringBank = bank.ToString().ToLower(); if (stringBank == @"none") @@ -252,6 +252,10 @@ namespace osu.Game.Rulesets.Objects.Legacy private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) { + // Todo: This should return the normal SampleInfos if the specified sample file isn't found, but that's a pretty edge-case scenario + if (!string.IsNullOrEmpty(bankInfo.Filename)) + return new List { new FileSampleInfo { Filename = bankInfo.Filename } }; + var soundTypes = new List { new SampleInfo @@ -297,14 +301,24 @@ namespace osu.Game.Rulesets.Objects.Legacy private class SampleBankInfo { + public string Filename; + public string Normal; public string Add; public int Volume; - public SampleBankInfo Clone() + public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone(); + } + + private class FileSampleInfo : SampleInfo + { + public string Filename; + + public override IEnumerable LookupNames => new[] { - return (SampleBankInfo)MemberwiseClone(); - } + Filename, + Path.ChangeExtension(Filename, null) + }; } [Flags] From 596787c94123ead5839c41379ff52cb3a5555b4f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 14:22:37 +0900 Subject: [PATCH 126/190] Standardise input handling of popup dialogs --- osu.Game/Overlays/Dialog/PopupDialog.cs | 147 +++++++++++++----------- osu.Game/Overlays/DialogOverlay.cs | 49 ++++---- 2 files changed, 100 insertions(+), 96 deletions(-) diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 5f90ec67ad..68e4481446 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -6,16 +6,16 @@ using System.Linq; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Dialog { @@ -23,6 +23,9 @@ namespace osu.Game.Overlays.Dialog { public static readonly float ENTER_DURATION = 500; public static readonly float EXIT_DURATION = 200; + + protected override bool BlockPassThroughMouse => false; + private readonly Vector2 ringSize = new Vector2(100f); private readonly Vector2 ringMinifiedSize = new Vector2(20f); private readonly Vector2 buttonsEnterSpacing = new Vector2(0f, 50f); @@ -34,26 +37,28 @@ namespace osu.Game.Overlays.Dialog private readonly SpriteText header; private readonly TextFlowContainer body; + private bool actionInvoked; + public FontAwesome Icon { - get { return icon.Icon; } - set { icon.Icon = value; } + get => icon.Icon; + set => icon.Icon = value; } public string HeaderText { - get { return header.Text; } - set { header.Text = value; } + get => header.Text; + set => header.Text = value; } public string BodyText { - set { body.Text = value; } + set => body.Text = value; } public IEnumerable Buttons { - get { return buttonsContainer.Children; } + get => buttonsContainer.Children; set { buttonsContainer.ChildrenEnumerable = value; @@ -62,71 +67,17 @@ namespace osu.Game.Overlays.Dialog var action = b.Action; b.Action = () => { + if (actionInvoked) return; + Hide(); + + actionInvoked = true; action?.Invoke(); }; } } } - private void pressButtonAtIndex(int index) - { - if (index < Buttons.Count()) - Buttons.Skip(index).First().TriggerOnClick(); - } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (args.Repeat) return false; - - if (args.Key == Key.Enter || args.Key == Key.KeypadEnter) - { - Buttons.OfType().FirstOrDefault()?.TriggerOnClick(); - return true; - } - - // press button at number if 1-9 on number row or keypad are pressed - var k = args.Key; - if (k >= Key.Number1 && k <= Key.Number9) - { - pressButtonAtIndex(k - Key.Number1); - return true; - } - - if (k >= Key.Keypad1 && k <= Key.Keypad9) - { - pressButtonAtIndex(k - Key.Keypad1); - return true; - } - - return base.OnKeyDown(state, args); - } - - protected override void PopIn() - { - base.PopIn(); - - // Reset various animations but only if the dialog animation fully completed - if (content.Alpha == 0) - { - buttonsContainer.TransformSpacingTo(buttonsEnterSpacing); - buttonsContainer.MoveToY(buttonsEnterSpacing.Y); - ring.ResizeTo(ringMinifiedSize); - } - - content.FadeIn(ENTER_DURATION, Easing.OutQuint); - ring.ResizeTo(ringSize, ENTER_DURATION, Easing.OutQuint); - buttonsContainer.TransformSpacingTo(Vector2.Zero, ENTER_DURATION, Easing.OutQuint); - buttonsContainer.MoveToY(0, ENTER_DURATION, Easing.OutQuint); - } - - protected override void PopOut() - { - base.PopOut(); - - content.FadeOut(EXIT_DURATION, Easing.InSine); - } - public PopupDialog() { RelativeSizeAxes = Axes.Both; @@ -136,9 +87,6 @@ namespace osu.Game.Overlays.Dialog content = new Container { RelativeSizeAxes = Axes.Both, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Width = 0.4f, Alpha = 0f, Children = new Drawable[] { @@ -243,5 +191,66 @@ namespace osu.Game.Overlays.Dialog }, }; } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Repeat) return false; + + if (args.Key == Key.Enter || args.Key == Key.KeypadEnter) + { + Buttons.OfType().FirstOrDefault()?.TriggerOnClick(); + return true; + } + + // press button at number if 1-9 on number row or keypad are pressed + var k = args.Key; + if (k >= Key.Number1 && k <= Key.Number9) + { + pressButtonAtIndex(k - Key.Number1); + return true; + } + + if (k >= Key.Keypad1 && k <= Key.Keypad9) + { + pressButtonAtIndex(k - Key.Keypad1); + return true; + } + + return base.OnKeyDown(state, args); + } + + protected override void PopIn() + { + base.PopIn(); + + actionInvoked = false; + + // Reset various animations but only if the dialog animation fully completed + if (content.Alpha == 0) + { + buttonsContainer.TransformSpacingTo(buttonsEnterSpacing); + buttonsContainer.MoveToY(buttonsEnterSpacing.Y); + ring.ResizeTo(ringMinifiedSize); + } + + content.FadeIn(ENTER_DURATION, Easing.OutQuint); + ring.ResizeTo(ringSize, ENTER_DURATION, Easing.OutQuint); + buttonsContainer.TransformSpacingTo(Vector2.Zero, ENTER_DURATION, Easing.OutQuint); + buttonsContainer.MoveToY(0, ENTER_DURATION, Easing.OutQuint); + } + + protected override void PopOut() + { + if (!actionInvoked) buttonsContainer.Last().TriggerOnClick(); + + base.PopOut(); + content.FadeOut(EXIT_DURATION, Easing.InSine); + } + + private void pressButtonAtIndex(int index) + { + if (index < Buttons.Count()) + Buttons.Skip(index).First().TriggerOnClick(); + } } } diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index e26a3cba2f..c40f517023 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -1,12 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays.Dialog; -using OpenTK.Graphics; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; namespace osu.Game.Overlays @@ -16,6 +13,20 @@ namespace osu.Game.Overlays private readonly Container dialogContainer; private PopupDialog currentDialog; + public DialogOverlay() + { + RelativeSizeAxes = Axes.Both; + + Child = dialogContainer = new Container + { + RelativeSizeAxes = Axes.Both, + }; + + Width = 0.4f; + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + } + public void Push(PopupDialog dialog) { if (dialog == currentDialog) return; @@ -32,6 +43,8 @@ namespace osu.Game.Overlays protected override bool PlaySamplesOnStateChange => false; + protected override bool BlockPassThroughKeyboard => true; + private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v) { if (v != Visibility.Hidden) return; @@ -52,32 +65,14 @@ namespace osu.Game.Overlays protected override void PopOut() { base.PopOut(); - this.FadeOut(PopupDialog.EXIT_DURATION, Easing.InSine); - } - public DialogOverlay() - { - RelativeSizeAxes = Axes.Both; - - Children = new Drawable[] + if (currentDialog?.State == Visibility.Visible) { - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - }, - }, - dialogContainer = new Container - { - RelativeSizeAxes = Axes.Both, - }, - }; + currentDialog.Hide(); + return; + } + + this.FadeOut(PopupDialog.EXIT_DURATION, Easing.InSine); } } } From 9a54bf68542a9e46dcadb04a9a3e0ab193ba3237 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 14:27:42 +0900 Subject: [PATCH 127/190] Revert unnecessary change --- osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index 6a1b3f8502..f13d96b35e 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Replays //a button is in a pressed state IsImportant(currentDirection > 0 ? CurrentFrame : NextFrame) && //the next frame is within an allowable time span - Math.Abs(CurrentTime - (NextFrame?.Time ?? 0)) <= sixty_frame_time * 1.2; + Math.Abs(CurrentTime - NextFrame?.Time ?? 0) <= sixty_frame_time * 1.2; protected virtual bool IsImportant(TFrame frame) => false; From 831b11ff974d177dc4b48a6e0c9c7eb42b6566ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 14:28:56 +0900 Subject: [PATCH 128/190] Remove unnecessary null checks --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 187cad33f6..bbe2d67baa 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; - double stackThreshold = objectN.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); + double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency; if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - double stackThreshold = objectI.TimePreempt * (beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); + double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo.StackLeniency; /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. From 7f832e34c05fab9975b83f8b4f7a8e175510fd60 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 14:29:18 +0900 Subject: [PATCH 129/190] Reorder sample bank property setters --- osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 8a996cfe30..95589d8953 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -197,8 +197,6 @@ namespace osu.Game.Rulesets.Objects.Legacy var bank = (LegacyBeatmapDecoder.LegacySampleBank)Convert.ToInt32(split[0]); var addbank = (LegacyBeatmapDecoder.LegacySampleBank)Convert.ToInt32(split[1]); - bankInfo.Filename = split.Length > 4 ? split[4] : null; - string stringBank = bank.ToString().ToLower(); if (stringBank == @"none") stringBank = null; @@ -211,6 +209,8 @@ namespace osu.Game.Rulesets.Objects.Legacy if (split.Length > 3) bankInfo.Volume = int.Parse(split[3]); + + bankInfo.Filename = split.Length > 4 ? split[4] : null; } /// From 189194ee8d3e36261152760dc66a7437ec8adf49 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 14:35:03 +0900 Subject: [PATCH 130/190] Don't include empty namespace in sample lookup --- osu.Game/Audio/SampleInfo.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 7906a6012f..3d76184e09 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -34,11 +34,16 @@ namespace osu.Game.Audio /// public int Volume; - public virtual IEnumerable LookupNames => new[] + public virtual IEnumerable LookupNames { - $"{Namespace}/{Bank}-{Name}", - $"{Bank}-{Name}" // Without namespace as a fallback - }; + get + { + if (!string.IsNullOrEmpty(Namespace)) + yield return $"{Namespace}/{Bank}-{Name}"; + + yield return $"{Bank}-{Name}"; // Without namespace as a fallback even when we have a namespace + } + } public SampleInfo Clone() => (SampleInfo)MemberwiseClone(); } From c1b8799253e4ab2f4789306308925b9b20be326a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 14:40:43 +0900 Subject: [PATCH 131/190] Add simple testcase --- .../Formats/LegacyBeatmapDecoderTest.cs | 18 ++++++++++++++++++ .../Resources/custom-hitobject-samples.osu | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 osu.Game.Tests/Resources/custom-hitobject-samples.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index d3c61960bb..ad203d2107 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -230,5 +230,23 @@ namespace osu.Game.Tests.Beatmaps.Formats SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" }); } + + [Test] + public void TestDecodeCustomHitObjectSamples() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + using (var resStream = Resource.OpenResource("custom-hitobject-samples.osu")) + using (var stream = new StreamReader(resStream)) + { + var hitObjects = decoder.Decode(stream).HitObjects; + + Assert.AreEqual("hit_1.wav", hitObjects[0].Samples[0].LookupNames.First()); + Assert.AreEqual("hit_2.wav", hitObjects[1].Samples[0].LookupNames.First()); + Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name); + Assert.AreEqual("hit_1.wav", hitObjects[3].Samples[0].LookupNames.First()); + } + + SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" }); + } } } diff --git a/osu.Game.Tests/Resources/custom-hitobject-samples.osu b/osu.Game.Tests/Resources/custom-hitobject-samples.osu new file mode 100644 index 0000000000..588672e2d9 --- /dev/null +++ b/osu.Game.Tests/Resources/custom-hitobject-samples.osu @@ -0,0 +1,16 @@ +osu file format v14 + +[General] +SampleSet: Normal + +[TimingPoints] +2170,468.75,4,1,0,40,1,0 +2638,-100,4,1,1,40,0,0 +3107,-100,4,1,2,40,0,0 +3576,-100,4,1,0,40,0,0 + +[HitObjects] +255,193,2170,1,0,0:0:0:0:hit_1.wav +256,191,2638,5,0,0:0:0:0:hit_2.wav +255,193,3107,1,0,0:0:0:0: +256,191,3576,1,0,0:0:0:0:hit_1.wav From b61fe10f62fd53cf2f63fcfc5532f260bc030b78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 15:07:13 +0900 Subject: [PATCH 132/190] Adapt to IBindables --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 4 ++-- osu.Game/Tests/Visual/OsuTestCase.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 7e4c986810..c584a32a82 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Mods public readonly Bindable> SelectedMods = new Bindable>(); - public readonly Bindable Ruleset = new Bindable(); + public readonly IBindable Ruleset = new Bindable(); private void rulesetChanged(RulesetInfo newRuleset) { @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Mods } [BackgroundDependencyLoader] - private void load(OsuColour colours, Bindable ruleset, AudioManager audio) + private void load(OsuColour colours, IBindable ruleset, AudioManager audio) { SelectedMods.ValueChanged += selectedModsChanged; diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index b3e523b63c..5f70055021 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -28,6 +28,7 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(beatmap); Dependencies.CacheAs(Ruleset); + Dependencies.CacheAs>(Ruleset); return Dependencies; } From 90d90370c2afc7964fc90574ece2599b1bcf399b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 15:25:37 +0900 Subject: [PATCH 133/190] Use testcase ruleset --- osu.Game.Tests/Visual/TestCaseMods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs index 3255478bea..73c37348d5 100644 --- a/osu.Game.Tests/Visual/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/TestCaseMods.cs @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual foreach (var rulesetInfo in rulesets.AvailableRulesets) { Ruleset ruleset = rulesetInfo.CreateInstance(); - AddStep($"switch to {ruleset.Description}", () => modSelect.Ruleset.Value = rulesetInfo); + AddStep($"switch to {ruleset.Description}", () => Ruleset.Value = rulesetInfo); switch (ruleset) { From 341ffa46672e5b2665b5a68c2a371424e3e9efe7 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 2 Jul 2018 16:07:52 +0900 Subject: [PATCH 134/190] Fix MenuCursor crash --- osu.Game/Graphics/Cursor/MenuCursor.cs | 54 +++++++++++++++----------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 5f57fb76b0..47a3d5c998 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -11,9 +11,9 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Game.Configuration; using System; -using System.Diagnostics; using JetBrains.Annotations; using osu.Framework.Graphics.Textures; +using OpenTK.Input; namespace osu.Game.Graphics.Cursor { @@ -25,9 +25,8 @@ namespace osu.Game.Graphics.Cursor protected override Drawable CreateCursor() => new Cursor(); private Bindable cursorRotate; - private bool dragging; - - private bool startRotation; + private DragRotationState dragRotationState; + private Vector2 positionMouseDown; [BackgroundDependencyLoader(true)] private void load([NotNull] OsuConfigManager config, [CanBeNull] ScreenshotManager screenshotManager) @@ -40,18 +39,18 @@ namespace osu.Game.Graphics.Cursor protected override bool OnMouseMove(InputState state) { - if (cursorRotate && dragging) + if (dragRotationState != DragRotationState.NotDragging) { - Debug.Assert(state.Mouse.PositionMouseDown != null); - + var position = state.Mouse.Position; + var distance = Vector2Extensions.Distance(position, positionMouseDown); // don't start rotating until we're moved a minimum distance away from the mouse down location, // else it can have an annoying effect. - // ReSharper disable once PossibleInvalidOperationException - startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; - - if (startRotation) + if (dragRotationState == DragRotationState.DragStarted && distance > 30) + dragRotationState = DragRotationState.Rotating; + // don't rotate when distance if zero to avoid NaN + if (dragRotationState == DragRotationState.Rotating && distance > 0) { - Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; + Vector2 offset = state.Mouse.Position - positionMouseDown; float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f; // Always rotate in the direction of least distance @@ -66,13 +65,7 @@ namespace osu.Game.Graphics.Cursor return base.OnMouseMove(state); } - - protected override bool OnDragStart(InputState state) - { - dragging = true; - return base.OnDragStart(state); - } - + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { ActiveCursor.Scale = new Vector2(1); @@ -80,6 +73,12 @@ namespace osu.Game.Graphics.Cursor ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); + + if (args.Button == MouseButton.Left && cursorRotate) + { + dragRotationState = DragRotationState.DragStarted; + positionMouseDown = state.Mouse.Position; + } return base.OnMouseDown(state, args); } @@ -87,14 +86,16 @@ namespace osu.Game.Graphics.Cursor { if (!state.Mouse.HasMainButtonPressed) { - dragging = false; - startRotation = false; - ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint); - ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); ActiveCursor.ScaleTo(1, 500, Easing.OutElastic); } + if (args.Button == MouseButton.Left) + { + if (dragRotationState == DragRotationState.Rotating) + ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); + dragRotationState = DragRotationState.NotDragging; + } return base.OnMouseUp(state, args); } @@ -160,5 +161,12 @@ namespace osu.Game.Graphics.Cursor cursorScale.TriggerChange(); } } + + private enum DragRotationState + { + NotDragging, + DragStarted, + Rotating, + } } } From 63746876c2cbcdeb3dd02c81d5ab750e192b88d1 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 2 Jul 2018 16:09:33 +0900 Subject: [PATCH 135/190] typo --- osu.Game/Graphics/Cursor/MenuCursor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 47a3d5c998..15fd554d5b 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -47,7 +47,7 @@ namespace osu.Game.Graphics.Cursor // else it can have an annoying effect. if (dragRotationState == DragRotationState.DragStarted && distance > 30) dragRotationState = DragRotationState.Rotating; - // don't rotate when distance if zero to avoid NaN + // don't rotate when distance is zero to avoid NaN if (dragRotationState == DragRotationState.Rotating && distance > 0) { Vector2 offset = state.Mouse.Position - positionMouseDown; From 45a4187923cd18f2f2d80b683ea5e3cadb11574c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 16:10:56 +0900 Subject: [PATCH 136/190] Tidy up lookups to NestedHitObjects --- osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs | 3 --- .../Objects/Drawables/DrawableSlider.cs | 8 ++++---- .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 12 +++++------- .../Visualisers/OverlappingSpeedChangeVisualiser.cs | 9 +++------ .../Visualisers/SequentialSpeedChangeVisualiser.cs | 9 +++------ 5 files changed, 15 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs index 0f70ceece2..e827fa1fdc 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs @@ -153,9 +153,6 @@ namespace osu.Game.Rulesets.Mania.Tests if (!(obj.HitObject is IHasEndTime endTime)) continue; - if (!obj.HasNestedHitObjects) - continue; - foreach (var nested in obj.NestedHitObjects) { double finalPosition = (nested.HitObject.StartTime - obj.HitObject.StartTime) / endTime.Duration; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index c8544d9cc1..f1907a92a8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -93,9 +93,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.AccentColour = value; Body.AccentColour = AccentColour; Ball.AccentColour = AccentColour; - if (HasNestedHitObjects) - foreach (var drawableHitObject in NestedHitObjects) - drawableHitObject.AccentColour = AccentColour; + + foreach (var drawableHitObject in NestedHitObjects) + drawableHitObject.AccentColour = AccentColour; } } @@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { if (!userTriggered && Time.Current >= slider.EndTime) { - var judgementsCount = NestedHitObjects.Count; + var judgementsCount = NestedHitObjects.Count(); var judgementsHit = NestedHitObjects.Count(h => h.IsHit); var hitFraction = (double)judgementsHit / judgementsCount; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 88990d435c..1f857cb7a8 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -33,8 +33,7 @@ namespace osu.Game.Rulesets.Objects.Drawables protected virtual IEnumerable GetSamples() => HitObject.Samples; private readonly Lazy> nestedHitObjects = new Lazy>(); - public bool HasNestedHitObjects => nestedHitObjects.IsValueCreated; - public IReadOnlyList NestedHitObjects => nestedHitObjects.Value; + public IEnumerable NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : Enumerable.Empty(); public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -50,12 +49,12 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether this and all of its nested s have been hit. /// - public bool IsHit => Judgements.Any(j => j.Final && j.IsHit) && (!HasNestedHitObjects || NestedHitObjects.All(n => n.IsHit)); + public bool IsHit => Judgements.Any(j => j.Final && j.IsHit) && NestedHitObjects.All(n => n.IsHit); /// /// Whether this and all of its nested s have been judged. /// - public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (!HasNestedHitObjects || NestedHitObjects.All(h => h.AllJudged)); + public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && NestedHitObjects.All(h => h.AllJudged); /// /// Whether this can be judged. @@ -206,9 +205,8 @@ namespace osu.Game.Rulesets.Objects.Drawables if (AllJudged) return false; - if (HasNestedHitObjects) - foreach (var d in NestedHitObjects) - judgementOccurred |= d.UpdateJudgement(userTriggered); + foreach (var d in NestedHitObjects) + judgementOccurred |= d.UpdateJudgement(userTriggered); if (!ProvidesJudgement || judgementFinalized || judgementOccurred) return judgementOccurred; diff --git a/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs index 35a91275a7..d2b79e2fa7 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs @@ -47,13 +47,10 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers } } - if (obj.HasNestedHitObjects) - { - ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); - // Nested hitobjects don't need to scroll, but they do need accurate positions - UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); - } + // Nested hitobjects don't need to scroll, but they do need accurate positions + UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs index 745352a4d3..25dea8dfbf 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs @@ -48,13 +48,10 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers } } - if (obj.HasNestedHitObjects) - { - ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); - // Nested hitobjects don't need to scroll, but they do need accurate positions - UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); - } + // Nested hitobjects don't need to scroll, but they do need accurate positions + UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } From ae6fdd8e29abfbda7394c16d4d30ea60be1de103 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 2 Jul 2018 16:20:44 +0900 Subject: [PATCH 137/190] whitespace --- osu.Game/Graphics/Cursor/MenuCursor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 15fd554d5b..0bb33930b0 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Graphics.Cursor return base.OnMouseMove(state); } - + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { ActiveCursor.Scale = new Vector2(1); From 9f405b0894910d02716545b9b28e39ea52ceca07 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 16:49:07 +0900 Subject: [PATCH 138/190] Don't hard-bail if config skin doesn't exist anymore --- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 930b3c1eaa..18a371e904 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -56,7 +56,13 @@ namespace osu.Game.Overlays.Settings.Sections reloadSkins(); - skinDropdown.Bindable = config.GetBindable(OsuSetting.Skin); + var skinBindable = config.GetBindable(OsuSetting.Skin); + + // Todo: This should not be necessary when OsuConfigManager is databased + if (skinDropdown.Items.All(s => s.Value != skinBindable.Value)) + skinBindable.Value = 0; + + skinDropdown.Bindable = skinBindable; } private void reloadSkins() => skinDropdown.Items = skins.GetAllUsableSkins().Select(s => new KeyValuePair(s.ToString(), s.ID)); From 6c848f135c70b67cc9d17bdb851518c79a1269af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 2 Jul 2018 17:48:16 +0900 Subject: [PATCH 139/190] Add comment about last button invocation --- osu.Game/Overlays/Dialog/PopupDialog.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 68e4481446..d90a850f4a 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -241,7 +241,10 @@ namespace osu.Game.Overlays.Dialog protected override void PopOut() { - if (!actionInvoked) buttonsContainer.Last().TriggerOnClick(); + if (!actionInvoked) + // In the case a user did not choose an action before a hide was triggered, press the last button. + // This is presumed to always be a sane default "cancel" action. + buttonsContainer.Last().TriggerOnClick(); base.PopOut(); content.FadeOut(EXIT_DURATION, Easing.InSine); From d476842c4462e04a9dcdad598c13a7938c1c1384 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 2 Jul 2018 22:03:17 -0700 Subject: [PATCH 140/190] Fix FooterButton clicking area --- osu.Game/Screens/Select/FooterButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 602b03380c..3fa12283b5 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -55,6 +55,8 @@ namespace osu.Game.Screens.Select private readonly Box box; private readonly Box light; + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => box.ReceiveMouseInputAt(screenSpacePos); + public FooterButton() { Children = new Drawable[] From f9f192ce3439a5649cf86ee091d3b01dcc4a93d3 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 2 Jul 2018 16:28:05 +0900 Subject: [PATCH 141/190] Modify MenuCursor hightlight animation --- osu.Game/Graphics/Cursor/MenuCursor.cs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 0bb33930b0..14a976f0c0 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -68,11 +68,15 @@ namespace osu.Game.Graphics.Cursor protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - ActiveCursor.Scale = new Vector2(1); - ActiveCursor.ScaleTo(0.90f, 800, Easing.OutQuint); + // only trigger animation for main mouse buttons + if (args.Button <= MouseButton.Right) + { + ActiveCursor.Scale = new Vector2(1); + ActiveCursor.ScaleTo(0.90f, 800, Easing.OutQuint); - ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; - ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); + ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; + ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); + } if (args.Button == MouseButton.Left && cursorRotate) { @@ -86,7 +90,7 @@ namespace osu.Game.Graphics.Cursor { if (!state.Mouse.HasMainButtonPressed) { - ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint); + ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint); ActiveCursor.ScaleTo(1, 500, Easing.OutElastic); } @@ -99,13 +103,6 @@ namespace osu.Game.Graphics.Cursor return base.OnMouseUp(state, args); } - protected override bool OnClick(InputState state) - { - ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint); - - return base.OnClick(state); - } - protected override void PopIn() { ActiveCursor.FadeTo(1, 250, Easing.OutQuint); From 73851fb1945a847b0e2108901c8845f4bcb439ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Jul 2018 15:57:05 +0900 Subject: [PATCH 142/190] Fix beatmap details not working for unranked beatmaps --- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 3b6bb565b0..bbaaa0c756 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -49,7 +49,7 @@ namespace osu.Game.Online.API.Requests.Responses private DateTimeOffset submitted { get; set; } [JsonProperty(@"ranked_date")] - private DateTimeOffset ranked { get; set; } + private DateTimeOffset? ranked { get; set; } [JsonProperty(@"last_updated")] private DateTimeOffset lastUpdated { get; set; } From 2aae528e1ccf08e0feb586a83faf02c3205de8d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Jul 2018 18:18:04 +0900 Subject: [PATCH 143/190] Improve code quality of main menu button system --- osu.Game.Tests/Visual/TestCaseButtonSystem.cs | 13 ++ osu.Game/Screens/Menu/Button.cs | 36 ++- osu.Game/Screens/Menu/ButtonArea.cs | 148 ++++++++++++ osu.Game/Screens/Menu/ButtonSystem.cs | 217 +++++------------- osu.Game/Screens/Menu/MainMenu.cs | 10 +- 5 files changed, 263 insertions(+), 161 deletions(-) create mode 100644 osu.Game/Screens/Menu/ButtonArea.cs diff --git a/osu.Game.Tests/Visual/TestCaseButtonSystem.cs b/osu.Game.Tests/Visual/TestCaseButtonSystem.cs index 5eb81cdf9f..7f8133d638 100644 --- a/osu.Game.Tests/Visual/TestCaseButtonSystem.cs +++ b/osu.Game.Tests/Visual/TestCaseButtonSystem.cs @@ -1,6 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -13,6 +16,13 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseButtonSystem : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ButtonSystem), + typeof(ButtonArea), + typeof(Button) + }; + public TestCaseButtonSystem() { OsuLogo logo; @@ -30,6 +40,9 @@ namespace osu.Game.Tests.Visual }; buttons.SetOsuLogo(logo); + + foreach (var s in Enum.GetValues(typeof(ButtonSystemState)).OfType().Skip(1)) + AddStep($"State to {s}", () => buttons.State = s); } } } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index 542ddd2c92..f862905b5e 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -35,6 +35,12 @@ namespace osu.Game.Screens.Menu private readonly Box boxHoverLayer; private readonly SpriteIcon icon; private readonly string sampleName; + + /// + /// The menu state for which we are visible for. + /// + public ButtonSystemState? VisibleState; + private readonly Action clickAction; private readonly Key triggerKey; private SampleChannel sampleClick; @@ -51,7 +57,7 @@ namespace osu.Game.Screens.Menu AutoSizeAxes = Axes.Both; Alpha = 0; - Vector2 boxSize = new Vector2(ButtonSystem.BUTTON_WIDTH + Math.Abs(extraWidth), ButtonSystem.BUTTON_AREA_HEIGHT); + Vector2 boxSize = new Vector2(ButtonSystem.BUTTON_WIDTH + Math.Abs(extraWidth), ButtonArea.BUTTON_AREA_HEIGHT); Children = new Drawable[] { @@ -260,6 +266,7 @@ namespace osu.Game.Screens.Menu this.FadeOut(800); break; } + break; case ButtonState.Expanded: const int expand_duration = 500; @@ -276,6 +283,33 @@ namespace osu.Game.Screens.Menu StateChanged?.Invoke(State); } } + + public ButtonSystemState ButtonSystemState + { + set + { + ContractStyle = 0; + + switch (value) + { + case ButtonSystemState.Initial: + State = ButtonState.Contracted; + break; + case ButtonSystemState.EnteringMode: + ContractStyle = 1; + State = ButtonState.Contracted; + break; + default: + if (!VisibleState.HasValue || value == VisibleState) + State = ButtonState.Expanded; + else if (value < VisibleState) + State = ButtonState.Contracted; + else + State = ButtonState.Exploded; + break; + } + } + } } public enum ButtonState diff --git a/osu.Game/Screens/Menu/ButtonArea.cs b/osu.Game/Screens/Menu/ButtonArea.cs new file mode 100644 index 0000000000..06004405b6 --- /dev/null +++ b/osu.Game/Screens/Menu/ButtonArea.cs @@ -0,0 +1,148 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK; + +namespace osu.Game.Screens.Menu +{ + public class ButtonArea : Container, IStateful + { + public FlowContainerWithOrigin Flow; + + protected override Container Content => Flow; + + private readonly ButtonAreaBackground buttonAreaBackground; + private Visibility state; + + public const float BUTTON_AREA_HEIGHT = 100; + + public ButtonArea() + { + RelativeSizeAxes = Axes.Both; + InternalChild = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Size = new Vector2(1, BUTTON_AREA_HEIGHT), + Alpha = 0, + Children = new Drawable[] + { + buttonAreaBackground = new ButtonAreaBackground(), + Flow = new FlowContainerWithOrigin + { + Direction = FillDirection.Horizontal, + Spacing = new Vector2(-ButtonSystem.WEDGE_WIDTH, 0), + Anchor = Anchor.Centre, + AutoSizeAxes = Axes.Both, + } + } + }; + } + + public ButtonSystemState ButtonSystemState + { + set + { + switch (value) + { + case ButtonSystemState.Exit: + case ButtonSystemState.Initial: + case ButtonSystemState.EnteringMode: + State = Visibility.Hidden; + break; + case ButtonSystemState.TopLevel: + case ButtonSystemState.Play: + State = Visibility.Visible; + break; + } + + buttonAreaBackground.ButtonSystemState = value; + } + } + + public Visibility State + { + get => state; + set + { + if (value == state) return; + + state = value; + InternalChild.FadeTo(state == Visibility.Hidden ? 0 : 1, 300); + StateChanged?.Invoke(state); + } + } + + public event Action StateChanged; + + private class ButtonAreaBackground : Box, IStateful + { + private ButtonAreaBackgroundState state; + + public ButtonAreaBackground() + { + RelativeSizeAxes = Axes.Both; + Size = new Vector2(2, 1); + Colour = OsuColour.Gray(50); + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + + public ButtonAreaBackgroundState State + { + get => state; + set + { + if (value == state) return; + + state = value; + + switch (state) + { + case ButtonAreaBackgroundState.Flat: + this.ScaleTo(new Vector2(2, 0), 300, Easing.InSine); + break; + case ButtonAreaBackgroundState.Normal: + this.ScaleTo(Vector2.One, 400, Easing.OutQuint); + break; + } + + StateChanged?.Invoke(state); + } + } + + public ButtonSystemState ButtonSystemState + { + set + { + switch (value) + { + default: + State = ButtonAreaBackgroundState.Normal; + break; + case ButtonSystemState.Initial: + case ButtonSystemState.Exit: + case ButtonSystemState.EnteringMode: + State = ButtonAreaBackgroundState.Flat; + break; + } + } + } + + public event Action StateChanged; + } + + public enum ButtonAreaBackgroundState + { + Normal, + Flat + } + } +} diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 374877673f..4f2437cf01 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -10,9 +10,9 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Framework.Input.Bindings; +using osu.Framework.Logging; using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Input.Bindings; @@ -23,9 +23,9 @@ using OpenTK.Input; namespace osu.Game.Screens.Menu { - public class ButtonSystem : Container, IStateful, IKeyBindingHandler + public class ButtonSystem : Container, IStateful, IKeyBindingHandler { - public event Action StateChanged; + public event Action StateChanged; public Action OnEdit; public Action OnExit; @@ -34,12 +34,6 @@ namespace osu.Game.Screens.Menu public Action OnSettings; public Action OnMulti; public Action OnChart; - public Action OnTest; - - private readonly FlowContainerWithOrigin buttonFlow; - - //todo: make these non-internal somehow. - public const float BUTTON_AREA_HEIGHT = 100; public const float BUTTON_WIDTH = 140f; public const float WEDGE_WIDTH = 20; @@ -55,18 +49,16 @@ namespace osu.Game.Screens.Menu this.logo.Action = onOsuLogo; // osuLogo.SizeForFlow relies on loading to be complete. - buttonFlow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); + buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); updateLogoState(); } } private readonly Drawable iconFacade; - private readonly Container buttonArea; - private readonly Box buttonAreaBackground; + private readonly ButtonArea buttonArea; private readonly Button backButton; - private readonly Button settingsButton; private readonly List public bool OmitFirstBarLine; - public override bool ChangeEquals(ControlPoint other) - => base.ChangeEquals(other) + public override bool EquivalentTo(ControlPoint other) + => base.EquivalentTo(other) && other is EffectControlPoint effect && KiaiMode.Equals(effect.KiaiMode) && OmitFirstBarLine.Equals(effect.OmitFirstBarLine); diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 77d42551c6..acccbcde46 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -45,8 +45,8 @@ namespace osu.Game.Beatmaps.ControlPoints return newSampleInfo; } - public override bool ChangeEquals(ControlPoint other) - => base.ChangeEquals(other) + public override bool EquivalentTo(ControlPoint other) + => base.EquivalentTo(other) && other is SampleControlPoint sample && SampleBank.Equals(sample.SampleBank) && SampleVolume.Equals(sample.SampleVolume); diff --git a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs index 8fe3257786..eb60133fed 100644 --- a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs @@ -24,8 +24,8 @@ namespace osu.Game.Beatmaps.ControlPoints private double beatLength = 1000; - public override bool ChangeEquals(ControlPoint other) - => base.ChangeEquals(other) + public override bool EquivalentTo(ControlPoint other) + => base.EquivalentTo(other) && other is TimingControlPoint timing && TimeSignature.Equals(timing.TimeSignature) && BeatLength.Equals(timing.BeatLength); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index fe55d19908..c79938e613 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -359,7 +359,7 @@ namespace osu.Game.Beatmaps.Formats { var existing = beatmap.ControlPointInfo.DifficultyPointAt(newPoint.Time); - if (newPoint.ChangeEquals(existing)) + if (newPoint.EquivalentTo(existing)) return; beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == newPoint.Time); @@ -370,7 +370,7 @@ namespace osu.Game.Beatmaps.Formats { var existing = beatmap.ControlPointInfo.EffectPointAt(newPoint.Time); - if (newPoint.ChangeEquals(existing)) + if (newPoint.EquivalentTo(existing)) return; beatmap.ControlPointInfo.EffectPoints.Add(newPoint); @@ -380,7 +380,7 @@ namespace osu.Game.Beatmaps.Formats { var existing = beatmap.ControlPointInfo.SamplePointAt(newPoint.Time); - if (newPoint.ChangeEquals(existing)) + if (newPoint.EquivalentTo(existing)) return; beatmap.ControlPointInfo.SamplePoints.Add(newPoint); diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index f5e3a34462..22a6acf459 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -184,8 +184,8 @@ namespace osu.Game.Beatmaps.Formats return baseInfo; } - public override bool ChangeEquals(ControlPoint other) - => base.ChangeEquals(other) + public override bool EquivalentTo(ControlPoint other) + => base.EquivalentTo(other) && other is LegacySampleControlPoint legacy && CustomSampleBank == legacy.CustomSampleBank; } From 1d6609d9f3688ddfd5ee76818db001fb5877225d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Jul 2018 11:32:09 +0900 Subject: [PATCH 148/190] Add common custom words to dotsettings dictionary Also fixes some typos and reduces spelling suggestions to hints. --- osu.Desktop/Program.cs | 4 +-- .../TestCaseCatcherArea.cs | 2 +- ...tCaseHyperdash.cs => TestCaseHyperDash.cs} | 4 +-- .../Difficulty/CatchDifficultyCalculator.cs | 4 +-- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 26 +++++++++---------- .../Legacy/EndTimeObjectPatternGenerator.cs | 4 +-- .../OsuBeatmapConversionTest.cs | 2 +- .../Difficulty/OsuDifficultyCalculator.cs | 8 +++--- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 4 +-- .../Connections/FollowPointRenderer.cs | 8 +++--- .../Objects/Drawables/DrawableHitCircle.cs | 2 +- .../Objects/Drawables/DrawableOsuHitObject.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../Objects/Drawables/Pieces/SliderBody.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 4 +-- osu.Game.Rulesets.Osu/Objects/SliderTick.cs | 2 +- .../Visual/TestCaseBeatmapInfoWedge.cs | 6 ++--- osu.Game.Tests/Visual/TestCaseMods.cs | 4 +-- osu.Game/Graphics/SpriteIcon.cs | 1 + osu.sln.DotSettings | 23 +++++++++++++++- 20 files changed, 67 insertions(+), 47 deletions(-) rename osu.Game.Rulesets.Catch.Tests/{TestCaseHyperdash.cs => TestCaseHyperDash.cs} (88%) diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index 61d2006315..780a9994fd 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -21,7 +21,7 @@ namespace osu.Desktop // required to initialise native SQLite libraries on some platforms. if (!RuntimeInfo.IsMono) - useMulticoreJit(); + useMultiCoreJit(); // Back up the cwd before DesktopGameHost changes it var cwd = Environment.CurrentDirectory; @@ -54,7 +54,7 @@ namespace osu.Desktop } } - private static void useMulticoreJit() + private static void useMultiCoreJit() { #if NET_FRAMEWORK var directory = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Profiles")); diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs index 0ba6398ced..25f7ca108d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Tests { } - public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperdashState(status ? 2 : 1); + public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperDashState(status ? 2 : 1); } } } diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperDash.cs similarity index 88% rename from osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs rename to osu.Game.Rulesets.Catch.Tests/TestCaseHyperDash.cs index 896582bf0a..14487b2c7f 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperDash.cs @@ -8,9 +8,9 @@ using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer + public class TestCaseHyperDash : Game.Tests.Visual.TestCasePlayer { - public TestCaseHyperdash() + public TestCaseHyperDash() : base(new CatchRuleset()) { } diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index 3d1013aad3..31c56c37c4 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -61,12 +61,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty return new CatchDifficultyAttributes(mods, 0); // this is the same as osu!, so there's potential to share the implementation... maybe - double preEmpt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate; + double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate; double starRating = Math.Sqrt(calculateDifficulty(difficultyHitObjects, timeRate)) * star_scaling_factor; return new CatchDifficultyAttributes(mods, starRating) { - ApproachRate = preEmpt > 1200.0 ? -(preEmpt - 1800.0) / 120.0 : -(preEmpt - 1200.0) / 150.0 + 5.0, + ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0, MaxCombo = difficultyHitObjects.Count }; } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 9c376f340a..2f42902fd0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -255,11 +255,11 @@ namespace osu.Game.Rulesets.Catch.UI double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition; double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0); - SetHyperdashState(Math.Abs(velocity), target.X); + SetHyperDashState(Math.Abs(velocity), target.X); } else { - SetHyperdashState(); + SetHyperDashState(); } return validCatch; @@ -270,18 +270,18 @@ namespace osu.Game.Rulesets.Catch.UI private float hyperDashTargetPosition; /// - /// Whether we are hypderdashing or not. + /// Whether we are hyper-dashing or not. /// public bool HyperDashing => hyperDashModifier != 1; /// - /// Set hyperdash state. + /// Set hyper-dash state. /// - /// The speed multiplier. If this is less or equals to 1, this catcher will be non-hyperdashing state. - /// When this catcher crosses this position, this catcher ends hyperdashing. - public void SetHyperdashState(double modifier = 1, float targetPosition = -1) + /// The speed multiplier. If this is less or equals to 1, this catcher will be non-hyper-dashing state. + /// When this catcher crosses this position, this catcher ends hyper-dashing. + public void SetHyperDashState(double modifier = 1, float targetPosition = -1) { - const float hyperdash_transition_length = 180; + const float hyper_dash_transition_length = 180; bool previouslyHyperDashing = HyperDashing; if (modifier <= 1 || X == targetPosition) @@ -291,8 +291,8 @@ namespace osu.Game.Rulesets.Catch.UI if (previouslyHyperDashing) { - this.FadeColour(Color4.White, hyperdash_transition_length, Easing.OutQuint); - this.FadeTo(1, hyperdash_transition_length, Easing.OutQuint); + this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint); + this.FadeTo(1, hyper_dash_transition_length, Easing.OutQuint); } } else @@ -303,8 +303,8 @@ namespace osu.Game.Rulesets.Catch.UI if (!previouslyHyperDashing) { - this.FadeColour(Color4.OrangeRed, hyperdash_transition_length, Easing.OutQuint); - this.FadeTo(0.2f, hyperdash_transition_length, Easing.OutQuint); + this.FadeColour(Color4.OrangeRed, hyper_dash_transition_length, Easing.OutQuint); + this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint); Trail = true; } } @@ -370,7 +370,7 @@ namespace osu.Game.Rulesets.Catch.UI hyperDashDirection < 0 && hyperDashTargetPosition > X) { X = hyperDashTargetPosition; - SetHyperdashState(); + SetHyperDashState(); } } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 3f34afee85..01b2b1e68e 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -19,9 +19,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, new Pattern(), originalBeatmap) { - var endtimeData = HitObject as IHasEndTime; - - endTime = endtimeData?.EndTime ?? 0; + endTime = (HitObject as IHasEndTime)?.EndTime ?? 0; } public override Pattern Generate() diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 3fa039d946..3a551bbbcf 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.Tests public struct ConvertValue : IEquatable { /// - /// A sane value to account for osu!stable using ints everwhere. + /// A sane value to account for osu!stable using s everywhere. /// private const double conversion_lenience = 2; diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 62fafd8196..5e91ed7a97 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -61,19 +61,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; - // Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future + // Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be removed in the future double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / timeRate; - double preEmpt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate; + double preempt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate; int maxCombo = beatmap.HitObjects.Count(); - // Add the ticks + tail of the slider. 1 is subtracted because the "headcircle" would be counted twice (once for the slider itself in the line above) + // Add the ticks + tail of the slider. 1 is subtracted because the head circle would be counted twice (once for the slider itself in the line above) maxCombo += beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count - 1); return new OsuDifficultyAttributes(mods, starRating) { AimStrain = aimRating, SpeedStrain = speedRating, - ApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5, + ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5, OverallDifficulty = (80 - hitWindowGreat) / 6, MaxCombo = maxCombo }; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 4220b72b16..4eff2a55c8 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override void ApplyToDrawableHitObjects(IEnumerable drawables) { - void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + void adjustFadeIn(OsuHitObject h) => h.TimeFadeIn = h.TimePreempt * fade_in_duration_multiplier; foreach (var d in drawables.OfType()) { @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods var h = d.HitObject; - var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadein; + var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadeIn; var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier; // new duration from completed fade in to end (before fading out) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs index 4653f45149..4ac3b0c983 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs @@ -96,12 +96,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections using (fp.BeginAbsoluteSequence(fadeInTime)) { - fp.FadeIn(currHitObject.TimeFadein); - fp.ScaleTo(1, currHitObject.TimeFadein, Easing.Out); + fp.FadeIn(currHitObject.TimeFadeIn); + fp.ScaleTo(1, currHitObject.TimeFadeIn, Easing.Out); - fp.MoveTo(pointEndPosition, currHitObject.TimeFadein, Easing.Out); + fp.MoveTo(pointEndPosition, currHitObject.TimeFadeIn, Easing.Out); - fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadein); + fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadeIn); } fp.Expire(true); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 421c93d485..c525b4bd97 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdatePreemptState(); - ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadein * 2, HitObject.TimePreempt)); + ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt)); ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 7c9503dfe2..02def2189f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AccentColour = skin.GetValue(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White; } - protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadein); + protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn); protected virtual void UpdateCurrentState(ArmedState state) { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 10539f85a2..1d3df69fb8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); if (!spmCounter.IsPresent && Disc.Tracking) - spmCounter.FadeIn(HitObject.TimeFadein); + spmCounter.FadeIn(HitObject.TimeFadeIn); base.Update(); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index 94a61e7904..283d6b91f6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -212,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var spanProgress = slider.ProgressAt(completionProgress); double start = 0; - double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadein, 0, 1) : 1; + double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadeIn, 0, 1) : 1; if (span >= slider.SpanCount() - 1) { diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index befbc01f3c..48a6365c00 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects public event Action PositionChanged; public double TimePreempt = 600; - public double TimeFadein = 400; + public double TimeFadeIn = 400; private Vector2 position; @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects base.ApplyDefaultsToSelf(controlPointInfo, difficulty); TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); - TimeFadein = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300); + TimeFadeIn = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300); Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs index 4db6eb9883..54337a12be 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects // This is so on repeats ticks don't appear too late to be visually processed by the player. offset = 200; else - offset = TimeFadein * 0.66f; + offset = TimeFadeIn * 0.66f; TimePreempt = (StartTime - SpanStartTime) / 2 + offset; } diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index ee66f53ddc..b232180eba 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -110,8 +110,8 @@ namespace osu.Game.Tests.Visual private void testInfoLabels(int expectedCount) { - AddAssert("check infolabels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any()); - AddAssert("check infolabels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount); + AddAssert("check info labels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any()); + AddAssert("check info labels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount); } private void testNullBeatmap() @@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Title); AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Artist); AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); - AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); + AddAssert("check no info labels", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); } private void selectBeatmap(IBeatmap b) diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs index 73c37348d5..1a28442e38 100644 --- a/osu.Game.Tests/Visual/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/TestCaseMods.cs @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour); testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour); - testUnimplmentedMod(autoPilotMod); + testUnimplementedMod(autoPilotMod); } private void testManiaMods(ManiaRuleset ruleset) @@ -154,7 +154,7 @@ namespace osu.Game.Tests.Visual checkNotSelected(mod); } - private void testUnimplmentedMod(Mod mod) + private void testUnimplementedMod(Mod mod) { selectNext(mod); checkNotSelected(mod); diff --git a/osu.Game/Graphics/SpriteIcon.cs b/osu.Game/Graphics/SpriteIcon.cs index 6acd20719e..45c4cebfcf 100644 --- a/osu.Game/Graphics/SpriteIcon.cs +++ b/osu.Game/Graphics/SpriteIcon.cs @@ -10,6 +10,7 @@ using osu.Framework.IO.Stores; using OpenTK; using OpenTK.Graphics; using osu.Framework.Caching; +// ReSharper disable IdentifierTypo namespace osu.Game.Graphics { diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 0b631d008b..1f1b6a79b1 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -23,6 +23,7 @@ HINT SUGGESTION HINT + HINT HINT WARNING WARNING @@ -43,6 +44,7 @@ DO_NOT_SHOW WARNING WARNING + HINT HINT ERROR HINT @@ -133,6 +135,7 @@ WARNING WARNING WARNING + HINT DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW @@ -666,4 +669,22 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste True True True - True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True From bbceac6cdaa93a215899cd6b137b1f61053152d8 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 5 Jul 2018 16:50:04 +0900 Subject: [PATCH 149/190] Apply renaming of wheel -> scroll --- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Volume/VolumeControlReceptor.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index bc680193bc..49c774a5a0 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -248,7 +248,7 @@ namespace osu.Game { RelativeSizeAxes = Axes.Both, ActionRequested = action => volume.Adjust(action), - WheelActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise), + ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise), }, mainContent = new Container { RelativeSizeAxes = Axes.Both }, overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue }, diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index bb9aadb888..3a64e12b27 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -9,13 +9,13 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Volume { - public class VolumeControlReceptor : Container, IMouseWheelBindingHandler, IHandleGlobalInput + public class VolumeControlReceptor : Container, IScrollBindingHandler, IHandleGlobalInput { public Func ActionRequested; - public Func WheelActionRequested; + public Func ScrollActionRequested; public bool OnPressed(GlobalAction action) => ActionRequested?.Invoke(action) ?? false; - public bool OnMouseWheel(GlobalAction action, float amount, bool isPrecise) => WheelActionRequested?.Invoke(action, amount, isPrecise) ?? false; + public bool OnScroll(GlobalAction action, float amount, bool isPrecise) => ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false; public bool OnReleased(GlobalAction action) => false; } } From 7328121ef5ab766f6ce75c35cc8b788b5199a07e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Jul 2018 19:29:49 +0900 Subject: [PATCH 150/190] Remove LD_PRELOAD as it is now unnecessary --- .vscode/launch.json | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 2c781363af..12bb5b7734 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,9 +13,8 @@ "preLaunchTask": "Build tests (Debug)", "linux": { "env": { - "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/libbass.so", - "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/", - }, + "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}" + } }, "console": "internalConsole" }, @@ -31,9 +30,8 @@ "preLaunchTask": "Build tests (Release)", "linux": { "env": { - "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/libbass.so", - "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/", - }, + "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}" + } }, "console": "internalConsole" }, @@ -49,9 +47,8 @@ "preLaunchTask": "Build osu! (Debug)", "linux": { "env": { - "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/libbass.so", - "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/", - }, + "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}" + } }, "console": "internalConsole" }, @@ -67,9 +64,8 @@ "preLaunchTask": "Build osu! (Release)", "linux": { "env": { - "LD_PRELOAD": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/libbass.so", - "LD_LIBRARY_PATH" : "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/", - }, + "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}" + } }, "console": "internalConsole" } From 8f04acc506bf5ae4474897f0f420d43583e4fcee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Jul 2018 20:16:55 +0900 Subject: [PATCH 151/190] Add missing xmldoc --- osu.Game/Audio/SampleInfo.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 3d76184e09..7e329ac651 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -34,6 +34,9 @@ namespace osu.Game.Audio /// public int Volume; + /// + /// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first). + /// public virtual IEnumerable LookupNames { get From 625b9ead4c1eec712824d59b91bf7cd00479cb3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Jul 2018 21:00:23 +0900 Subject: [PATCH 152/190] Fix links from profile top scores to beatmaps not working correctly --- osu.Game/Beatmaps/BeatmapMetadata.cs | 1 - osu.Game/Online/API/Requests/Responses/APIScore.cs | 9 ++++++++- .../Profile/Sections/BeatmapMetadataContainer.cs | 6 +++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index 6c1bcd0531..57983ec568 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -14,7 +14,6 @@ namespace osu.Game.Beatmaps public class BeatmapMetadata : IEquatable { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - [JsonIgnore] public int ID { get; set; } public string Title { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIScore.cs b/osu.Game/Online/API/Requests/Responses/APIScore.cs index a398bf46ee..25eb32a79f 100644 --- a/osu.Game/Online/API/Requests/Responses/APIScore.cs +++ b/osu.Game/Online/API/Requests/Responses/APIScore.cs @@ -63,7 +63,14 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"beatmapset")] private BeatmapMetadata metadata { - set => Beatmap.Metadata = value; + set + { + // extract the set ID to its correct place. + Beatmap.BeatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = value.ID }; + value.ID = 0; + + Beatmap.Metadata = value; + } } [JsonProperty(@"statistics")] diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 359bfc7564..eaa0ac4aaa 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -9,6 +9,7 @@ using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; + namespace osu.Game.Overlays.Profile.Sections { /// @@ -32,7 +33,10 @@ namespace osu.Game.Overlays.Profile.Sections { Action = () => { - if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value); + if (beatmap.OnlineBeatmapID != null) + beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.OnlineBeatmapID.Value); + else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) + beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value); }; Child = new FillFlowContainer From 7e28a993f7e0e86132d91f1cbc310518e6bcd76f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Jul 2018 21:08:53 +0900 Subject: [PATCH 153/190] Update framework --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 56c33c47af..da55726447 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 7a091083871223584a659bd0986eb1f90bc1e124 Mon Sep 17 00:00:00 2001 From: John Neijzen Date: Thu, 5 Jul 2018 22:38:34 +0800 Subject: [PATCH 154/190] Remove extra , make this valid JSON file --- .vscode/launch.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 12bb5b7734..e9b8d6f397 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -41,7 +41,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll", + "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Debug)", @@ -58,7 +58,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll", + "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Release)", @@ -70,4 +70,4 @@ "console": "internalConsole" } ] -} \ No newline at end of file +} From a1d2092cc9ab5cfa0537d1f80aa9a09373d16920 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Fri, 6 Jul 2018 13:29:40 +0900 Subject: [PATCH 155/190] Fix incorrect default drain time --- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 8ef942c683..55081e5822 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy int drainTime = (int)(((lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0) - OriginalBeatmap.TotalBreakTime) / 1000); if (drainTime == 0) - drainTime = 100000; + drainTime = 10000; BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty; conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + (double)OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15; From b8d314a809c7b39a20d97a35373181954fdbddf9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jul 2018 16:39:27 +0900 Subject: [PATCH 156/190] Tidy up updater namespace --- osu.Desktop/OsuGameDesktop.cs | 85 ++++++++++--------- osu.Desktop/Overlays/VersionManager.cs | 4 - .../SquirrelUpdateManager.cs | 5 +- 3 files changed, 48 insertions(+), 46 deletions(-) rename osu.Desktop/{Overlays => Updater}/SquirrelUpdateManager.cs (97%) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 64adcecba4..d27bd70cda 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -12,6 +12,7 @@ using osu.Framework.Platform; using osu.Game; using OpenTK.Input; using Microsoft.Win32; +using osu.Desktop.Updater; using osu.Framework.Platform.Windows; namespace osu.Desktop @@ -38,6 +39,50 @@ namespace osu.Desktop } } + protected override void LoadComplete() + { + base.LoadComplete(); + + if (!noVersionOverlay) + { + LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v => + { + Add(v); + v.State = Visibility.Visible; + }); + +#if NET_FRAMEWORK + Add(new SquirrelUpdateManager()); +#endif + } + } + + public override void SetHost(GameHost host) + { + base.SetHost(host); + var desktopWindow = host.Window as DesktopGameWindow; + if (desktopWindow != null) + { + desktopWindow.CursorState |= CursorState.Hidden; + + desktopWindow.SetIconFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico")); + desktopWindow.Title = Name; + + desktopWindow.FileDrop += fileDrop; + } + } + + private void fileDrop(object sender, FileDropEventArgs e) + { + var filePaths = new[] { e.FileName }; + + var firstExtension = Path.GetExtension(filePaths.First()); + + if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return; + + Task.Factory.StartNew(() => Import(filePaths), TaskCreationOptions.LongRunning); + } + /// /// A method of accessing an osu-stable install in a controlled fashion. /// @@ -77,45 +122,5 @@ namespace osu.Desktop { } } - - protected override void LoadComplete() - { - base.LoadComplete(); - - if (!noVersionOverlay) - { - LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v => - { - Add(v); - v.State = Visibility.Visible; - }); - } - } - - public override void SetHost(GameHost host) - { - base.SetHost(host); - var desktopWindow = host.Window as DesktopGameWindow; - if (desktopWindow != null) - { - desktopWindow.CursorState |= CursorState.Hidden; - - desktopWindow.SetIconFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico")); - desktopWindow.Title = Name; - - desktopWindow.FileDrop += fileDrop; - } - } - - private void fileDrop(object sender, FileDropEventArgs e) - { - var filePaths = new[] { e.FileName }; - - var firstExtension = Path.GetExtension(filePaths.First()); - - if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return; - - Task.Factory.StartNew(() => Import(filePaths), TaskCreationOptions.LongRunning); - } } } diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index bc1faec822..1129969694 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -91,10 +91,6 @@ namespace osu.Desktop.Overlays } } }; - -#if NET_FRAMEWORK - Add(new SquirrelUpdateManager()); -#endif } protected override void LoadComplete() diff --git a/osu.Desktop/Overlays/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs similarity index 97% rename from osu.Desktop/Overlays/SquirrelUpdateManager.cs rename to osu.Desktop/Updater/SquirrelUpdateManager.cs index ea86d2f028..81da26cff2 100644 --- a/osu.Desktop/Overlays/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -3,6 +3,7 @@ #if NET_FRAMEWORK using System; +using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -16,7 +17,7 @@ using OpenTK; using OpenTK.Graphics; using Squirrel; -namespace osu.Desktop.Overlays +namespace osu.Desktop.Updater { public class SquirrelUpdateManager : Component { @@ -35,7 +36,7 @@ namespace osu.Desktop.Overlays notificationOverlay = notification; if (game.IsDeployedBuild) - Schedule(() => checkForUpdateAsync()); + Schedule(() => Task.Run(() => checkForUpdateAsync())); } private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) From 7120408a634ef1b272a7dde57e190b74707a9a8b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jul 2018 16:39:42 +0900 Subject: [PATCH 157/190] Add fallback "updater", which prompts the user to update --- osu.Desktop/OsuGameDesktop.cs | 2 + osu.Desktop/Updater/SimpleUpdateManager.cs | 103 +++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 osu.Desktop/Updater/SimpleUpdateManager.cs diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index d27bd70cda..a4270f22b4 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -53,6 +53,8 @@ namespace osu.Desktop #if NET_FRAMEWORK Add(new SquirrelUpdateManager()); +#else + Add(new SimpleUpdateManager()); #endif } } diff --git a/osu.Desktop/Updater/SimpleUpdateManager.cs b/osu.Desktop/Updater/SimpleUpdateManager.cs new file mode 100644 index 0000000000..cda8e6a7ca --- /dev/null +++ b/osu.Desktop/Updater/SimpleUpdateManager.cs @@ -0,0 +1,103 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json; +using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.IO.Network; +using osu.Framework.Platform; +using osu.Game; +using osu.Game.Graphics; +using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; + +namespace osu.Desktop.Updater +{ + /// + /// An update manager that shows notifications if a newer release is detected. + /// Installation is left up to the user. + /// + internal class SimpleUpdateManager : CompositeDrawable + { + private NotificationOverlay notificationOverlay; + private string version; + private GameHost host; + + [BackgroundDependencyLoader] + private void load(NotificationOverlay notification, OsuGameBase game, GameHost host) + { + notificationOverlay = notification; + + this.host = host; + version = game.Version; + + if (game.IsDeployedBuild) + Schedule(() => Task.Run(() => checkForUpdateAsync())); + } + + private async void checkForUpdateAsync() + { + var releases = new JsonWebRequest("https://api.github.com/repos/ppy/osu/releases/latest"); + await releases.PerformAsync(); + + var latest = releases.ResponseObject; + + if (latest.TagName != version) + { + notificationOverlay.Post(new SimpleNotification + { + Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n" + + "Click here to download the new version, which can be installed over the top of your existing installation", + Icon = FontAwesome.fa_upload, + Activated = () => + { + host.OpenUrlExternally(getBestUrl(latest)); + return true; + } + }); + } + } + + private string getBestUrl(GitHubRelease release) + { + GitHubAsset bestAsset = null; + + switch (RuntimeInfo.OS) + { + case RuntimeInfo.Platform.Windows: + bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".exe")); + break; + case RuntimeInfo.Platform.MacOsx: + bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".dmg")); + break; + } + + return bestAsset?.BrowserDownloadUrl ?? release.HtmlUrl; + } + + public class GitHubRelease + { + [JsonProperty("html_url")] + public string HtmlUrl { get; set; } + + [JsonProperty("tag_name")] + public string TagName { get; set; } + + [JsonProperty("assets")] + public List Assets { get; set; } + } + + public class GitHubAsset + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("browser_download_url")] + public string BrowserDownloadUrl { get; set; } + } + } +} From 54db2877918186d1ddff1cd568312e3353734504 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jul 2018 17:45:39 +0900 Subject: [PATCH 158/190] Remove casting --- osu.Game/Graphics/Cursor/MenuCursor.cs | 32 ++++++++++++++------------ 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 14a976f0c0..517be4c055 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -22,7 +22,9 @@ namespace osu.Game.Graphics.Cursor private readonly IBindable screenshotCursorVisibility = new Bindable(true); public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent; - protected override Drawable CreateCursor() => new Cursor(); + protected override Drawable CreateCursor() => activeCursor = new Cursor(); + + private Cursor activeCursor; private Bindable cursorRotate; private DragRotationState dragRotationState; @@ -54,12 +56,12 @@ namespace osu.Game.Graphics.Cursor float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f; // Always rotate in the direction of least distance - float diff = (degrees - ActiveCursor.Rotation) % 360; + float diff = (degrees - activeCursor.Rotation) % 360; if (diff < -180) diff += 360; if (diff > 180) diff -= 360; - degrees = ActiveCursor.Rotation + diff; + degrees = activeCursor.Rotation + diff; - ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint); + activeCursor.RotateTo(degrees, 600, Easing.OutQuint); } } @@ -71,11 +73,11 @@ namespace osu.Game.Graphics.Cursor // only trigger animation for main mouse buttons if (args.Button <= MouseButton.Right) { - ActiveCursor.Scale = new Vector2(1); - ActiveCursor.ScaleTo(0.90f, 800, Easing.OutQuint); + activeCursor.Scale = new Vector2(1); + activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint); - ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; - ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); + activeCursor.AdditiveLayer.Alpha = 0; + activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint); } if (args.Button == MouseButton.Left && cursorRotate) @@ -90,14 +92,14 @@ namespace osu.Game.Graphics.Cursor { if (!state.Mouse.HasMainButtonPressed) { - ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint); - ActiveCursor.ScaleTo(1, 500, Easing.OutElastic); + activeCursor.AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint); + activeCursor.ScaleTo(1, 500, Easing.OutElastic); } if (args.Button == MouseButton.Left) { if (dragRotationState == DragRotationState.Rotating) - ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); + activeCursor.RotateTo(0, 600 * (1 + Math.Abs(activeCursor.Rotation / 720)), Easing.OutElasticHalf); dragRotationState = DragRotationState.NotDragging; } return base.OnMouseUp(state, args); @@ -105,14 +107,14 @@ namespace osu.Game.Graphics.Cursor protected override void PopIn() { - ActiveCursor.FadeTo(1, 250, Easing.OutQuint); - ActiveCursor.ScaleTo(1, 400, Easing.OutQuint); + activeCursor.FadeTo(1, 250, Easing.OutQuint); + activeCursor.ScaleTo(1, 400, Easing.OutQuint); } protected override void PopOut() { - ActiveCursor.FadeTo(0, 250, Easing.OutQuint); - ActiveCursor.ScaleTo(0.6f, 250, Easing.In); + activeCursor.FadeTo(0, 250, Easing.OutQuint); + activeCursor.ScaleTo(0.6f, 250, Easing.In); } public class Cursor : Container From c025158735b96c275d8d31b13c27305c1ba3a271 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jul 2018 17:53:01 +0900 Subject: [PATCH 159/190] Give VisibleState a default rather than nullable --- osu.Game/Screens/Menu/Button.cs | 4 ++-- osu.Game/Screens/Menu/ButtonSystem.cs | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index f862905b5e..29820f234d 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Menu /// /// The menu state for which we are visible for. /// - public ButtonSystemState? VisibleState; + public ButtonSystemState VisibleState = ButtonSystemState.TopLevel; private readonly Action clickAction; private readonly Key triggerKey; @@ -300,7 +300,7 @@ namespace osu.Game.Screens.Menu State = ButtonState.Contracted; break; default: - if (!VisibleState.HasValue || value == VisibleState) + if (value == VisibleState) State = ButtonState.Expanded; else if (value < VisibleState) State = ButtonState.Contracted; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 4f2437cf01..1a0cd4fa5b 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -73,10 +73,7 @@ namespace osu.Game.Screens.Menu buttonArea.AddRange(new[] { - new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O) - { - VisibleState = ButtonSystemState.TopLevel, - }, + new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O), backButton = new Button(@"back", @"button-back-select", FontAwesome.fa_osu_left_o, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH) { VisibleState = ButtonSystemState.Play, @@ -98,7 +95,6 @@ namespace osu.Game.Screens.Menu buttonsTopLevel.Add(new Button(@"osu!editor", @"button-generic-select", FontAwesome.fa_osu_edit_o, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E)); buttonsTopLevel.Add(new Button(@"osu!direct", @"button-direct-select", FontAwesome.fa_osu_chevron_down_o, new Color4(165, 204, 0, 255), () => OnDirect?.Invoke(), 0, Key.D)); buttonsTopLevel.Add(new Button(@"exit", string.Empty, FontAwesome.fa_osu_cross_o, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q)); - buttonsTopLevel.ForEach(b => b.VisibleState = ButtonSystemState.TopLevel); buttonArea.AddRange(buttonsPlay); buttonArea.AddRange(buttonsTopLevel); From f92a90c098002fd4ea63052e3ca681944ffcfa64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 8 Jul 2018 02:03:42 +0900 Subject: [PATCH 160/190] Update README.md --- README.md | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9d19f16ebd..c270da198f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,32 @@ # osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu) [![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy) -Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! +Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Commonly known by the codename "osu!lazer". Pew pew. # Status -This is still heavily under development and is not intended for end-user use. This repository is intended for developer collaboration. You're welcome to try and use it but please do not submit bug reports without a patch. Please do not ask for help building or using this software. +This project is still heavily under development, but is in a state where users are encouraged to try it out and keep it installed alongside the stable osu! client. It will continue to evolve over the coming months and hopefully bring some new unique features to the table. + +We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below. # Requirements -- A desktop platform that can compile .NET 4.7.1. We recommend using [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio for Mac](https://www.visualstudio.com/vs/visual-studio-mac/) (macOS) or [MonoDevelop](http://www.monodevelop.com/download/) (Linux), all of which are free. [Visual Studio Code](https://code.visualstudio.com/) may also be used but requires further setup steps which are not covered here. +- A desktop platform with the [.NET Core SDK 2.1](https://www.microsoft.com/net/learn/get-started) or higher installed. +- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial). -# Getting Started -- Clone the repository including submodules (`git clone --recurse-submodules https://github.com/ppy/osu`) -- Build in your IDE of choice (recommended IDEs automatically restore nuget packages; if you are using an alternative make sure to `nuget restore`) +# Building and running + +If you are not interested in developing the game, please head over to the [releases](https://github.com/ppy/osu/releases) to download a precompiled build with automatic updating enabled (download and run the install executable for your platform). + +Clone the repository including submodules + +`git clone --recurse-submodules https://github.com/ppy/osu` + +Build and run + +- Using Visual Studio 2017, Rider or Visual Studio Code (configurations are included) +- From command line using `dotnet run --project osu.Desktop --framework netcoreapp2.1` + +The above methods should automatically do so, but if you run into issues building you may need to `nuget restore`. # Contributing From 27311ce1fcfaa228cb3675d04361a92db6b38792 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 8 Jul 2018 11:21:18 +0900 Subject: [PATCH 161/190] Update nuget restore instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c270da198f..fd0ba838cc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Build and run - Using Visual Studio 2017, Rider or Visual Studio Code (configurations are included) - From command line using `dotnet run --project osu.Desktop --framework netcoreapp2.1` -The above methods should automatically do so, but if you run into issues building you may need to `nuget restore`. +The above methods should automatically do so, but if you run into issues building you may need to restore nuget packages (commonly via `dotnet restore`). # Contributing From e223074876d09c8897a8aa4af88f01a6446d157b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jul 2018 00:24:55 +0900 Subject: [PATCH 162/190] Fix import failures if single set has multiple conflicting OnlineBeatmapIDs Resolves #2970. --- osu.Game/Beatmaps/BeatmapManager.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e488dacf80..fd24e4297b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -339,6 +339,8 @@ namespace osu.Game.Beatmaps { var beatmapInfos = new List(); + bool invalidateOnlineIDs = false; + foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu"))) { using (var raw = reader.GetStream(name)) @@ -355,9 +357,18 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash(); beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash(); - // check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence. - if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null) - beatmap.BeatmapInfo.OnlineBeatmapID = null; + if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue) + { + var ourId = beatmap.BeatmapInfo.OnlineBeatmapID; + + // check that no existing beatmap in database exists that is imported with the same online beatmap ID. if so, give it precedence. + if (QueryBeatmap(b => b.OnlineBeatmapID.Value == ourId) != null) + beatmap.BeatmapInfo.OnlineBeatmapID = null; + + // check that no other beatmap in this imported set has a conflicting online beatmap ID. If so, presume *all* are incorrect. + if (beatmapInfos.Any(b => b.OnlineBeatmapID == ourId)) + invalidateOnlineIDs = true; + } RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID); @@ -375,6 +386,9 @@ namespace osu.Game.Beatmaps } } + if (invalidateOnlineIDs) + beatmapInfos.ForEach(b => b.OnlineBeatmapID = null); + return beatmapInfos; } From b20afb915db429e0e3c2463d88e19d98c52e9684 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jul 2018 15:26:22 +0900 Subject: [PATCH 163/190] Fix right mouse activated absolute scroll not working --- osu.Game/OsuGameBase.cs | 30 ++++++++++++++++++++++++++++++ osu.Game/osu.Game.csproj | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 246229a794..c1d5ae581e 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics.Cursor; using osu.Game.Online.API; using osu.Framework.Graphics.Performance; using osu.Framework.Graphics.Textures; +using osu.Framework.Input; using osu.Framework.Logging; using osu.Game.Audio; using osu.Game.Database; @@ -30,6 +31,7 @@ using osu.Game.IO; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; +using OpenTK.Input; using DebugUtils = osu.Game.Utils.DebugUtils; namespace osu.Game @@ -98,6 +100,8 @@ namespace osu.Game private DatabaseContextFactory contextFactory; + protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager(); + [BackgroundDependencyLoader] private void load() { @@ -267,5 +271,31 @@ namespace osu.Game return copy; } } + + private class OsuUserInputManager : UserInputManager + { + protected override MouseButtonEventManager CreateButtonManagerFor(MouseButton button) + { + switch (button) + { + case MouseButton.Right: + return new RightMouseManager(button); + } + + return base.CreateButtonManagerFor(button); + } + + private class RightMouseManager : MouseButtonEventManager + { + public RightMouseManager(MouseButton button) + : base(button) + { + } + + public override bool EnableDrag => true; // allow right-mouse dragging for absolute scroll in scroll containers. + public override bool EnableClick => false; + public override bool ChangeFocusOnClick => false; + } + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index da55726447..cac3459412 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 0a67e5a274676b0bbb7146ce9c4b1fda24ec7c49 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Jul 2018 17:09:17 +0900 Subject: [PATCH 164/190] Fix some possible null reference exceptions --- osu.Game/Screens/Select/Leaderboards/DrawableRank.cs | 4 +++- osu.Game/Users/Country.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/DrawableRank.cs b/osu.Game/Screens/Select/Leaderboards/DrawableRank.cs index 2a11bf8346..228633a41f 100644 --- a/osu.Game/Screens/Select/Leaderboards/DrawableRank.cs +++ b/osu.Game/Screens/Select/Leaderboards/DrawableRank.cs @@ -46,7 +46,9 @@ namespace osu.Game.Screens.Select.Leaderboards public void UpdateRank(ScoreRank newRank) { Rank = newRank; - updateTexture(); + + if (IsLoaded) + updateTexture(); } } } diff --git a/osu.Game/Users/Country.cs b/osu.Game/Users/Country.cs index c9b577a62f..98b3a2df0c 100644 --- a/osu.Game/Users/Country.cs +++ b/osu.Game/Users/Country.cs @@ -42,7 +42,9 @@ namespace osu.Game.Users return; country = value; - sprite.Texture = getFlagTexture(); + + if (IsLoaded) + sprite.Texture = getFlagTexture(); } } From 930667d0f9046ac16bae01598a7262a4236adf2b Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Mon, 9 Jul 2018 10:12:10 +0200 Subject: [PATCH 165/190] Remove unused age display code --- osu.Game/Overlays/Profile/ProfileHeader.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index c72ff6131b..c5510d3d70 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -360,11 +360,6 @@ namespace osu.Game.Overlays.Profile Text = text }; - if (user.Age != null) - { - infoTextLeft.AddText($"{user.Age} years old ", boldItalic); - } - if (user.Country != null) { infoTextLeft.AddText("From ", lightText); From 10aae3b0eead50a05be15cfb2e218ffc9a5ac4be Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Mon, 9 Jul 2018 10:33:46 +0200 Subject: [PATCH 166/190] Remove age from User class --- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 1 - osu.Game/Users/User.cs | 3 --- 2 files changed, 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index aca832110a..cb281d045b 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -53,7 +53,6 @@ namespace osu.Game.Tests.Visual CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", JoinDate = DateTimeOffset.Now.AddDays(-1), LastVisit = DateTimeOffset.Now, - Age = 1, ProfileOrder = new[] { "me" }, Statistics = new UserStatistics { diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index e1f68e1ce8..f42df4023f 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -23,9 +23,6 @@ namespace osu.Game.Users public Bindable Status = new Bindable(); - [JsonProperty(@"age")] - public int? Age; - //public Team Team; [JsonProperty(@"profile_colour")] From df67c0498de51314d30cdbeeeb4741bc92c7f302 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jul 2018 17:53:39 +0900 Subject: [PATCH 167/190] Fix OSD fade-in not correctly debouncing It could potentially never fade in on quick presses. --- .../Visual/TestCaseOnScreenDisplay.cs | 2 +- osu.Game/Overlays/OnScreenDisplay.cs | 38 +++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs b/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs index 123c1fe055..bc232d814d 100644 --- a/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual private class TestOnScreenDisplay : OnScreenDisplay { - protected override void Display(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110); + protected override void DisplayTemporarily(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110); } } } diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 1c80f2e626..753cd33cc6 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -14,6 +14,8 @@ using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Threading; using osu.Game.Configuration; using osu.Game.Graphics.Sprites; @@ -135,7 +137,7 @@ namespace osu.Game.Overlays /// If is already being tracked from the same . public void BeginTracking(object source, ITrackableConfigManager configManager) { - if (configManager == null) throw new ArgumentNullException(nameof(configManager)); + if (configManager == null) throw new ArgumentNullException(nameof(configManager)); if (trackedConfigManagers.ContainsKey((source, configManager))) throw new InvalidOperationException($"{nameof(configManager)} is already registered."); @@ -159,7 +161,7 @@ namespace osu.Game.Overlays /// If is not being tracked from the same . public void StopTracking(object source, ITrackableConfigManager configManager) { - if (configManager == null) throw new ArgumentNullException(nameof(configManager)); + if (configManager == null) throw new ArgumentNullException(nameof(configManager)); if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing)) throw new InvalidOperationException($"{nameof(configManager)} is not registered."); @@ -181,7 +183,7 @@ namespace osu.Game.Overlays if (string.IsNullOrEmpty(textLine3.Text)) textLine3.Text = "NO KEY BOUND"; - Display(box); + DisplayTemporarily(box); int optionCount = 0; int selectedOption = -1; @@ -213,15 +215,29 @@ namespace osu.Game.Overlays }); } - protected virtual void Display(Drawable toDisplay) + private TransformSequence fadeIn; + private ScheduledDelegate fadeOut; + + protected virtual void DisplayTemporarily(Drawable toDisplay) { - toDisplay.Animate( - b => b.FadeIn(500, Easing.OutQuint), - b => b.ResizeHeightTo(height, 500, Easing.OutQuint) - ).Then( - b => b.FadeOutFromOne(1500, Easing.InQuint), - b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint) - ); + // avoid starting a new fade-in if one is already active. + if (fadeIn == null) + { + fadeIn = toDisplay.Animate( + b => b.FadeIn(500, Easing.OutQuint), + b => b.ResizeHeightTo(height, 500, Easing.OutQuint) + ); + + fadeIn.Finally(_ => fadeIn = null); + } + + fadeOut?.Cancel(); + fadeOut = Scheduler.AddDelayed(() => + { + toDisplay.Animate( + b => b.FadeOutFromOne(1500, Easing.InQuint), + b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint)); + }, 500); } private class OptionLight : Container From 09b3375a9d157ac4380f0f4308cd9e2f43a7d8fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jul 2018 18:12:23 +0900 Subject: [PATCH 168/190] Fix pressing escape too fast causing multiple exit attempts at song select --- osu.Game/Screens/Select/SongSelect.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9c62f92311..1d051a159e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -138,7 +138,11 @@ namespace osu.Game.Screens.Select Height = filter_height, FilterChanged = c => Carousel.Filter(c), Background = { Width = 2 }, - Exit = Exit, + Exit = () => + { + if (IsCurrentScreen) + Exit(); + }, }, } }, From 49e94850b62b552bbb598cb509ea8b7f05357788 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jul 2018 18:43:20 +0900 Subject: [PATCH 169/190] Fix being able to trigger player before carousel is ready Causes an eventual crash. --- osu.Game/Screens/Select/SongSelect.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9c62f92311..6b0f9d83cf 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -231,6 +231,10 @@ namespace osu.Game.Screens.Select /// Whether to trigger . public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true) { + // avoid attempting to continue before a selection has been obtained. + // this could happen via a user interaction while the carousel is still in a loading state. + if (Carousel.SelectedBeatmap == null) return; + // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). Carousel.FlushPendingFilterOperations(); From abfebbddd9c666a7fe3b973b0dc6efb8c571b09d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jul 2018 23:50:45 +0900 Subject: [PATCH 170/190] Update framework --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index da55726447..ec2742d4a9 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 974c4f5185f98bee0a1b61cf6f79c137d8de6882 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jul 2018 01:20:21 +0900 Subject: [PATCH 171/190] ToolbarMode* -> ToolbarRuleset* --- osu.Game.Tests/Visual/TestCaseToolbar.cs | 4 ++-- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- .../{ToolbarModeButton.cs => ToolbarRulesetButton.cs} | 2 +- ...oolbarModeSelector.cs => ToolbarRulesetSelector.cs} | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) rename osu.Game/Overlays/Toolbar/{ToolbarModeButton.cs => ToolbarRulesetButton.cs} (96%) rename osu.Game/Overlays/Toolbar/{ToolbarModeSelector.cs => ToolbarRulesetSelector.cs} (93%) diff --git a/osu.Game.Tests/Visual/TestCaseToolbar.cs b/osu.Game.Tests/Visual/TestCaseToolbar.cs index fd218af054..96f14e6b32 100644 --- a/osu.Game.Tests/Visual/TestCaseToolbar.cs +++ b/osu.Game.Tests/Visual/TestCaseToolbar.cs @@ -16,8 +16,8 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(ToolbarButton), - typeof(ToolbarModeSelector), - typeof(ToolbarModeButton), + typeof(ToolbarRulesetSelector), + typeof(ToolbarRulesetButton), typeof(ToolbarNotificationButton), }; diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 48d0674b3d..eeace2f11c 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Toolbar { Action = () => OnHome?.Invoke() }, - new ToolbarModeSelector() + new ToolbarRulesetSelector() } }, new FillFlowContainer diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs similarity index 96% rename from osu.Game/Overlays/Toolbar/ToolbarModeButton.cs rename to osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs index 90b9abb2e4..bbdf796e7a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs @@ -7,7 +7,7 @@ using OpenTK.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarModeButton : ToolbarButton + public class ToolbarRulesetButton : ToolbarButton { private RulesetInfo ruleset; public RulesetInfo Ruleset diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs similarity index 93% rename from osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs rename to osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index dae4f84b1a..b1af3f0d62 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -16,18 +16,18 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Toolbar { - public class ToolbarModeSelector : Container + public class ToolbarRulesetSelector : Container { private const float padding = 10; private readonly FillFlowContainer modeButtons; private readonly Drawable modeButtonLine; - private ToolbarModeButton activeButton; + private ToolbarRulesetButton activeButton; private RulesetStore rulesets; private readonly Bindable ruleset = new Bindable(); - public ToolbarModeSelector() + public ToolbarRulesetSelector() { RelativeSizeAxes = Axes.Y; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Toolbar this.rulesets = rulesets; foreach (var r in rulesets.AvailableRulesets) { - modeButtons.Add(new ToolbarModeButton + modeButtons.Add(new ToolbarRulesetButton { Ruleset = r, Action = delegate { ruleset.Value = r; } @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Toolbar private void rulesetChanged(RulesetInfo ruleset) { - foreach (ToolbarModeButton m in modeButtons.Children.Cast()) + foreach (ToolbarRulesetButton m in modeButtons.Children.Cast()) { bool isActive = m.Ruleset.ID == ruleset.ID; m.Active = isActive; From 9e59b4a8e2122f6ed824795f546bbe6cc86703a4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jul 2018 01:29:24 +0900 Subject: [PATCH 172/190] Fix SongSelect binding to ruleset too early Causes music to stop playing while at main menu. --- osu.Game/Screens/Select/SongSelect.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 85eecd5c1a..81502fc024 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -193,8 +193,6 @@ namespace osu.Game.Screens.Select dependencies.CacheAs(Ruleset); dependencies.CacheAs>(Ruleset); - base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce); - if (Footer != null) { Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); @@ -222,6 +220,12 @@ namespace osu.Game.Screens.Select Beatmap.BindValueChanged(workingBeatmapChanged); } + protected override void LoadComplete() + { + base.LoadComplete(); + base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce); + } + public void Edit(BeatmapInfo beatmap) { Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); From ba258b8a054398a1a860220db453301245b064b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jul 2018 02:56:00 +0900 Subject: [PATCH 173/190] Fix lack of fallback logic for custom bank samples Closes #2966. --- Was causing some beatmaps to not play all of their hitsounds --- osu.Game/Audio/SampleInfo.cs | 13 ++++++++++++- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 7e329ac651..9ed40c648e 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -29,6 +29,11 @@ namespace osu.Game.Audio /// public string Name; + /// + /// An optional suffix to provide priority lookup. Falls back to non-suffixed . + /// + public string Suffix; + /// /// The sample volume. /// @@ -41,9 +46,15 @@ namespace osu.Game.Audio { get { + if (!string.IsNullOrEmpty(Suffix)) + { + if (!string.IsNullOrEmpty(Namespace)) + yield return $"{Namespace}/{Bank}-{Name}{Suffix}"; + yield return $"{Bank}-{Name}{Suffix}"; // Without namespace as a fallback even when we have a namespace + } + if (!string.IsNullOrEmpty(Namespace)) yield return $"{Namespace}/{Bank}-{Name}"; - yield return $"{Bank}-{Name}"; // Without namespace as a fallback even when we have a namespace } } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 22a6acf459..c8874c3bc7 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -179,7 +179,7 @@ namespace osu.Game.Beatmaps.Formats var baseInfo = base.ApplyTo(sampleInfo); if (CustomSampleBank > 1) - baseInfo.Name += CustomSampleBank; + baseInfo.Suffix = CustomSampleBank.ToString(); return baseInfo; } From 7f315d79c27cea08e07a8c321cb69094232ab19e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jul 2018 13:06:03 +0900 Subject: [PATCH 174/190] Fix pixel gap in user profile when scrolling --- osu.Game/Overlays/Profile/ProfileHeader.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index c5510d3d70..9d09836d25 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -158,6 +158,13 @@ namespace osu.Game.Overlays.Profile } } }, + new Box // this is a temporary workaround for incorrect masking behaviour of FillMode.Fill used in UserCoverBackground (see https://github.com/ppy/osu-framework/issues/1675) + { + RelativeSizeAxes = Axes.X, + Height = 1, + Y = cover_height, + Colour = OsuColour.Gray(34), + }, infoTextLeft = new LinkFlowContainer(t => t.TextSize = 14) { X = UserProfileOverlay.CONTENT_X_MARGIN, From 14c3cc70b15da9a3ac20cb25c37e704a8536dc61 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jul 2018 15:23:47 +0900 Subject: [PATCH 175/190] Prefer namespace lookups first --- osu.Game/Audio/SampleInfo.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 9ed40c648e..4345d09e05 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -46,16 +46,17 @@ namespace osu.Game.Audio { get { - if (!string.IsNullOrEmpty(Suffix)) + if (!string.IsNullOrEmpty(Namespace)) { - if (!string.IsNullOrEmpty(Namespace)) + if (!string.IsNullOrEmpty(Suffix)) yield return $"{Namespace}/{Bank}-{Name}{Suffix}"; - yield return $"{Bank}-{Name}{Suffix}"; // Without namespace as a fallback even when we have a namespace + yield return $"{Namespace}/{Bank}-{Name}"; } - if (!string.IsNullOrEmpty(Namespace)) - yield return $"{Namespace}/{Bank}-{Name}"; - yield return $"{Bank}-{Name}"; // Without namespace as a fallback even when we have a namespace + // check non-namespace as a fallback even when we have a namespace + if (!string.IsNullOrEmpty(Suffix)) + yield return $"{Bank}-{Name}{Suffix}"; + yield return $"{Bank}-{Name}"; } } From bf1ce8cdd8895f618437ca39857609bc15871f84 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Jul 2018 16:02:13 +0900 Subject: [PATCH 176/190] Fix linking still being broken --- osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index eaa0ac4aaa..1a1f13933d 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Profile.Sections Action = () => { if (beatmap.OnlineBeatmapID != null) - beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.OnlineBeatmapID.Value); + beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value); else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value); }; From ab155e511f88db6dd25e565d85f9a40269cad196 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Tue, 10 Jul 2018 16:09:18 +0900 Subject: [PATCH 177/190] Remove commented disable-once --- osu.Game/Graphics/SpriteIcon.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/SpriteIcon.cs b/osu.Game/Graphics/SpriteIcon.cs index 45c4cebfcf..6acd20719e 100644 --- a/osu.Game/Graphics/SpriteIcon.cs +++ b/osu.Game/Graphics/SpriteIcon.cs @@ -10,7 +10,6 @@ using osu.Framework.IO.Stores; using OpenTK; using OpenTK.Graphics; using osu.Framework.Caching; -// ReSharper disable IdentifierTypo namespace osu.Game.Graphics { From 65d351c31a7494c1103e92a2425a24310d482d01 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Jul 2018 16:26:04 +0900 Subject: [PATCH 178/190] Fix failing test cases --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index ad203d2107..2f5b4a13d9 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -222,10 +222,10 @@ namespace osu.Game.Tests.Beatmaps.Formats { var hitObjects = decoder.Decode(stream).HitObjects; - Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[0]).Name); - Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[1]).Name); - Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name); - Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[3]).Name); + Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[0]).LookupNames.First()); + Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[1]).LookupNames.First()); + Assert.AreEqual("normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First()); + Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[3]).LookupNames.First()); } SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" }); @@ -242,7 +242,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("hit_1.wav", hitObjects[0].Samples[0].LookupNames.First()); Assert.AreEqual("hit_2.wav", hitObjects[1].Samples[0].LookupNames.First()); - Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name); + Assert.AreEqual("normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First()); Assert.AreEqual("hit_1.wav", hitObjects[3].Samples[0].LookupNames.First()); } From 2150cb10283ad38604c9b67aa6b3abcad6568aeb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jul 2018 20:30:08 +0900 Subject: [PATCH 179/190] Update framework and other packages --- osu.Desktop/Program.cs | 6 ++---- osu.Game/osu.Game.csproj | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index 780a9994fd..7e6a07c89f 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework; using osu.Framework.Platform; using osu.Game.IPC; + #if NET_FRAMEWORK using System.Runtime; #endif @@ -18,10 +19,7 @@ namespace osu.Desktop [STAThread] public static int Main(string[] args) { - // required to initialise native SQLite libraries on some platforms. - - if (!RuntimeInfo.IsMono) - useMultiCoreJit(); + useMultiCoreJit(); // Back up the cwd before DesktopGameHost changes it var cwd = Environment.CurrentDirectory; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ec2742d4a9..f7c8c62e91 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,11 +14,11 @@ - + - + From 7157428882545b367e4bc975556a9361a620e735 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 02:59:00 +0900 Subject: [PATCH 180/190] Fix import failure of beatmap sets containing duplicate beatmap difficulties --- osu.Game/Beatmaps/BeatmapManager.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index fd24e4297b..fc4d43080e 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -92,7 +92,7 @@ namespace osu.Game.Beatmaps // by setting the model here, we can update the noline set id below. b.BeatmapSet = model; - fetchAndPopulateOnlineIDs(b); + fetchAndPopulateOnlineIDs(b, model.Beatmaps); } // check if a set already exists with the same online id, delete if it does. @@ -396,9 +396,10 @@ namespace osu.Game.Beatmaps /// Query the API to populate mising OnlineBeatmapID / OnlineBeatmapSetID properties. /// /// The beatmap to populate. + /// The other beatmaps contained within this set. /// Whether to re-query if the provided beatmap already has populated values. /// True if population was successful. - private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, bool force = false) + private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, IEnumerable otherBeatmaps, bool force = false) { if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null) return true; @@ -418,6 +419,12 @@ namespace osu.Game.Beatmaps Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database); + if (otherBeatmaps.Any(b => b.OnlineBeatmapID == res.OnlineBeatmapID)) + { + Logger.Log("Another beatmap in the same set already mapped to this ID. We'll skip adding it this time.", LoggingTarget.Database); + return false; + } + beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmap.OnlineBeatmapID = res.OnlineBeatmapID; return true; From 55e0cd770d5c8451634ff461b402d29546cb4054 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 11 Jul 2018 11:24:43 +0900 Subject: [PATCH 181/190] Use BypassAutoSizeAxes --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 5d4d627995..d407dc9cf9 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -102,6 +102,7 @@ namespace osu.Game.Overlays.KeyBinding RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Margin = new MarginPadding(padding), + Padding = new MarginPadding { Top = height }, Alpha = 0, Colour = colours.YellowDark } @@ -267,7 +268,7 @@ namespace osu.Game.Overlays.KeyBinding GetContainingInputManager().ChangeFocus(null); pressAKey.FadeOut(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding { Top = height, Bottom = -pressAKey.DrawHeight }; + pressAKey.BypassAutoSizeAxes |= Axes.Y; } protected override void OnFocus(InputState state) @@ -276,7 +277,7 @@ namespace osu.Game.Overlays.KeyBinding AutoSizeEasing = Easing.OutQuint; pressAKey.FadeIn(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding { Top = height }; + pressAKey.BypassAutoSizeAxes &= ~Axes.Y; updateBindTarget(); base.OnFocus(state); From 5615a32953065870204f9dff6c2ed4a6739ca158 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 14:53:40 +0900 Subject: [PATCH 182/190] Fix mac installer extension being incorrect --- osu.Desktop/Updater/SimpleUpdateManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/Updater/SimpleUpdateManager.cs b/osu.Desktop/Updater/SimpleUpdateManager.cs index cda8e6a7ca..6c363422f7 100644 --- a/osu.Desktop/Updater/SimpleUpdateManager.cs +++ b/osu.Desktop/Updater/SimpleUpdateManager.cs @@ -72,7 +72,7 @@ namespace osu.Desktop.Updater bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".exe")); break; case RuntimeInfo.Platform.MacOsx: - bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".dmg")); + bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".app.zip")); break; } From 8bc7c4c9a262057013a14cb4f05c1fc81f64e8c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 16:30:33 +0900 Subject: [PATCH 183/190] Add TestCase and update disclaimer screen --- osu.Game.Tests/Visual/TestCaseDisclaimer.cs | 28 +++++ osu.Game/Screens/Menu/Disclaimer.cs | 120 +++++++++----------- 2 files changed, 84 insertions(+), 64 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseDisclaimer.cs diff --git a/osu.Game.Tests/Visual/TestCaseDisclaimer.cs b/osu.Game.Tests/Visual/TestCaseDisclaimer.cs new file mode 100644 index 0000000000..a8253a991a --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseDisclaimer.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Screens.Menu; +using OpenTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseDisclaimer : OsuTestCase + { + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new Disclaimer() + }; + } + } +} diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 0c70dbf570..694f911773 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -3,10 +3,9 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.Containers; using OpenTK; using OpenTK.Graphics; using osu.Game.Overlays; @@ -16,96 +15,89 @@ namespace osu.Game.Screens.Menu public class Disclaimer : OsuScreen { private Intro intro; - private readonly SpriteIcon icon; + private SpriteIcon icon; private Color4 iconColour; + private LinkFlowContainer textFlow; protected override bool HideOverlaysOnEnter => true; protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; public override bool CursorVisible => false; + private const float icon_y = -0.09f; + public Disclaimer() { ValidForResume = false; - - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 2), - Children = new Drawable[] - { - icon = new SpriteIcon - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Icon = FontAwesome.fa_warning, - Size = new Vector2(30), - }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - TextSize = 30, - Text = "This is a development build", - Margin = new MarginPadding - { - Bottom = 20 - }, - }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Don't expect shit to work perfectly as this is very much a work in progress." - }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Don't report bugs because we are aware. Don't complain about missing features because we are adding them." - }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Sit back and enjoy. Visit discord.gg/ppy if you want to help out!", - Margin = new MarginPadding { Bottom = 20 }, - }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - TextSize = 12, - Text = "oh and yes, you will get seizures.", - }, - } - } - }; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - LoadComponentAsync(intro = new Intro()); + Children = new Drawable[] + { + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_warning, + Size = new Vector2(30), + RelativePositionAxes = Axes.Both, + Y = icon_y, + }, + textFlow = new LinkFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(50), + TextAnchor = Anchor.TopCentre, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Spacing = new Vector2(0, 2), + } + }; + + textFlow.AddText("This is an ", t => + { + t.TextSize = 30; + t.Font = @"Exo2.0-Light"; + }); + textFlow.AddText("early development build", t => + { + t.TextSize = 30; + t.Font = @"Exo2.0-SemiBold"; + }); + + textFlow.AddParagraph("Don't expect everything to work perfectly."); + textFlow.AddParagraph(""); + textFlow.AddParagraph("Detailed bug reports are welcomed via github issues."); + textFlow.AddParagraph(""); + + textFlow.AddText("Visit "); + textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy"); + textFlow.AddText(" if you want to help out or follow progress!"); iconColour = colours.Yellow; } + protected override void LoadComplete() + { + base.LoadComplete(); + LoadComponentAsync(intro = new Intro()); + } + protected override void OnEntering(Screen last) { base.OnEntering(last); - icon.Delay(1500).FadeColour(iconColour, 200); + icon.Delay(1500).FadeColour(iconColour, 200, Easing.OutQuint); + icon.Delay(1500).MoveToY(icon_y * 1.1f, 100, Easing.OutCirc).Then().MoveToY(icon_y, 100, Easing.InCirc); Content .FadeInFromZero(500) .Then(5500) .FadeOut(250) + .ScaleTo(0.9f, 250, Easing.InQuint) .Finally(d => Push(intro)); } } From 4638ac902c63c5501e69cb4ce1fdc3afdb533d5d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 16:30:16 +0900 Subject: [PATCH 184/190] Remove pointless rate adjust slider from TestCaseOsuGame --- osu.Game.Tests/Visual/TestCaseOsuGame.cs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseOsuGame.cs b/osu.Game.Tests/Visual/TestCaseOsuGame.cs index f1a21a58d5..7a4e4c1210 100644 --- a/osu.Game.Tests/Visual/TestCaseOsuGame.cs +++ b/osu.Game.Tests/Visual/TestCaseOsuGame.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; -using osu.Framework.Timing; using osu.Game.Screens; using osu.Game.Screens.Menu; using OpenTK.Graphics; @@ -23,19 +22,15 @@ namespace osu.Game.Tests.Visual public TestCaseOsuGame() { - var rateAdjustClock = new StopwatchClock(true); - var framedClock = new FramedClock(rateAdjustClock); - framedClock.ProcessFrame(); - - Add(new Box + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }); - - Add(new Loader()); - - AddSliderStep("Playback speed", 0.0, 2.0, 1, v => rateAdjustClock.Rate = v); + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new Loader() + }; } } } From fbc5250bf1ba54de25889fd534ba9f3b9d5c1a7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 17:07:14 +0900 Subject: [PATCH 185/190] Update framework --- osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs | 4 ++-- osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 4 ++-- osu.Game.Tests/Visual/TestCasePreviewTrackManager.cs | 8 ++++---- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 4 ++-- osu.Game/OsuGame.cs | 4 ++-- osu.Game/OsuGameBase.cs | 4 ++-- osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs | 4 ++-- osu.Game/Rulesets/UI/RulesetContainer.cs | 4 ++-- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 4 ++-- osu.Game/Screens/Tournament/Drawings.cs | 4 ++-- osu.Game/Skinning/LocalSkinOverrideContainer.cs | 4 ++-- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 4 ++-- osu.Game/Tests/Visual/EditorClockTestCase.cs | 4 ++-- osu.Game/Tests/Visual/OsuTestCase.cs | 4 ++-- osu.Game/osu.Game.csproj | 2 +- 18 files changed, 37 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs b/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs index 78a98e83e8..5a93efb0dc 100644 --- a/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs +++ b/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs @@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Mania.Tests this.direction = direction; } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs(new ScrollingInfo { Direction = { Value = direction }}); return dependencies; } diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs index e827fa1fdc..64ed08373a 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs @@ -137,9 +137,9 @@ namespace osu.Game.Rulesets.Mania.Tests }; } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs>(new Bindable()); return dependencies; } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index a19a6fb5d4..8465258055 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -118,9 +118,9 @@ namespace osu.Game.Rulesets.Mania.UI } } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs>(Action); return dependencies; } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index e6ebf43c67..f1dff29a0c 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -80,9 +80,9 @@ namespace osu.Game.Rulesets.Mania.UI private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs(scrollingInfo = new ScrollingInfo()); return dependencies; } diff --git a/osu.Game.Tests/Visual/TestCasePreviewTrackManager.cs b/osu.Game.Tests/Visual/TestCasePreviewTrackManager.cs index d711d501fe..e4cb848d90 100644 --- a/osu.Game.Tests/Visual/TestCasePreviewTrackManager.cs +++ b/osu.Game.Tests/Visual/TestCasePreviewTrackManager.cs @@ -14,9 +14,9 @@ namespace osu.Game.Tests.Visual { private readonly PreviewTrackManager trackManager = new TestPreviewTrackManager(); - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs(trackManager); dependencies.CacheAs(this); return dependencies; @@ -101,9 +101,9 @@ namespace osu.Game.Tests.Visual AddInternal(track); } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs(this); return dependencies; } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index d6bc4a2095..1d832d1c54 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -26,9 +26,9 @@ namespace osu.Game.Graphics.Containers protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.CacheAs(this); return dependencies; } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 922d228701..b654e5d53f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -122,8 +122,8 @@ namespace osu.Game private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c1d5ae581e..a9b74d6740 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -95,8 +95,8 @@ namespace osu.Game private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); private DatabaseContextFactory contextFactory; diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs index 05104018cd..191308cca6 100644 --- a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -21,9 +21,9 @@ namespace osu.Game.Overlays.Settings private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); var config = dependencies.Get().GetConfigFor(ruleset); if (config != null) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index fedb6abed3..71d7919dd4 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -85,9 +85,9 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); onScreenDisplay = dependencies.Get(); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 7eeabd3e5e..a52fa3b462 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -42,8 +42,8 @@ namespace osu.Game.Screens.Edit private DependencyContainer dependencies; private GameHost host; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] private void load(OsuColour colours, GameHost host) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 81502fc024..e6926c118b 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -69,8 +69,8 @@ namespace osu.Game.Screens.Select private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); protected SongSelect() { diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index 29301899d5..49a46b96e3 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -49,8 +49,8 @@ namespace osu.Game.Screens.Tournament private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] private void load(TextureStore textures, Storage storage) diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index ad6a033936..3adf287cf7 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -71,9 +71,9 @@ namespace osu.Game.Skinning private void onSourceChanged() => SourceChanged?.Invoke(); - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); fallbackSource = dependencies.Get(); dependencies.CacheAs(this); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index a2f4372323..d746bb90c4 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -36,8 +36,8 @@ namespace osu.Game.Storyboards.Drawables public override bool RemoveCompletedTransforms => false; private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); public DrawableStoryboard(Storyboard storyboard) { diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 521b51529e..22f3e5b6df 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -25,9 +25,9 @@ namespace osu.Game.Tests.Visual Clock = new EditorClock(new ControlPointInfo(), 5000, BeatDivisor) { IsCoupled = false }; } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); dependencies.Cache(BeatDivisor); dependencies.CacheAs(Clock); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 5f70055021..fcbab5b8f5 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -20,9 +20,9 @@ namespace osu.Game.Tests.Visual protected DependencyContainer Dependencies { get; private set; } - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - Dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); Dependencies.CacheAs(beatmap); Dependencies.CacheAs(beatmap); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f7c8c62e91..bfc7b21242 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 24054246b80def77001f1a55c5e0d498aaaaa632 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 17:25:57 +0900 Subject: [PATCH 186/190] Fix DI regression --- .../ManiaSettingsSubsection.cs | 4 ++-- .../UI/ManiaRulesetContainer.cs | 4 ++-- .../Settings/RulesetSettingsSubsection.cs | 9 ++++++--- osu.Game/Rulesets/UI/RulesetContainer.cs | 17 +++++++++-------- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index 54a7bf954d..783142fadc 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -19,14 +19,14 @@ namespace osu.Game.Rulesets.Mania } [BackgroundDependencyLoader] - private void load(ManiaConfigManager config) + private void load() { Children = new Drawable[] { new SettingsEnumDropdown { LabelText = "Scrolling direction", - Bindable = config.GetBindable(ManiaSetting.ScrollDirection) + Bindable = ((ManiaConfigManager)Config).GetBindable(ManiaSetting.ScrollDirection) } }; } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index f1dff29a0c..abc9705119 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -70,11 +70,11 @@ namespace osu.Game.Rulesets.Mania.UI } [BackgroundDependencyLoader] - private void load(ManiaConfigManager config) + private void load() { BarLines.ForEach(Playfield.Add); - config.BindWith(ManiaSetting.ScrollDirection, configDirection); + ((ManiaConfigManager)Config).BindWith(ManiaSetting.ScrollDirection, configDirection); configDirection.BindValueChanged(d => scrollingInfo.Direction.Value = (ScrollingDirection)d, true); } diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs index 191308cca6..60a1c7c125 100644 --- a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Game.Rulesets; +using osu.Game.Rulesets.Configuration; namespace osu.Game.Overlays.Settings { @@ -14,6 +15,8 @@ namespace osu.Game.Overlays.Settings { private readonly Ruleset ruleset; + protected IRulesetConfigManager Config; + protected RulesetSettingsSubsection(Ruleset ruleset) { this.ruleset = ruleset; @@ -25,9 +28,9 @@ namespace osu.Game.Overlays.Settings { dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - var config = dependencies.Get().GetConfigFor(ruleset); - if (config != null) - dependencies.Cache(config); + Config = dependencies.Get().GetConfigFor(ruleset); + if (Config != null) + dependencies.Cache(Config); return dependencies; } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 71d7919dd4..0bfde148e7 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -70,7 +70,8 @@ namespace osu.Game.Rulesets.UI protected readonly Ruleset Ruleset; - private IRulesetConfigManager rulesetConfig; + protected IRulesetConfigManager Config { get; private set; } + private OnScreenDisplay onScreenDisplay; /// @@ -91,11 +92,11 @@ namespace osu.Game.Rulesets.UI onScreenDisplay = dependencies.Get(); - rulesetConfig = dependencies.Get().GetConfigFor(Ruleset); - if (rulesetConfig != null) + Config = dependencies.Get().GetConfigFor(Ruleset); + if (Config != null) { - dependencies.Cache(rulesetConfig); - onScreenDisplay?.BeginTracking(this, rulesetConfig); + dependencies.Cache(Config); + onScreenDisplay?.BeginTracking(this, Config); } return dependencies; @@ -143,10 +144,10 @@ namespace osu.Game.Rulesets.UI { base.Dispose(isDisposing); - if (rulesetConfig != null) + if (Config != null) { - onScreenDisplay?.StopTracking(this, rulesetConfig); - rulesetConfig = null; + onScreenDisplay?.StopTracking(this, Config); + Config = null; } } } From e550b3f52b46946af51c6550215bf3f3d184a63c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 18:25:55 +0900 Subject: [PATCH 187/190] Turn cache back on for chocolatey packages --- appveyor.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index ac6d6ebff8..7c08eb9e9c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,9 @@ clone_depth: 1 version: '{branch}-{build}' image: Visual Studio 2017 configuration: Debug +cache: + - C:\ProgramData\chocolatey\bin -> appveyor.yml + - C:\ProgramData\chocolatey\lib -> appveyor.yml install: - cmd: git submodule update --init --recursive --depth=5 - cmd: choco install resharper-clt -y @@ -18,4 +21,4 @@ build: verbosity: minimal after_build: - cmd: inspectcode --o="inspectcodereport.xml" --projects:osu.Game* --caches-home="inspectcode" osu.sln > NUL - - cmd: NVika parsereport "inspectcodereport.xml" --treatwarningsaserrors \ No newline at end of file + - cmd: NVika parsereport "inspectcodereport.xml" --treatwarningsaserrors From 5df2df9b3aa8bcf55fd78b949af89449bb74dc67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jul 2018 12:15:22 +0900 Subject: [PATCH 188/190] Fix osu! logo handling non-left mouse buttons --- osu.Game/Screens/Menu/OsuLogo.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 16482b0e48..b74546310f 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using OpenTK; using OpenTK.Graphics; +using OpenTK.Input; namespace osu.Game.Screens.Menu { @@ -345,12 +346,16 @@ namespace osu.Game.Screens.Menu protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { + if (args.Button != MouseButton.Left) return false; + logoBounceContainer.ScaleTo(0.9f, 1000, Easing.Out); return true; } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { + if (args.Button != MouseButton.Left) return false; + logoBounceContainer.ScaleTo(1f, 500, Easing.OutElastic); return true; } From c67e11b2c78025f1a708f8a1f64d0a9a3b26eeac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jul 2018 15:27:17 +0900 Subject: [PATCH 189/190] Restore old tooltip appear delay behaviour --- osu.Game/Graphics/Cursor/OsuTooltipContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index c0e331148d..44156f6e83 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -21,6 +21,8 @@ namespace osu.Game.Graphics.Cursor { } + protected override double AppearDelay => (1 - CurrentTooltip.Alpha) * base.AppearDelay; // reduce appear delay if the tooltip is already partly visible. + public class OsuTooltip : Tooltip { private readonly Box background; From 6bcc8d1cbcc2a680dd4895c2870a68e30df841e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jul 2018 19:56:41 +0900 Subject: [PATCH 190/190] Update framework --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index bfc7b21242..c8db3e4d66 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - +