From 6cf227a7af53014b2b5a5a14112e71537af68b7b Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Wed, 23 May 2018 03:24:18 +0200 Subject: [PATCH 001/125] 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/125] 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/125] 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/125] 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/125] 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 38e5e35743f372de3be1324d3adf0473f29d8bd1 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 01:20:05 +0900 Subject: [PATCH 006/125] modify catch hyperdash behavior --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 62 ++++++++++++++--------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 181536a91e..56826d228c 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -248,37 +248,46 @@ namespace osu.Game.Rulesets.Catch.UI if (validCatch && fruit.HyperDash) { - HyperDashModifier = Math.Abs(fruit.HyperDashTarget.X - fruit.X) / Math.Abs(fruit.HyperDashTarget.StartTime - fruit.StartTime) / BASE_SPEED; - HyperDashDirection = fruit.HyperDashTarget.X - fruit.X; + var target = fruit.HyperDashTarget; + double timeDifference = target.StartTime - fruit.StartTime; + double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition; + double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0); + + HyperDashing = true; + hyperDashModifier = Math.Abs(velocity); + hyperDashDirection = (int)Math.Sign(velocity); + hyperDashTargetPosition = target.X; } else - HyperDashModifier = 1; + { + HyperDashing = false; + } return validCatch; } + private double hyperDashModifier = 1; + private int hyperDashDirection = 0; + private float hyperDashTargetPosition; + private bool hyperDashing = false; + /// /// Whether we are hypderdashing or not. /// - public bool HyperDashing => hyperDashModifier != 1; - - private double hyperDashModifier = 1; - - /// - /// The direction in which hyperdash is allowed. 0 allows both directions. - /// - public double HyperDashDirection; - - /// - /// The speed modifier resultant from hyperdash. Will trigger hyperdash when not equal to 1. - /// - public double HyperDashModifier + protected bool HyperDashing { - get { return hyperDashModifier; } + get => hyperDashing; set { - if (value == hyperDashModifier) return; - hyperDashModifier = value; + if (hyperDashing == value) return; + + hyperDashing = value; + + if (!HyperDashing) + { + hyperDashModifier = 1; + hyperDashDirection = 0; + } const float transition_length = 180; @@ -290,7 +299,6 @@ namespace osu.Game.Rulesets.Catch.UI } else { - HyperDashDirection = 0; this.FadeColour(Color4.White, transition_length, Easing.OutQuint); this.FadeTo(1, transition_length, Easing.OutQuint); } @@ -347,12 +355,18 @@ namespace osu.Game.Rulesets.Catch.UI var direction = Math.Sign(currentDirection); double dashModifier = Dashing ? 1 : 0.5; - - if (hyperDashModifier != 1 && (HyperDashDirection == 0 || direction == Math.Sign(HyperDashDirection))) - dashModifier = hyperDashModifier; + double speed = BASE_SPEED * dashModifier * hyperDashModifier; Scale = new Vector2(Math.Abs(Scale.X) * direction, Scale.Y); - X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * BASE_SPEED * dashModifier, 0, 1); + X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1); + + // Correct overshooting. + if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) || + (hyperDashDirection < 0 && hyperDashTargetPosition > X)) + { + X = hyperDashTargetPosition; + HyperDashing = false; + } } /// From 99c0e19189b95df33b332784e8a13f8a985c2181 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 01:52:15 +0900 Subject: [PATCH 007/125] Fix build error --- osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs index f239290ed4..ed6600c55d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs @@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Catch.Tests public TestCaseCatcherArea() { AddSliderStep("CircleSize", 0, 8, 5, createCatcher); - AddToggleStep("Hyperdash", t => catcherArea.ToggleHyperDash(t)); } private void createCatcher(float size) @@ -54,8 +53,6 @@ namespace osu.Game.Rulesets.Catch.Tests : base(beatmapDifficulty) { } - - public void ToggleHyperDash(bool status) => MovableCatcher.HyperDashModifier = status ? 2 : 1; } } } From be323c71477d009bb8bcda38560fa5c370bcd6f1 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 02:14:56 +0900 Subject: [PATCH 008/125] Fix InspectCode issues. --- osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs | 3 +-- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs index ed6600c55d..511cda6399 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs @@ -16,7 +16,6 @@ namespace osu.Game.Rulesets.Catch.Tests public class TestCaseCatcherArea : OsuTestCase { private RulesetInfo catchRuleset; - private TestCatcherArea catcherArea; public override IReadOnlyList RequiredTypes => new[] { @@ -33,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Tests Child = new CatchInputManager(catchRuleset) { RelativeSizeAxes = Axes.Both, - Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) + Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) { Anchor = Anchor.CentreLeft, Origin = Anchor.BottomLeft diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 56826d228c..d57d52cf5f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -255,7 +255,7 @@ namespace osu.Game.Rulesets.Catch.UI HyperDashing = true; hyperDashModifier = Math.Abs(velocity); - hyperDashDirection = (int)Math.Sign(velocity); + hyperDashDirection = Math.Sign(velocity); hyperDashTargetPosition = target.X; } else @@ -267,9 +267,9 @@ namespace osu.Game.Rulesets.Catch.UI } private double hyperDashModifier = 1; - private int hyperDashDirection = 0; + private int hyperDashDirection; private float hyperDashTargetPosition; - private bool hyperDashing = false; + private bool hyperDashing; /// /// Whether we are hypderdashing or not. @@ -361,8 +361,8 @@ namespace osu.Game.Rulesets.Catch.UI X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1); // Correct overshooting. - if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) || - (hyperDashDirection < 0 && hyperDashTargetPosition > X)) + if (hyperDashDirection > 0 && hyperDashTargetPosition < X || + hyperDashDirection < 0 && hyperDashTargetPosition > X) { X = hyperDashTargetPosition; HyperDashing = false; From 9f2e09dae4cba569d6dbd1e36767f5770bfcda93 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 16:21:51 +0900 Subject: [PATCH 009/125] Move PostProcessing to after control points applied and nested hit objects created. --- osu.Game/Beatmaps/WorkingBeatmap.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 66a6206c16..2e6426c056 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -116,9 +116,6 @@ namespace osu.Game.Beatmaps mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); } - // Post-process - rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess(); - // 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); @@ -127,6 +124,9 @@ namespace osu.Game.Beatmaps foreach (var obj in converted.HitObjects) mod.ApplyToHitObject(obj); + // Post-process + rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess(); + return converted; } From ca2c2097016521c16a345e6a173d4e62c78cac0a Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 16:26:19 +0900 Subject: [PATCH 010/125] add FastRandom --- .../MathUtils/FastRandom.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs diff --git a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs new file mode 100644 index 0000000000..5e8256a504 --- /dev/null +++ b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs @@ -0,0 +1,91 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; + +namespace osu.Game.Rulesets.Catch.MathUtils +{ + /// + /// A PRNG specified in http://heliosphan.org/fastrandom.html. + /// + internal class FastRandom + { + private const double int_to_real = 1.0 / (int.MaxValue + 1.0); + private const uint int_mask = 0x7FFFFFFF; + private const uint y = 842502087; + private const uint z = 3579807591; + private const uint w = 273326509; + private uint _x, _y = y, _z = z, _w = w; + + public FastRandom(int seed) + { + _x = (uint)seed; + } + + public FastRandom() + : this(Environment.TickCount) + { + } + + /// + /// Generates a random unsigned integer within the range [, ). + /// + /// 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; + } + + /// + /// Generates a random integer value within the range [0, ). + /// + /// The random value. + public int Next() => (int)(int_mask & NextUInt()); + + /// + /// Generates a random integer value within the range [0, ). + /// + /// The upper bound. + /// The random value. + public int Next(int upperBound) => (int)(NextDouble() * upperBound); + + /// + /// Generates a random integer value within the range [, ). + /// + /// The lower bound of the range. + /// The upper bound of the range. + /// The random value. + public int Next(int lowerBound, int upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound)); + + /// + /// Generates a random double value within the range [0, 1). + /// + /// The random value. + public double NextDouble() => int_to_real * Next(); + + private uint bitBuffer; + private int bitIndex = 32; + + /// + /// Generates a reandom boolean value. Cached such that a random value is only generated once in every 32 calls. + /// + /// The random value. + public bool NextBool() + { + if (bitIndex == 32) + { + bitBuffer = NextUInt(); + bitIndex = 1; + + return (bitBuffer & 1) == 1; + } + + bitIndex++; + return ((bitBuffer >>= 1) & 1) == 1; + } + } +} From 8c8e87ed7af2423f8d2ab3a7cf77b98d490c17f9 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 16:49:41 +0900 Subject: [PATCH 011/125] Make FastRandom public --- osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs index 5e8256a504..5b3835755a 100644 --- a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs +++ b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs @@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Catch.MathUtils /// /// A PRNG specified in http://heliosphan.org/fastrandom.html. /// - internal class FastRandom + public class FastRandom { private const double int_to_real = 1.0 / (int.MaxValue + 1.0); private const uint int_mask = 0x7FFFFFFF; From 26c6313dec3a1286757f157947e93f10a61f2bdc Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 19:11:29 +0900 Subject: [PATCH 012/125] catch: the fruit positions are finalized on the post process --- .../Beatmaps/CatchBeatmapProcessor.cs | 45 +++++++++++++++++++ .../Objects/BananaShower.cs | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index e16f5fcb60..91a69b5c34 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects.Types; using OpenTK; +using osu.Game.Rulesets.Catch.MathUtils; namespace osu.Game.Rulesets.Catch.Beatmaps { @@ -21,6 +22,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps public override void PostProcess() { + finalizePosition(); + initialiseHyperDash((List)Beatmap.HitObjects); base.PostProcess(); @@ -30,6 +33,48 @@ namespace osu.Game.Rulesets.Catch.Beatmaps obj.IndexInBeatmap = index++; } + public const int RNG_SEED = 1337; + + private void finalizePosition() + { + 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(); + // discarding 3 times + rng.Next(); + rng.Next(); + rng.Next(); + } + break; + case JuiceStream juiceStream: + foreach (var nested in juiceStream.NestedHitObjects) + { + if (nested is TinyDroplet tinyDroplet) + { + tinyDroplet.X += (float)rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; + } + else if (nested is Droplet) + { + rng.Next(); // Big droplets are not slided + } + } + break; + case Fruit fruit: + break; + } + var catchHitObject = obj as CatchHitObject; + + } + } + private void initialiseHyperDash(List objects) { // todo: add difficulty adjust. diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index a6aba42f03..ed49359c0f 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = Samples, StartTime = i, - X = RNG.NextSingle() + X = 0 // The position will be set on the post processing }); } From 456dc81f2fdd67a966a8e837c0c82fb8839a759e Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 25 May 2018 19:18:11 +0900 Subject: [PATCH 013/125] Fix InspectCode issues --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 6 +----- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 91a69b5c34..869bc560a8 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { if (nested is TinyDroplet tinyDroplet) { - tinyDroplet.X += (float)rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; + tinyDroplet.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; } else if (nested is Droplet) { @@ -67,11 +67,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps } } break; - case Fruit fruit: - break; } - var catchHitObject = obj as CatchHitObject; - } } diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index ed49359c0f..4590856d98 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.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.Framework.MathUtils; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Catch.Objects From 961702aadff5955ad1844278b96bf6ee4c206d33 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 25 May 2018 13:05:41 +0200 Subject: [PATCH 014/125] 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 015/125] 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 016/125] 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 017/125] 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 018/125] 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 019/125] 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 020/125] 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 021/125] 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 9f27dd848a8503350ab127cc4d87e02412be2018 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 3 Jun 2018 15:29:56 +0900 Subject: [PATCH 022/125] HyperDashModifier >= 1 --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 38 +++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 6c3624aa0a..2ae1f7eb7a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -18,6 +18,7 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; +using System.Diagnostics; namespace osu.Game.Rulesets.Catch.UI { @@ -243,14 +244,21 @@ 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); - HyperDashing = true; - hyperDashModifier = Math.Abs(velocity); - hyperDashDirection = Math.Sign(velocity); - hyperDashTargetPosition = target.X; + // An edge case + if (Math.Abs(velocity) <= 1) + { + HyperDashModifier = 1; + } + else + { + hyperDashDirection = Math.Sign(velocity); + hyperDashTargetPosition = target.X; + HyperDashModifier = Math.Abs(velocity); + } } else { - HyperDashing = false; + HyperDashModifier = 1; } return validCatch; @@ -259,23 +267,27 @@ namespace osu.Game.Rulesets.Catch.UI private double hyperDashModifier = 1; private int hyperDashDirection; private float hyperDashTargetPosition; - private bool hyperDashing; /// /// Whether we are hypderdashing or not. /// - protected bool HyperDashing + public bool HyperDashing => hyperDashModifier != 1; + + /// + /// The modifier multiplied to the catcher speed. + /// It is always not less than 1 and it is greater than 1 if and only if the catcher is hyper-dashing. + /// + protected double HyperDashModifier { - get => hyperDashing; + get => hyperDashModifier; set { - if (hyperDashing == value) return; - - hyperDashing = value; + Trace.Assert(value >= 1); + if (hyperDashModifier == value) return; + hyperDashModifier = value; if (!HyperDashing) { - hyperDashModifier = 1; hyperDashDirection = 0; } @@ -355,7 +367,7 @@ namespace osu.Game.Rulesets.Catch.UI hyperDashDirection < 0 && hyperDashTargetPosition > X) { X = hyperDashTargetPosition; - HyperDashing = false; + HyperDashModifier = 1; } } From 25d3f0ead18bceec90c477fd11a3ed5ea1908e0b Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 3 Jun 2018 15:31:51 +0900 Subject: [PATCH 023/125] Revert TestCaseCatcherArea --- osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs | 8 ++++++-- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs index 9ec39189f8..f239290ed4 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs @@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests public class TestCaseCatcherArea : OsuTestCase { private RulesetInfo catchRuleset; + private TestCatcherArea catcherArea; public override IReadOnlyList RequiredTypes => new[] { @@ -25,6 +26,7 @@ namespace osu.Game.Rulesets.Catch.Tests public TestCaseCatcherArea() { AddSliderStep("CircleSize", 0, 8, 5, createCatcher); + AddToggleStep("Hyperdash", t => catcherArea.ToggleHyperDash(t)); } private void createCatcher(float size) @@ -32,10 +34,10 @@ namespace osu.Game.Rulesets.Catch.Tests Child = new CatchInputManager(catchRuleset) { RelativeSizeAxes = Axes.Both, - Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) + Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) { Anchor = Anchor.CentreLeft, - Origin = Anchor.TopLeft + Origin = Anchor.BottomLeft }, }; } @@ -52,6 +54,8 @@ namespace osu.Game.Rulesets.Catch.Tests : base(beatmapDifficulty) { } + + public void ToggleHyperDash(bool status) => MovableCatcher.HyperDashModifier = status ? 2 : 1; } } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 2ae1f7eb7a..d7d4691ad0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -277,7 +277,7 @@ namespace osu.Game.Rulesets.Catch.UI /// The modifier multiplied to the catcher speed. /// It is always not less than 1 and it is greater than 1 if and only if the catcher is hyper-dashing. /// - protected double HyperDashModifier + public double HyperDashModifier { get => hyperDashModifier; set From a5c5d11da20febe6f6eeb1772a6955818c0247f3 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 3 Jun 2018 15:42:27 +0900 Subject: [PATCH 024/125] I think I should learn how to use git --- osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs index f239290ed4..5119260c53 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Catch.Tests Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) { Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft + Origin = Anchor.TopLeft }, }; } From f486bcfee1610cad4329f6910c1c8d4594175921 Mon Sep 17 00:00:00 2001 From: clayton Date: Sat, 9 Jun 2018 17:38:17 -0700 Subject: [PATCH 025/125] 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 026/125] 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 027/125] 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 028/125] 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 029/125] 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 030/125] 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 031/125] 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 cafdbc2d251626dd3dc624c9a7044db3e9828f5a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 18:39:26 +0900 Subject: [PATCH 032/125] Fix discarding too many RNG values, and add test --- .../CatchBeatmapConversionTest.cs | 12 +++ .../Beatmaps/CatchBeatmapProcessor.cs | 6 +- .../Beatmaps/spinner-expected-conversion.json | 74 +++++++++++++++++++ .../Resources/Testing/Beatmaps/spinner.osu | 20 +++++ 4 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner.osu diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 5b34e46247..9de0ce3565 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; [TestCase("basic"), Ignore("See: https://github.com/ppy/osu/issues/2232")] + [TestCase("spinner")] public new void Test(string name) { base.Test(name); @@ -35,6 +36,17 @@ namespace osu.Game.Rulesets.Catch.Tests }; } } + else if (hitObject is BananaShower shower) + { + foreach (var nested in shower.NestedHitObjects) + { + yield return new ConvertValue + { + StartTime = nested.StartTime, + Position = ((CatchHitObject)nested).X * CatchPlayfield.BASE_WIDTH + }; + } + } else { yield return new ConvertValue diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 869bc560a8..a9fbc8bcb2 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -48,10 +48,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps foreach (var nested in bananaShower.NestedHitObjects) { ((BananaShower.Banana)nested).X = (float)rng.NextDouble(); - // discarding 3 times - rng.Next(); - rng.Next(); - rng.Next(); + rng.Next(); // osu!stable retrieved a random banana type + rng.Next(); // osu!stable retrieved a random banana rotation } break; case JuiceStream juiceStream: diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json new file mode 100644 index 0000000000..933adb4acc --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json @@ -0,0 +1,74 @@ +{ + "Mappings": [{ + "StartTime": 18500, + "Objects": [{ + "StartTime": 18500, + "Position": 65 + }, + { + "StartTime": 18559, + "Position": 459 + }, + { + "StartTime": 18618, + "Position": 255 + }, + { + "StartTime": 18678, + "Position": 113 + }, + { + "StartTime": 18737, + "Position": 315 + }, + { + "StartTime": 18796, + "Position": 17 + }, + { + "StartTime": 18856, + "Position": 482 + }, + { + "StartTime": 18915, + "Position": 44 + }, + { + "StartTime": 18975, + "Position": 310 + }, + { + "StartTime": 19034, + "Position": 244 + }, + { + "StartTime": 19093, + "Position": 18 + }, + { + "StartTime": 19153, + "Position": 482 + }, + { + "StartTime": 19212, + "Position": 243 + }, + { + "StartTime": 19271, + "Position": 332 + }, + { + "StartTime": 19331, + "Position": 477 + }, + { + "StartTime": 19390, + "Position": 376 + }, + { + "StartTime": 19450, + "Position": 104 + } + ] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner.osu new file mode 100644 index 0000000000..0fbd4dbf42 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner.osu @@ -0,0 +1,20 @@ +osu file format v14 + +[General] +Mode: 2 + +[Difficulty] +HPDrainRate:6 +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8.3 +SliderMultiplier:1.6 +SliderTickRate:1 + +[TimingPoints] +500,500,4,2,1,50,1,0 +13426,-100,4,3,1,45,0,0 +14884,-100,4,2,1,50,0,0 + +[HitObjects] +256,192,18500,12,0,19450,0:0:0:0: From a97a7e13bd492a87b3ab7695307ff66bd87f0cf7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 19:52:04 +0900 Subject: [PATCH 033/125] Rework RNG discarding comment --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index a9fbc8bcb2..a146617182 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -56,13 +56,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps foreach (var nested in juiceStream.NestedHitObjects) { if (nested is TinyDroplet tinyDroplet) - { tinyDroplet.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; - } else if (nested is Droplet) - { - rng.Next(); // Big droplets are not slided - } + rng.Next(); // osu!stable retrieved a random droplet rotation } break; } From 9b403b0053519266bfb0dfb74313adcf42ff090b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 19:56:00 +0900 Subject: [PATCH 034/125] Fix non-catch beatmaps not getting properly converted Because Osu.ConvertSpinner implements IHasXPosition. --- .../Beatmaps/CatchBeatmapConverter.cs | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index ad500606ed..46fe8454dc 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -27,22 +27,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps var comboData = obj as IHasCombo; var endTime = obj as IHasEndTime; - if (positionData == null) - { - if (endTime != null) - { - yield return new BananaShower - { - StartTime = obj.StartTime, - Samples = obj.Samples, - Duration = endTime.Duration, - NewCombo = comboData?.NewCombo ?? false - }; - } - - yield break; - } - if (curveData != null) { yield return new JuiceStream @@ -54,20 +38,30 @@ namespace osu.Game.Rulesets.Catch.Beatmaps Distance = curveData.Distance, RepeatSamples = curveData.RepeatSamples, RepeatCount = curveData.RepeatCount, - X = positionData.X / CatchPlayfield.BASE_WIDTH, + X = (positionData?.X ?? 0) / CatchPlayfield.BASE_WIDTH, NewCombo = comboData?.NewCombo ?? false }; - - yield break; } - - yield return new Fruit + else if (endTime != null) { - StartTime = obj.StartTime, - Samples = obj.Samples, - NewCombo = comboData?.NewCombo ?? false, - X = positionData.X / CatchPlayfield.BASE_WIDTH - }; + yield return new BananaShower + { + StartTime = obj.StartTime, + Samples = obj.Samples, + Duration = endTime.Duration, + NewCombo = comboData?.NewCombo ?? false + }; + } + else + { + yield return new Fruit + { + StartTime = obj.StartTime, + Samples = obj.Samples, + NewCombo = comboData?.NewCombo ?? false, + X = (positionData?.X ?? 0) / CatchPlayfield.BASE_WIDTH + }; + } } protected override Beatmap CreateBeatmap() => new CatchBeatmap(); From 250e8645e19ecb4f4cdbde14643cfcf25ea7e1ba Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 20:11:27 +0900 Subject: [PATCH 035/125] finalisePosition -> applyPositionOffsets --- 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 a146617182..1ac1643297 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps public override void PostProcess() { - finalizePosition(); + applyPositionOffsets(); initialiseHyperDash((List)Beatmap.HitObjects); @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps public const int RNG_SEED = 1337; - private void finalizePosition() + private void applyPositionOffsets() { var rng = new FastRandom(RNG_SEED); // todo: HardRock displacement should be applied here From e1f549892475d27b11121dfcb9c96cf3e9c7c414 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 21:10:54 +0900 Subject: [PATCH 036/125] Discarding 3 times is correct --- .../Beatmaps/CatchBeatmapProcessor.cs | 1 + .../Beatmaps/spinner-expected-conversion.json | 62 +++++++++---------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 1ac1643297..2768357034 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -50,6 +50,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps ((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: diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json index 933adb4acc..b69b1ae056 100644 --- a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-expected-conversion.json @@ -7,67 +7,67 @@ }, { "StartTime": 18559, - "Position": 459 + "Position": 482 }, { "StartTime": 18618, - "Position": 255 + "Position": 164 }, { "StartTime": 18678, - "Position": 113 - }, - { - "StartTime": 18737, "Position": 315 }, + { + "StartTime": 18737, + "Position": 145 + }, { "StartTime": 18796, - "Position": 17 + "Position": 159 }, { "StartTime": 18856, - "Position": 482 - }, - { - "StartTime": 18915, - "Position": 44 - }, - { - "StartTime": 18975, "Position": 310 }, + { + "StartTime": 18915, + "Position": 441 + }, + { + "StartTime": 18975, + "Position": 428 + }, { "StartTime": 19034, - "Position": 244 - }, - { - "StartTime": 19093, - "Position": 18 - }, - { - "StartTime": 19153, - "Position": 482 - }, - { - "StartTime": 19212, "Position": 243 }, + { + "StartTime": 19093, + "Position": 422 + }, + { + "StartTime": 19153, + "Position": 481 + }, + { + "StartTime": 19212, + "Position": 104 + }, { "StartTime": 19271, - "Position": 332 + "Position": 473 }, { "StartTime": 19331, - "Position": 477 + "Position": 135 }, { "StartTime": 19390, - "Position": 376 + "Position": 360 }, { "StartTime": 19450, - "Position": 104 + "Position": 123 } ] }] From ced4e61b54a320e2307cc60e395035b574747c8b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 21:11:56 +0900 Subject: [PATCH 037/125] Adjust expected output with spinner changes --- .../Beatmaps/basic-expected-conversion.json | 2226 ++++++++++------- 1 file changed, 1272 insertions(+), 954 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json index 9357d3b75c..8ede7b6719 100644 --- a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json @@ -1,957 +1,1275 @@ { "Mappings": [{ - "StartTime": 500.0, - "Objects": [{ - "StartTime": 500.0, - "Position": 96.0 - }, { - "StartTime": 562.0, - "Position": 100.84 - }, { - "StartTime": 625.0, - "Position": 125.0 - }, { - "StartTime": 687.0, - "Position": 152.84 - }, { - "StartTime": 750.0, - "Position": 191.0 - }, { - "StartTime": 812.0, - "Position": 212.84 - }, { - "StartTime": 875.0, - "Position": 217.0 - }, { - "StartTime": 937.0, - "Position": 234.84 - }, { - "StartTime": 1000.0, - "Position": 256.0 - }, { - "StartTime": 1062.0, - "Position": 267.84 - }, { - "StartTime": 1125.0, - "Position": 284.0 - }, { - "StartTime": 1187.0, - "Position": 311.84 - }, { - "StartTime": 1250.0, - "Position": 350.0 - }, { - "StartTime": 1312.0, - "Position": 359.84 - }, { - "StartTime": 1375.0, - "Position": 367.0 - }, { - "StartTime": 1437.0, - "Position": 400.84 - }, { - "StartTime": 1500.0, - "Position": 416.0 - }, { - "StartTime": 1562.0, - "Position": 377.159973 - }, { - "StartTime": 1625.0, - "Position": 367.0 - }, { - "StartTime": 1687.0, - "Position": 374.159973 - }, { - "StartTime": 1750.0, - "Position": 353.0 - }, { - "StartTime": 1812.0, - "Position": 329.159973 - }, { - "StartTime": 1875.0, - "Position": 288.0 - }, { - "StartTime": 1937.0, - "Position": 259.159973 - }, { - "StartTime": 2000.0, - "Position": 256.0 - }, { - "StartTime": 2058.0, - "Position": 232.44 - }, { - "StartTime": 2116.0, - "Position": 222.879974 - }, { - "StartTime": 2174.0, - "Position": 185.319992 - }, { - "StartTime": 2232.0, - "Position": 177.76001 - }, { - "StartTime": 2290.0, - "Position": 162.200012 - }, { - "StartTime": 2348.0, - "Position": 158.639984 - }, { - "StartTime": 2406.0, - "Position": 111.079994 - }, { - "StartTime": 2500.0, - "Position": 96.0 - }] - }, { - "StartTime": 3000.0, - "Objects": [{ - "StartTime": 3000.0, - "Position": 18.0 - }, { - "StartTime": 3062.0, - "Position": 482.0 - }, { - "StartTime": 3125.0, - "Position": 243.0 - }, { - "StartTime": 3187.0, - "Position": 332.0 - }, { - "StartTime": 3250.0, - "Position": 477.0 - }, { - "StartTime": 3312.0, - "Position": 376.0 - }, { - "StartTime": 3375.0, - "Position": 104.0 - }, { - "StartTime": 3437.0, - "Position": 156.0 - }, { - "StartTime": 3500.0, - "Position": 135.0 - }, { - "StartTime": 3562.0, - "Position": 256.0 - }, { - "StartTime": 3625.0, - "Position": 360.0 - }, { - "StartTime": 3687.0, - "Position": 199.0 - }, { - "StartTime": 3750.0, - "Position": 239.0 - }, { - "StartTime": 3812.0, - "Position": 326.0 - }, { - "StartTime": 3875.0, - "Position": 393.0 - }, { - "StartTime": 3937.0, - "Position": 470.0 - }, { - "StartTime": 4000.0, - "Position": 136.0 - }] - }, { - "StartTime": 4500.0, - "Objects": [{ - "StartTime": 4500.0, - "Position": 317.0 - }, { - "StartTime": 4562.0, - "Position": 354.0 - }, { - "StartTime": 4625.0, - "Position": 414.0 - }, { - "StartTime": 4687.0, - "Position": 39.0 - }, { - "StartTime": 4750.0, - "Position": 172.0 - }, { - "StartTime": 4812.0, - "Position": 479.0 - }, { - "StartTime": 4875.0, - "Position": 18.0 - }, { - "StartTime": 4937.0, - "Position": 151.0 - }, { - "StartTime": 5000.0, - "Position": 342.0 - }, { - "StartTime": 5062.0, - "Position": 400.0 - }, { - "StartTime": 5125.0, - "Position": 420.0 - }, { - "StartTime": 5187.0, - "Position": 90.0 - }, { - "StartTime": 5250.0, - "Position": 220.0 - }, { - "StartTime": 5312.0, - "Position": 80.0 - }, { - "StartTime": 5375.0, - "Position": 421.0 - }, { - "StartTime": 5437.0, - "Position": 473.0 - }, { - "StartTime": 5500.0, - "Position": 97.0 - }] - }, { - "StartTime": 6000.0, - "Objects": [{ - "StartTime": 6000.0, - "Position": 105.0 - }, { - "StartTime": 6062.0, - "Position": 249.0 - }, { - "StartTime": 6125.0, - "Position": 163.0 - }, { - "StartTime": 6187.0, - "Position": 194.0 - }, { - "StartTime": 6250.0, - "Position": 106.0 - }, { - "StartTime": 6312.0, - "Position": 212.0 - }, { - "StartTime": 6375.0, - "Position": 257.0 - }, { - "StartTime": 6437.0, - "Position": 461.0 - }, { - "StartTime": 6500.0, - "Position": 79.0 - }] - }, { - "StartTime": 7000.0, - "Objects": [{ - "StartTime": 7000.0, - "Position": 256.0 - }, { - "StartTime": 7062.0, - "Position": 294.84 - }, { - "StartTime": 7125.0, - "Position": 279.0 - }, { - "StartTime": 7187.0, - "Position": 309.84 - }, { - "StartTime": 7250.0, - "Position": 336.0 - }, { - "StartTime": 7312.0, - "Position": 322.16 - }, { - "StartTime": 7375.0, - "Position": 308.0 - }, { - "StartTime": 7437.0, - "Position": 263.16 - }, { - "StartTime": 7500.0, - "Position": 256.0 - }, { - "StartTime": 7562.0, - "Position": 261.84 - }, { - "StartTime": 7625.0, - "Position": 277.0 - }, { - "StartTime": 7687.0, - "Position": 318.84 - }, { - "StartTime": 7750.0, - "Position": 336.0 - }, { - "StartTime": 7803.0, - "Position": 305.04 - }, { - "StartTime": 7857.0, - "Position": 307.76 - }, { - "StartTime": 7910.0, - "Position": 297.8 - }, { - "StartTime": 8000.0, - "Position": 256.0 - }] - }, { - "StartTime": 8500.0, - "Objects": [{ - "StartTime": 8500.0, - "Position": 32.0 - }, { - "StartTime": 8562.0, - "Position": 22.8515015 - }, { - "StartTime": 8625.0, - "Position": 28.5659637 - }, { - "StartTime": 8687.0, - "Position": 50.3433228 - }, { - "StartTime": 8750.0, - "Position": 56.58974 - }, { - "StartTime": 8812.0, - "Position": 64.23422 - }, { - "StartTime": 8875.0, - "Position": 67.7117844 - }, { - "StartTime": 8937.0, - "Position": 90.52607 - }, { - "StartTime": 9000.0, - "Position": 101.81015 - }, { - "StartTime": 9062.0, - "Position": 113.478188 - }, { - "StartTime": 9125.0, - "Position": 159.414444 - }, { - "StartTime": 9187.0, - "Position": 155.1861 - }, { - "StartTime": 9250.0, - "Position": 179.600418 - }, { - "StartTime": 9312.0, - "Position": 212.293015 - }, { - "StartTime": 9375.0, - "Position": 197.2076 - }, { - "StartTime": 9437.0, - "Position": 243.438324 - }, { - "StartTime": 9500.0, - "Position": 237.2304 - }, { - "StartTime": 9562.0, - "Position": 241.253983 - }, { - "StartTime": 9625.0, - "Position": 258.950623 - }, { - "StartTime": 9687.0, - "Position": 253.3786 - }, { - "StartTime": 9750.0, - "Position": 270.8865 - }, { - "StartTime": 9812.0, - "Position": 244.38974 - }, { - "StartTime": 9875.0, - "Position": 242.701874 - }, { - "StartTime": 9937.0, - "Position": 256.2331 - }, { - "StartTime": 10000.0, - "Position": 270.339874 - }, { - "StartTime": 10062.0, - "Position": 275.9349 - }, { - "StartTime": 10125.0, - "Position": 297.2969 - }, { - "StartTime": 10187.0, - "Position": 307.834137 - }, { - "StartTime": 10250.0, - "Position": 321.6449 - }, { - "StartTime": 10312.0, - "Position": 357.746338 - }, { - "StartTime": 10375.0, - "Position": 358.21875 - }, { - "StartTime": 10437.0, - "Position": 394.943 - }, { - "StartTime": 10500.0, - "Position": 401.0588 - }, { - "StartTime": 10558.0, - "Position": 418.21347 - }, { - "StartTime": 10616.0, - "Position": 424.6034 - }, { - "StartTime": 10674.0, - "Position": 455.835754 - }, { - "StartTime": 10732.0, - "Position": 477.5042 - }, { - "StartTime": 10790.0, - "Position": 476.290955 - }, { - "StartTime": 10848.0, - "Position": 470.943237 - }, { - "StartTime": 10906.0, - "Position": 503.3372 - }, { - "StartTime": 10999.0, - "Position": 508.166229 - }] - }, { - "StartTime": 11500.0, - "Objects": [{ - "StartTime": 11500.0, - "Position": 321.0 - }, { - "StartTime": 11562.0, - "Position": 17.0 - }, { - "StartTime": 11625.0, - "Position": 173.0 - }, { - "StartTime": 11687.0, - "Position": 170.0 - }, { - "StartTime": 11750.0, - "Position": 447.0 - }, { - "StartTime": 11812.0, - "Position": 218.0 - }, { - "StartTime": 11875.0, - "Position": 394.0 - }, { - "StartTime": 11937.0, - "Position": 46.0 - }, { - "StartTime": 12000.0, - "Position": 480.0 - }] - }, { - "StartTime": 12500.0, - "Objects": [{ - "StartTime": 12500.0, - "Position": 512.0 - }, { - "StartTime": 12562.0, - "Position": 491.3132 - }, { - "StartTime": 12625.0, - "Position": 484.3089 - }, { - "StartTime": 12687.0, - "Position": 454.6221 - }, { - "StartTime": 12750.0, - "Position": 433.617767 - }, { - "StartTime": 12812.0, - "Position": 399.930969 - }, { - "StartTime": 12875.0, - "Position": 395.926666 - }, { - "StartTime": 12937.0, - "Position": 361.239868 - }, { - "StartTime": 13000.0, - "Position": 353.235535 - }, { - "StartTime": 13062.0, - "Position": 314.548767 - }, { - "StartTime": 13125.0, - "Position": 315.544434 - }, { - "StartTime": 13187.0, - "Position": 288.857635 - }, { - "StartTime": 13250.0, - "Position": 254.853333 - }, { - "StartTime": 13312.0, - "Position": 239.166534 - }, { - "StartTime": 13375.0, - "Position": 240.1622 - }, { - "StartTime": 13437.0, - "Position": 212.4754 - }, { - "StartTime": 13500.0, - "Position": 194.471069 - }, { - "StartTime": 13562.0, - "Position": 161.784271 - }, { - "StartTime": 13625.0, - "Position": 145.779968 - }, { - "StartTime": 13687.0, - "Position": 129.09314 - }, { - "StartTime": 13750.0, - "Position": 104.088837 - }, { - "StartTime": 13812.0, - "Position": 95.40204 - }, { - "StartTime": 13875.0, - "Position": 61.3977356 - }, { - "StartTime": 13937.0, - "Position": 56.710907 - }, { - "StartTime": 14000.0, - "Position": 35.7066345 - }, { - "StartTime": 14062.0, - "Position": 5.019806 - }, { - "StartTime": 14125.0, - "Position": 0.0 - }, { - "StartTime": 14187.0, - "Position": 39.7696266 - }, { - "StartTime": 14250.0, - "Position": 23.0119171 - }, { - "StartTime": 14312.0, - "Position": 75.94882 - }, { - "StartTime": 14375.0, - "Position": 98.19112 - }, { - "StartTime": 14437.0, - "Position": 82.12803 - }, { - "StartTime": 14500.0, - "Position": 118.370323 - }, { - "StartTime": 14562.0, - "Position": 149.307236 - }, { - "StartTime": 14625.0, - "Position": 168.549515 - }, { - "StartTime": 14687.0, - "Position": 190.486435 - }, { - "StartTime": 14750.0, - "Position": 186.728714 - }, { - "StartTime": 14812.0, - "Position": 199.665634 - }, { - "StartTime": 14875.0, - "Position": 228.907928 - }, { - "StartTime": 14937.0, - "Position": 264.844849 - }, { - "StartTime": 15000.0, - "Position": 271.087128 - }, { - "StartTime": 15062.0, - "Position": 290.024017 - }, { - "StartTime": 15125.0, - "Position": 302.266327 - }, { - "StartTime": 15187.0, - "Position": 344.203247 - }, { - "StartTime": 15250.0, - "Position": 356.445526 - }, { - "StartTime": 15312.0, - "Position": 359.382446 - }, { - "StartTime": 15375.0, - "Position": 401.624725 - }, { - "StartTime": 15437.0, - "Position": 388.561646 - }, { - "StartTime": 15500.0, - "Position": 423.803925 - }, { - "StartTime": 15562.0, - "Position": 425.740845 - }, { - "StartTime": 15625.0, - "Position": 449.983124 - }, { - "StartTime": 15687.0, - "Position": 468.920044 - }, { - "StartTime": 15750.0, - "Position": 492.162323 - }, { - "StartTime": 15812.0, - "Position": 506.784332 - }, { - "StartTime": 15875.0, - "Position": 474.226227 - }, { - "StartTime": 15937.0, - "Position": 482.978638 - }, { - "StartTime": 16000.0, - "Position": 446.420532 - }, { - "StartTime": 16058.0, - "Position": 418.4146 - }, { - "StartTime": 16116.0, - "Position": 425.408844 - }, { - "StartTime": 16174.0, - "Position": 383.402924 - }, { - "StartTime": 16232.0, - "Position": 363.397156 - }, { - "StartTime": 16290.0, - "Position": 343.391235 - }, { - "StartTime": 16348.0, - "Position": 328.385468 - }, { - "StartTime": 16406.0, - "Position": 322.3797 - }, { - "StartTime": 16500.0, - "Position": 291.1977 - }] - }, { - "StartTime": 17000.0, - "Objects": [{ - "StartTime": 17000.0, - "Position": 256.0 - }, { - "StartTime": 17062.0, - "Position": 228.16 - }, { - "StartTime": 17125.0, - "Position": 234.0 - }, { - "StartTime": 17187.0, - "Position": 202.16 - }, { - "StartTime": 17250.0, - "Position": 176.0 - }, { - "StartTime": 17312.0, - "Position": 210.84 - }, { - "StartTime": 17375.0, - "Position": 221.0 - }, { - "StartTime": 17437.0, - "Position": 219.84 - }, { - "StartTime": 17500.0, - "Position": 256.0 - }, { - "StartTime": 17562.0, - "Position": 219.16 - }, { - "StartTime": 17625.0, - "Position": 228.0 - }, { - "StartTime": 17687.0, - "Position": 203.16 - }, { - "StartTime": 17750.0, - "Position": 176.0 - }, { - "StartTime": 17803.0, - "Position": 174.959991 - }, { - "StartTime": 17857.0, - "Position": 214.23999 - }, { - "StartTime": 17910.0, - "Position": 228.200012 - }, { - "StartTime": 18000.0, - "Position": 256.0 - }] - }, { - "StartTime": 18500.0, - "Objects": [{ - "StartTime": 18500.0, - "Position": 362.0 - }, { - "StartTime": 18559.0, - "Position": 249.0 - }, { - "StartTime": 18618.0, - "Position": 357.0 - }, { - "StartTime": 18678.0, - "Position": 167.0 - }, { - "StartTime": 18737.0, - "Position": 477.0 - }, { - "StartTime": 18796.0, - "Position": 411.0 - }, { - "StartTime": 18856.0, - "Position": 254.0 - }, { - "StartTime": 18915.0, - "Position": 308.0 - }, { - "StartTime": 18975.0, - "Position": 399.0 - }, { - "StartTime": 19034.0, - "Position": 176.0 - }, { - "StartTime": 19093.0, - "Position": 14.0 - }, { - "StartTime": 19153.0, - "Position": 258.0 - }, { - "StartTime": 19212.0, - "Position": 221.0 - }, { - "StartTime": 19271.0, - "Position": 481.0 - }, { - "StartTime": 19331.0, - "Position": 92.0 - }, { - "StartTime": 19390.0, - "Position": 211.0 - }, { - "StartTime": 19450.0, - "Position": 135.0 - }] - }, { - "StartTime": 19875.0, - "Objects": [{ - "StartTime": 19875.0, - "Position": 216.0 - }, { - "StartTime": 19937.0, - "Position": 215.307053 - }, { - "StartTime": 20000.0, - "Position": 236.036865 - }, { - "StartTime": 20062.0, - "Position": 236.312088 - }, { - "StartTime": 20125.0, - "Position": 235.838928 - }, { - "StartTime": 20187.0, - "Position": 269.9743 - }, { - "StartTime": 20250.0, - "Position": 285.999146 - }, { - "StartTime": 20312.0, - "Position": 283.669067 - }, { - "StartTime": 20375.0, - "Position": 317.446747 - }, { - "StartTime": 20437.0, - "Position": 330.750275 - }, { - "StartTime": 20500.0, - "Position": 344.0156 - }, { - "StartTime": 20562.0, - "Position": 318.472168 - }, { - "StartTime": 20625.0, - "Position": 309.165466 - }, { - "StartTime": 20687.0, - "Position": 317.044617 - }, { - "StartTime": 20750.0, - "Position": 280.457367 - }, { - "StartTime": 20812.0, - "Position": 272.220581 - }, { - "StartTime": 20875.0, - "Position": 270.3294 - }, { - "StartTime": 20937.0, - "Position": 262.57605 - }, { - "StartTime": 21000.0, - "Position": 244.803329 - }, { - "StartTime": 21062.0, - "Position": 215.958359 - }, { - "StartTime": 21125.0, - "Position": 177.79332 - }, { - "StartTime": 21187.0, - "Position": 190.948349 - }, { - "StartTime": 21250.0, - "Position": 158.78334 - }, { - "StartTime": 21312.0, - "Position": 136.93837 - }, { - "StartTime": 21375.0, - "Position": 119.121056 - }, { - "StartTime": 21437.0, - "Position": 132.387573 - }, { - "StartTime": 21500.0, - "Position": 124.503014 - }, { - "StartTime": 21562.0, - "Position": 118.749374 - }, { - "StartTime": 21625.0, - "Position": 123.165535 - }, { - "StartTime": 21687.0, - "Position": 96.02999 - }, { - "StartTime": 21750.0, - "Position": 118.547928 - }, { - "StartTime": 21812.0, - "Position": 128.856232 - }, { - "StartTime": 21875.0, - "Position": 124.28746 - }, { - "StartTime": 21937.0, - "Position": 150.754929 - }, { - "StartTime": 22000.0, - "Position": 149.528732 - }, { - "StartTime": 22062.0, - "Position": 145.1691 - }, { - "StartTime": 22125.0, - "Position": 182.802155 - }, { - "StartTime": 22187.0, - "Position": 178.6452 - }, { - "StartTime": 22250.0, - "Position": 213.892181 - }, { - "StartTime": 22312.0, - "Position": 218.713028 - }, { - "StartTime": 22375.0, - "Position": 240.4715 - }, { - "StartTime": 22437.0, - "Position": 239.371887 - }, { - "StartTime": 22500.0, - "Position": 261.907257 - }, { - "StartTime": 22562.0, - "Position": 314.353119 - }, { - "StartTime": 22625.0, - "Position": 299.273376 - }, { - "StartTime": 22687.0, - "Position": 356.98288 - }, { - "StartTime": 22750.0, - "Position": 339.078552 - }, { - "StartTime": 22812.0, - "Position": 377.8958 - }, { - "StartTime": 22875.0, - "Position": 398.054047 - }, { - "StartTime": 22937.0, - "Position": 398.739441 - }, { - "StartTime": 23000.0, - "Position": 407.178467 - }, { - "StartTime": 23062.0, - "Position": 444.8687 - }, { - "StartTime": 23125.0, - "Position": 417.069977 - }, { - "StartTime": 23187.0, - "Position": 454.688477 - }, { - "StartTime": 23250.0, - "Position": 428.9612 - }, { - "StartTime": 23312.0, - "Position": 441.92807 - }, { - "StartTime": 23375.0, - "Position": 439.749878 - }, { - "StartTime": 23433.0, - "Position": 455.644684 - }, { - "StartTime": 23491.0, - "Position": 440.7359 - }, { - "StartTime": 23549.0, - "Position": 430.0944 - }, { - "StartTime": 23607.0, - "Position": 420.796173 - }, { - "StartTime": 23665.0, - "Position": 435.897461 - }, { - "StartTime": 23723.0, - "Position": 418.462555 - }, { - "StartTime": 23781.0, - "Position": 405.53775 - }, { - "StartTime": 23874.0, - "Position": 408.720825 - }] - }] + "StartTime": 500, + "Objects": [{ + "StartTime": 500, + "Position": 96 + }, + { + "StartTime": 562, + "Position": 100.84 + }, + { + "StartTime": 625, + "Position": 125 + }, + { + "StartTime": 687, + "Position": 152.84 + }, + { + "StartTime": 750, + "Position": 191 + }, + { + "StartTime": 812, + "Position": 212.84 + }, + { + "StartTime": 875, + "Position": 217 + }, + { + "StartTime": 937, + "Position": 234.84 + }, + { + "StartTime": 1000, + "Position": 256 + }, + { + "StartTime": 1062, + "Position": 267.84 + }, + { + "StartTime": 1125, + "Position": 284 + }, + { + "StartTime": 1187, + "Position": 311.84 + }, + { + "StartTime": 1250, + "Position": 350 + }, + { + "StartTime": 1312, + "Position": 359.84 + }, + { + "StartTime": 1375, + "Position": 367 + }, + { + "StartTime": 1437, + "Position": 400.84 + }, + { + "StartTime": 1500, + "Position": 416 + }, + { + "StartTime": 1562, + "Position": 377.159973 + }, + { + "StartTime": 1625, + "Position": 367 + }, + { + "StartTime": 1687, + "Position": 374.159973 + }, + { + "StartTime": 1750, + "Position": 353 + }, + { + "StartTime": 1812, + "Position": 329.159973 + }, + { + "StartTime": 1875, + "Position": 288 + }, + { + "StartTime": 1937, + "Position": 259.159973 + }, + { + "StartTime": 2000, + "Position": 256 + }, + { + "StartTime": 2062, + "Position": 231.159988 + }, + { + "StartTime": 2125, + "Position": 220 + }, + { + "StartTime": 2187, + "Position": 181.159988 + }, + { + "StartTime": 2250, + "Position": 172 + }, + { + "StartTime": 2312, + "Position": 155.159988 + }, + { + "StartTime": 2375, + "Position": 150 + }, + { + "StartTime": 2437, + "Position": 101.159988 + }, + { + "StartTime": 2500, + "Position": 96 + } + ] + }, + { + "StartTime": 3000, + "Objects": [{ + "StartTime": 3000, + "Position": 18 + }, + { + "StartTime": 3062, + "Position": 249 + }, + { + "StartTime": 3125, + "Position": 184 + }, + { + "StartTime": 3187, + "Position": 477 + }, + { + "StartTime": 3250, + "Position": 43 + }, + { + "StartTime": 3312, + "Position": 494 + }, + { + "StartTime": 3375, + "Position": 135 + }, + { + "StartTime": 3437, + "Position": 30 + }, + { + "StartTime": 3500, + "Position": 11 + }, + { + "StartTime": 3562, + "Position": 239 + }, + { + "StartTime": 3625, + "Position": 505 + }, + { + "StartTime": 3687, + "Position": 353 + }, + { + "StartTime": 3750, + "Position": 136 + }, + { + "StartTime": 3812, + "Position": 135 + }, + { + "StartTime": 3875, + "Position": 346 + }, + { + "StartTime": 3937, + "Position": 39 + }, + { + "StartTime": 4000, + "Position": 300 + } + ] + }, + { + "StartTime": 4500, + "Objects": [{ + "StartTime": 4500, + "Position": 398 + }, + { + "StartTime": 4562, + "Position": 151 + }, + { + "StartTime": 4625, + "Position": 73 + }, + { + "StartTime": 4687, + "Position": 311 + }, + { + "StartTime": 4750, + "Position": 90 + }, + { + "StartTime": 4812, + "Position": 264 + }, + { + "StartTime": 4875, + "Position": 477 + }, + { + "StartTime": 4937, + "Position": 473 + }, + { + "StartTime": 5000, + "Position": 120 + }, + { + "StartTime": 5062, + "Position": 115 + }, + { + "StartTime": 5125, + "Position": 163 + }, + { + "StartTime": 5187, + "Position": 447 + }, + { + "StartTime": 5250, + "Position": 72 + }, + { + "StartTime": 5312, + "Position": 257 + }, + { + "StartTime": 5375, + "Position": 153 + }, + { + "StartTime": 5437, + "Position": 388 + }, + { + "StartTime": 5500, + "Position": 336 + } + ] + }, + { + "StartTime": 6000, + "Objects": [{ + "StartTime": 6000, + "Position": 13 + }, + { + "StartTime": 6062, + "Position": 429 + }, + { + "StartTime": 6125, + "Position": 381 + }, + { + "StartTime": 6187, + "Position": 186 + }, + { + "StartTime": 6250, + "Position": 267 + }, + { + "StartTime": 6312, + "Position": 305 + }, + { + "StartTime": 6375, + "Position": 456 + }, + { + "StartTime": 6437, + "Position": 26 + }, + { + "StartTime": 6500, + "Position": 238 + } + ] + }, + { + "StartTime": 7000, + "Objects": [{ + "StartTime": 7000, + "Position": 256 + }, + { + "StartTime": 7062, + "Position": 262.84 + }, + { + "StartTime": 7125, + "Position": 295 + }, + { + "StartTime": 7187, + "Position": 303.84 + }, + { + "StartTime": 7250, + "Position": 336 + }, + { + "StartTime": 7312, + "Position": 319.16 + }, + { + "StartTime": 7375, + "Position": 306 + }, + { + "StartTime": 7437, + "Position": 272.16 + }, + { + "StartTime": 7500, + "Position": 256 + }, + { + "StartTime": 7562, + "Position": 255.84 + }, + { + "StartTime": 7625, + "Position": 300 + }, + { + "StartTime": 7687, + "Position": 320.84 + }, + { + "StartTime": 7750, + "Position": 336 + }, + { + "StartTime": 7812, + "Position": 316.16 + }, + { + "StartTime": 7875, + "Position": 278 + }, + { + "StartTime": 7937, + "Position": 257.16 + }, + { + "StartTime": 8000, + "Position": 256 + } + ] + }, + { + "StartTime": 8500, + "Objects": [{ + "StartTime": 8500, + "Position": 32 + }, + { + "StartTime": 8562, + "Position": 21.8515015 + }, + { + "StartTime": 8625, + "Position": 44.5659637 + }, + { + "StartTime": 8687, + "Position": 33.3433228 + }, + { + "StartTime": 8750, + "Position": 63.58974 + }, + { + "StartTime": 8812, + "Position": 71.23422 + }, + { + "StartTime": 8875, + "Position": 62.7117844 + }, + { + "StartTime": 8937, + "Position": 65.52607 + }, + { + "StartTime": 9000, + "Position": 101.81015 + }, + { + "StartTime": 9062, + "Position": 134.47818 + }, + { + "StartTime": 9125, + "Position": 141.414444 + }, + { + "StartTime": 9187, + "Position": 164.1861 + }, + { + "StartTime": 9250, + "Position": 176.600418 + }, + { + "StartTime": 9312, + "Position": 184.293015 + }, + { + "StartTime": 9375, + "Position": 212.2076 + }, + { + "StartTime": 9437, + "Position": 236.438324 + }, + { + "StartTime": 9500, + "Position": 237.2304 + }, + { + "StartTime": 9562, + "Position": 241.253983 + }, + { + "StartTime": 9625, + "Position": 233.950623 + }, + { + "StartTime": 9687, + "Position": 265.3786 + }, + { + "StartTime": 9750, + "Position": 236.8865 + }, + { + "StartTime": 9812, + "Position": 273.38974 + }, + { + "StartTime": 9875, + "Position": 267.701874 + }, + { + "StartTime": 9937, + "Position": 263.2331 + }, + { + "StartTime": 10000, + "Position": 270.339874 + }, + { + "StartTime": 10062, + "Position": 291.9349 + }, + { + "StartTime": 10125, + "Position": 294.2969 + }, + { + "StartTime": 10187, + "Position": 307.834137 + }, + { + "StartTime": 10250, + "Position": 310.6449 + }, + { + "StartTime": 10312, + "Position": 344.746338 + }, + { + "StartTime": 10375, + "Position": 349.21875 + }, + { + "StartTime": 10437, + "Position": 373.943 + }, + { + "StartTime": 10500, + "Position": 401.0588 + }, + { + "StartTime": 10562, + "Position": 422.44046 + }, + { + "StartTime": 10625, + "Position": 434.209717 + }, + { + "StartTime": 10687, + "Position": 437.275177 + }, + { + "StartTime": 10750, + "Position": 456.6923 + }, + { + "StartTime": 10812, + "Position": 490.584229 + }, + { + "StartTime": 10875, + "Position": 493.13208 + }, + { + "StartTime": 10937, + "Position": 496.8966 + }, + { + "StartTime": 10999, + "Position": 508.166229 + } + ] + }, + { + "StartTime": 11500, + "Objects": [{ + "StartTime": 11500, + "Position": 97 + }, + { + "StartTime": 11562, + "Position": 267 + }, + { + "StartTime": 11625, + "Position": 116 + }, + { + "StartTime": 11687, + "Position": 451 + }, + { + "StartTime": 11750, + "Position": 414 + }, + { + "StartTime": 11812, + "Position": 88 + }, + { + "StartTime": 11875, + "Position": 257 + }, + { + "StartTime": 11937, + "Position": 175 + }, + { + "StartTime": 12000, + "Position": 38 + } + ] + }, + { + "StartTime": 12500, + "Objects": [{ + "StartTime": 12500, + "Position": 512 + }, + { + "StartTime": 12562, + "Position": 494.3132 + }, + { + "StartTime": 12625, + "Position": 461.3089 + }, + { + "StartTime": 12687, + "Position": 469.6221 + }, + { + "StartTime": 12750, + "Position": 441.617767 + }, + { + "StartTime": 12812, + "Position": 402.930969 + }, + { + "StartTime": 12875, + "Position": 407.926666 + }, + { + "StartTime": 12937, + "Position": 364.239868 + }, + { + "StartTime": 13000, + "Position": 353.235535 + }, + { + "StartTime": 13062, + "Position": 320.548767 + }, + { + "StartTime": 13125, + "Position": 303.544434 + }, + { + "StartTime": 13187, + "Position": 295.857635 + }, + { + "StartTime": 13250, + "Position": 265.853333 + }, + { + "StartTime": 13312, + "Position": 272.166534 + }, + { + "StartTime": 13375, + "Position": 240.1622 + }, + { + "StartTime": 13437, + "Position": 229.4754 + }, + { + "StartTime": 13500, + "Position": 194.471069 + }, + { + "StartTime": 13562, + "Position": 158.784271 + }, + { + "StartTime": 13625, + "Position": 137.779968 + }, + { + "StartTime": 13687, + "Position": 147.09314 + }, + { + "StartTime": 13750, + "Position": 122.088837 + }, + { + "StartTime": 13812, + "Position": 77.40204 + }, + { + "StartTime": 13875, + "Position": 79.3977356 + }, + { + "StartTime": 13937, + "Position": 56.710907 + }, + { + "StartTime": 14000, + "Position": 35.7066345 + }, + { + "StartTime": 14062, + "Position": 1.01980591 + }, + { + "StartTime": 14125, + "Position": 0 + }, + { + "StartTime": 14187, + "Position": 21.7696266 + }, + { + "StartTime": 14250, + "Position": 49.0119171 + }, + { + "StartTime": 14312, + "Position": 48.9488258 + }, + { + "StartTime": 14375, + "Position": 87.19112 + }, + { + "StartTime": 14437, + "Position": 97.12803 + }, + { + "StartTime": 14500, + "Position": 118.370323 + }, + { + "StartTime": 14562, + "Position": 130.307236 + }, + { + "StartTime": 14625, + "Position": 154.549515 + }, + { + "StartTime": 14687, + "Position": 190.486435 + }, + { + "StartTime": 14750, + "Position": 211.728714 + }, + { + "StartTime": 14812, + "Position": 197.665634 + }, + { + "StartTime": 14875, + "Position": 214.907928 + }, + { + "StartTime": 14937, + "Position": 263.844849 + }, + { + "StartTime": 15000, + "Position": 271.087128 + }, + { + "StartTime": 15062, + "Position": 270.024017 + }, + { + "StartTime": 15125, + "Position": 308.266327 + }, + { + "StartTime": 15187, + "Position": 313.203247 + }, + { + "StartTime": 15250, + "Position": 328.445526 + }, + { + "StartTime": 15312, + "Position": 370.382446 + }, + { + "StartTime": 15375, + "Position": 387.624725 + }, + { + "StartTime": 15437, + "Position": 421.561646 + }, + { + "StartTime": 15500, + "Position": 423.803925 + }, + { + "StartTime": 15562, + "Position": 444.740845 + }, + { + "StartTime": 15625, + "Position": 469.983124 + }, + { + "StartTime": 15687, + "Position": 473.920044 + }, + { + "StartTime": 15750, + "Position": 501.162323 + }, + { + "StartTime": 15812, + "Position": 488.784332 + }, + { + "StartTime": 15875, + "Position": 466.226227 + }, + { + "StartTime": 15937, + "Position": 445.978638 + }, + { + "StartTime": 16000, + "Position": 446.420532 + }, + { + "StartTime": 16062, + "Position": 427.1729 + }, + { + "StartTime": 16125, + "Position": 417.6148 + }, + { + "StartTime": 16187, + "Position": 370.367218 + }, + { + "StartTime": 16250, + "Position": 365.8091 + }, + { + "StartTime": 16312, + "Position": 343.561523 + }, + { + "StartTime": 16375, + "Position": 332.003418 + }, + { + "StartTime": 16437, + "Position": 327.755829 + }, + { + "StartTime": 16500, + "Position": 291.1977 + } + ] + }, + { + "StartTime": 17000, + "Objects": [{ + "StartTime": 17000, + "Position": 256 + }, + { + "StartTime": 17062, + "Position": 247.16 + }, + { + "StartTime": 17125, + "Position": 211 + }, + { + "StartTime": 17187, + "Position": 183.16 + }, + { + "StartTime": 17250, + "Position": 176 + }, + { + "StartTime": 17312, + "Position": 204.84 + }, + { + "StartTime": 17375, + "Position": 218 + }, + { + "StartTime": 17437, + "Position": 231.84 + }, + { + "StartTime": 17500, + "Position": 256 + }, + { + "StartTime": 17562, + "Position": 229.16 + }, + { + "StartTime": 17625, + "Position": 227 + }, + { + "StartTime": 17687, + "Position": 186.16 + }, + { + "StartTime": 17750, + "Position": 176 + }, + { + "StartTime": 17812, + "Position": 214.84 + }, + { + "StartTime": 17875, + "Position": 203 + }, + { + "StartTime": 17937, + "Position": 233.84 + }, + { + "StartTime": 18000, + "Position": 256 + } + ] + }, + { + "StartTime": 18500, + "Objects": [{ + "StartTime": 18500, + "Position": 437 + }, + { + "StartTime": 18559, + "Position": 289 + }, + { + "StartTime": 18618, + "Position": 464 + }, + { + "StartTime": 18678, + "Position": 36 + }, + { + "StartTime": 18737, + "Position": 378 + }, + { + "StartTime": 18796, + "Position": 297 + }, + { + "StartTime": 18856, + "Position": 418 + }, + { + "StartTime": 18915, + "Position": 329 + }, + { + "StartTime": 18975, + "Position": 338 + }, + { + "StartTime": 19034, + "Position": 394 + }, + { + "StartTime": 19093, + "Position": 40 + }, + { + "StartTime": 19153, + "Position": 13 + }, + { + "StartTime": 19212, + "Position": 80 + }, + { + "StartTime": 19271, + "Position": 138 + }, + { + "StartTime": 19331, + "Position": 311 + }, + { + "StartTime": 19390, + "Position": 216 + }, + { + "StartTime": 19450, + "Position": 310 + } + ] + }, + { + "StartTime": 19875, + "Objects": [{ + "StartTime": 19875, + "Position": 216 + }, + { + "StartTime": 19937, + "Position": 228.307053 + }, + { + "StartTime": 20000, + "Position": 214.036865 + }, + { + "StartTime": 20062, + "Position": 224.312088 + }, + { + "StartTime": 20125, + "Position": 253.838928 + }, + { + "StartTime": 20187, + "Position": 259.9743 + }, + { + "StartTime": 20250, + "Position": 299.999146 + }, + { + "StartTime": 20312, + "Position": 289.669067 + }, + { + "StartTime": 20375, + "Position": 317.446747 + }, + { + "StartTime": 20437, + "Position": 344.750275 + }, + { + "StartTime": 20500, + "Position": 328.0156 + }, + { + "StartTime": 20562, + "Position": 331.472168 + }, + { + "StartTime": 20625, + "Position": 302.165466 + }, + { + "StartTime": 20687, + "Position": 303.044617 + }, + { + "StartTime": 20750, + "Position": 306.457367 + }, + { + "StartTime": 20812, + "Position": 265.220581 + }, + { + "StartTime": 20875, + "Position": 270.3294 + }, + { + "StartTime": 20937, + "Position": 257.57605 + }, + { + "StartTime": 21000, + "Position": 247.803329 + }, + { + "StartTime": 21062, + "Position": 225.958359 + }, + { + "StartTime": 21125, + "Position": 201.79332 + }, + { + "StartTime": 21187, + "Position": 170.948349 + }, + { + "StartTime": 21250, + "Position": 146.78334 + }, + { + "StartTime": 21312, + "Position": 149.93837 + }, + { + "StartTime": 21375, + "Position": 119.121056 + }, + { + "StartTime": 21437, + "Position": 133.387573 + }, + { + "StartTime": 21500, + "Position": 117.503014 + }, + { + "StartTime": 21562, + "Position": 103.749374 + }, + { + "StartTime": 21625, + "Position": 127.165535 + }, + { + "StartTime": 21687, + "Position": 113.029991 + }, + { + "StartTime": 21750, + "Position": 101.547928 + }, + { + "StartTime": 21812, + "Position": 133.856232 + }, + { + "StartTime": 21875, + "Position": 124.28746 + }, + { + "StartTime": 21937, + "Position": 121.754929 + }, + { + "StartTime": 22000, + "Position": 155.528732 + }, + { + "StartTime": 22062, + "Position": 142.1691 + }, + { + "StartTime": 22125, + "Position": 186.802155 + }, + { + "StartTime": 22187, + "Position": 198.6452 + }, + { + "StartTime": 22250, + "Position": 191.892181 + }, + { + "StartTime": 22312, + "Position": 232.713028 + }, + { + "StartTime": 22375, + "Position": 240.4715 + }, + { + "StartTime": 22437, + "Position": 278.3719 + }, + { + "StartTime": 22500, + "Position": 288.907257 + }, + { + "StartTime": 22562, + "Position": 297.353119 + }, + { + "StartTime": 22625, + "Position": 301.273376 + }, + { + "StartTime": 22687, + "Position": 339.98288 + }, + { + "StartTime": 22750, + "Position": 353.078552 + }, + { + "StartTime": 22812, + "Position": 363.8958 + }, + { + "StartTime": 22875, + "Position": 398.054047 + }, + { + "StartTime": 22937, + "Position": 419.739441 + }, + { + "StartTime": 23000, + "Position": 435.178467 + }, + { + "StartTime": 23062, + "Position": 420.8687 + }, + { + "StartTime": 23125, + "Position": 448.069977 + }, + { + "StartTime": 23187, + "Position": 425.688477 + }, + { + "StartTime": 23250, + "Position": 426.9612 + }, + { + "StartTime": 23312, + "Position": 454.92807 + }, + { + "StartTime": 23375, + "Position": 439.749878 + }, + { + "StartTime": 23437, + "Position": 440.540833 + }, + { + "StartTime": 23500, + "Position": 445.371735 + }, + { + "StartTime": 23562, + "Position": 431.408173 + }, + { + "StartTime": 23625, + "Position": 414.647522 + }, + { + "StartTime": 23687, + "Position": 406.2767 + }, + { + "StartTime": 23750, + "Position": 407.2297 + }, + { + "StartTime": 23812, + "Position": 403.716827 + }, + { + "StartTime": 23874, + "Position": 408.720825 + } + ] + } + ] } \ No newline at end of file From 6867a398cadb5826dfa8c8e6088dea5ab97a74ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 21:12:08 +0900 Subject: [PATCH 038/125] Add one more test case --- .../CatchBeatmapConversionTest.cs | 1 + ...inner-and-circles-expected-conversion.json | 65 +++++++++++++++++++ .../Testing/Beatmaps/spinner-and-circles.osu | 24 +++++++ 3 files changed, 90 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles-expected-conversion.json create mode 100644 osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles.osu diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 9de0ce3565..820929bb4c 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("basic"), Ignore("See: https://github.com/ppy/osu/issues/2232")] [TestCase("spinner")] + [TestCase("spinner-and-circles")] public new void Test(string name) { base.Test(name); diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles-expected-conversion.json new file mode 100644 index 0000000000..dd81947f1c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles-expected-conversion.json @@ -0,0 +1,65 @@ +{ + "Mappings": [{ + "StartTime": 2589, + "Objects": [{ + "StartTime": 2589, + "Position": 256 + }] + }, + { + "StartTime": 2915, + "Objects": [{ + "StartTime": 2915, + "Position": 65 + }, + { + "StartTime": 2916, + "Position": 482 + } + ] + }, + { + "StartTime": 3078, + "Objects": [{ + "StartTime": 3078, + "Position": 164 + }, + { + "StartTime": 3079, + "Position": 315 + } + ] + }, + { + "StartTime": 3241, + "Objects": [{ + "StartTime": 3241, + "Position": 145 + }, + { + "StartTime": 3242, + "Position": 159 + } + ] + }, + { + "StartTime": 3404, + "Objects": [{ + "StartTime": 3404, + "Position": 310 + }, + { + "StartTime": 3405, + "Position": 441 + } + ] + }, + { + "StartTime": 5197, + "Objects": [{ + "StartTime": 5197, + "Position": 256 + }] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles.osu new file mode 100644 index 0000000000..9a90768428 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/spinner-and-circles.osu @@ -0,0 +1,24 @@ +osu file format v14 + +[General] +StackLeniency: 0.7 +Mode: 2 + +[Difficulty] +HPDrainRate:5 +CircleSize:2 +OverallDifficulty:5 +ApproachRate:8 +SliderMultiplier:1.4 +SliderTickRate:4 + +[TimingPoints] +2589,326.086956521739,4,2,1,70,1,0 + +[HitObjects] +256,192,2589,5,0,0:0:0:0: +256,192,2915,12,0,2916,0:0:0:0: +256,192,3078,12,0,3079,0:0:0:0: +256,192,3241,12,0,3242,0:0:0:0: +256,192,3404,12,0,3405,0:0:0:0: +256,192,5197,5,0,0:0:0:0: From 31bd59442f9bef317802e2a0f6f605c1c833125b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 21:15:10 +0900 Subject: [PATCH 039/125] Remove banana positioning comment --- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index 4590856d98..4dd491966c 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -30,8 +30,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new Banana { Samples = Samples, - StartTime = i, - X = 0 // The position will be set on the post processing + StartTime = i }); } From e840083ab4b6315b2f1c4ff24fc5940dfb81c363 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 22:22:29 +0900 Subject: [PATCH 040/125] Oops fix incorrectly changed file --- .../Beatmaps/basic-expected-conversion.json | 136 +++++++++--------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json index 8ede7b6719..b65d54a565 100644 --- a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/basic-expected-conversion.json @@ -102,32 +102,32 @@ "Position": 256 }, { - "StartTime": 2062, - "Position": 231.159988 + "StartTime": 2058, + "Position": 232.44 }, { - "StartTime": 2125, - "Position": 220 + "StartTime": 2116, + "Position": 222.879974 }, { - "StartTime": 2187, - "Position": 181.159988 + "StartTime": 2174, + "Position": 185.319992 }, { - "StartTime": 2250, - "Position": 172 + "StartTime": 2232, + "Position": 177.76001 }, { - "StartTime": 2312, - "Position": 155.159988 + "StartTime": 2290, + "Position": 162.200012 }, { - "StartTime": 2375, - "Position": 150 + "StartTime": 2348, + "Position": 158.639984 }, { - "StartTime": 2437, - "Position": 101.159988 + "StartTime": 2406, + "Position": 111.079994 }, { "StartTime": 2500, @@ -374,16 +374,16 @@ "Position": 336 }, { - "StartTime": 7812, - "Position": 316.16 + "StartTime": 7803, + "Position": 319.04 }, { - "StartTime": 7875, - "Position": 278 + "StartTime": 7857, + "Position": 283.76 }, { - "StartTime": 7937, - "Position": 257.16 + "StartTime": 7910, + "Position": 265.8 }, { "StartTime": 8000, @@ -526,32 +526,32 @@ "Position": 401.0588 }, { - "StartTime": 10562, - "Position": 422.44046 + "StartTime": 10558, + "Position": 421.21347 }, { - "StartTime": 10625, - "Position": 434.209717 + "StartTime": 10616, + "Position": 431.6034 }, { - "StartTime": 10687, - "Position": 437.275177 + "StartTime": 10674, + "Position": 433.835754 }, { - "StartTime": 10750, - "Position": 456.6923 + "StartTime": 10732, + "Position": 452.5042 }, { - "StartTime": 10812, - "Position": 490.584229 + "StartTime": 10790, + "Position": 486.290955 }, { - "StartTime": 10875, - "Position": 493.13208 + "StartTime": 10848, + "Position": 488.943237 }, { - "StartTime": 10937, - "Position": 496.8966 + "StartTime": 10906, + "Position": 493.3372 }, { "StartTime": 10999, @@ -830,32 +830,32 @@ "Position": 446.420532 }, { - "StartTime": 16062, - "Position": 427.1729 + "StartTime": 16058, + "Position": 428.4146 }, { - "StartTime": 16125, - "Position": 417.6148 + "StartTime": 16116, + "Position": 420.408844 }, { - "StartTime": 16187, - "Position": 370.367218 + "StartTime": 16174, + "Position": 374.402924 }, { - "StartTime": 16250, - "Position": 365.8091 + "StartTime": 16232, + "Position": 371.397156 }, { - "StartTime": 16312, - "Position": 343.561523 + "StartTime": 16290, + "Position": 350.391235 }, { - "StartTime": 16375, - "Position": 332.003418 + "StartTime": 16348, + "Position": 340.385468 }, { - "StartTime": 16437, - "Position": 327.755829 + "StartTime": 16406, + "Position": 337.3797 }, { "StartTime": 16500, @@ -918,16 +918,16 @@ "Position": 176 }, { - "StartTime": 17812, - "Position": 214.84 + "StartTime": 17803, + "Position": 211.959991 }, { - "StartTime": 17875, - "Position": 203 + "StartTime": 17857, + "Position": 197.23999 }, { - "StartTime": 17937, - "Position": 233.84 + "StartTime": 17910, + "Position": 225.200012 }, { "StartTime": 18000, @@ -1238,32 +1238,32 @@ "Position": 439.749878 }, { - "StartTime": 23437, - "Position": 440.540833 + "StartTime": 23433, + "Position": 440.644684 }, { - "StartTime": 23500, - "Position": 445.371735 + "StartTime": 23491, + "Position": 445.7359 }, { - "StartTime": 23562, - "Position": 431.408173 + "StartTime": 23549, + "Position": 432.0944 }, { - "StartTime": 23625, - "Position": 414.647522 + "StartTime": 23607, + "Position": 415.796173 }, { - "StartTime": 23687, - "Position": 406.2767 + "StartTime": 23665, + "Position": 407.897461 }, { - "StartTime": 23750, - "Position": 407.2297 + "StartTime": 23723, + "Position": 409.462555 }, { - "StartTime": 23812, - "Position": 403.716827 + "StartTime": 23781, + "Position": 406.53775 }, { "StartTime": 23874, From b97c415c50a17423c6e10e9255fb47ee0a622c77 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 14:16:58 +0900 Subject: [PATCH 041/125] Fix memory leak due to incorrect binding --- osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index 240d8dc396..35146dfe29 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor }; this.beatmap.BindTo(beatmap); - beatmap.ValueChanged += v => calculateScale(); + this.beatmap.ValueChanged += v => calculateScale(); cursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); cursorScale.ValueChanged += v => calculateScale(); From caeddc861ab7cdfc65813c185417c8ec4950b43d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 15:12:10 +0900 Subject: [PATCH 042/125] Add test for WorkingBeatmap leakage --- osu.Game/Tests/Visual/TestCasePlayer.cs | 34 ++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 3cdc496ee1..55fb9c483b 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -1,9 +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.Framework.Allocation; using osu.Framework.Graphics.Shapes; +using osu.Framework.Lists; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -43,6 +46,7 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset)); AddUntilStep(() => ContinueCondition(p)); + } else { @@ -51,6 +55,20 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(r.Name, () => p = loadPlayerFor(r)); AddUntilStep(() => ContinueCondition(p)); + AddAssert("no leaked beatmaps", () => + { + p = null; + + GC.Collect(); + GC.WaitForPendingFinalizers(); + int count = 0; + + workingWeakReferences.ForEachAlive(_ => count++); + + Logger.Log($"reference count {count}"); + + return count == 1; + }); } } } @@ -59,21 +77,29 @@ namespace osu.Game.Tests.Visual protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); + private readonly WeakList workingWeakReferences = new WeakList(); + private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); private Player loadPlayerFor(Ruleset r) { var beatmap = CreateBeatmap(r); + var working = new TestWorkingBeatmap(beatmap); - Beatmap.Value = new TestWorkingBeatmap(beatmap); + workingWeakReferences.Add(working); + + Beatmap.Value = working; Beatmap.Value.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; - if (Player != null) - Remove(Player); + Player?.Exit(); var player = CreatePlayer(r); - LoadComponentAsync(player, LoadScreen); + LoadComponentAsync(player, p => + { + Player = p; + LoadScreen(p); + }); return player; } From cb73f215ac126c21553b9f691e134e1bc64f8592 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 15:26:05 +0900 Subject: [PATCH 043/125] Add check for player screens too --- osu.Game/Tests/Visual/TestCasePlayer.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 55fb9c483b..beaa6bb43a 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics.Shapes; using osu.Framework.Lists; -using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -55,6 +54,7 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(r.Name, () => p = loadPlayerFor(r)); AddUntilStep(() => ContinueCondition(p)); + AddAssert("no leaked beatmaps", () => { p = null; @@ -64,9 +64,16 @@ namespace osu.Game.Tests.Visual int count = 0; workingWeakReferences.ForEachAlive(_ => count++); + return count == 1; + }); - Logger.Log($"reference count {count}"); + AddAssert("no leaked players", () => + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + int count = 0; + playerWeakReferences.ForEachAlive(_ => count++); return count == 1; }); } @@ -78,6 +85,7 @@ namespace osu.Game.Tests.Visual protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); private readonly WeakList workingWeakReferences = new WeakList(); + private readonly WeakList playerWeakReferences = new WeakList(); private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); @@ -95,6 +103,8 @@ namespace osu.Game.Tests.Visual var player = CreatePlayer(r); + playerWeakReferences.Add(player); + LoadComponentAsync(player, p => { Player = p; From d259b31893b6deb0c08e49ae643a190cea0068e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 15:43:00 +0900 Subject: [PATCH 044/125] Fix empty line --- osu.Game/Tests/Visual/TestCasePlayer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index beaa6bb43a..20c9646aa3 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -45,7 +45,6 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset)); AddUntilStep(() => ContinueCondition(p)); - } else { From 9709a40c5455b2191a5b806e788b520484cb149e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 21:46:47 +0900 Subject: [PATCH 045/125] Fix conversion test failing --- .../CatchBeatmapConversionTest.cs | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 820929bb4c..89e8361a72 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Newtonsoft.Json; using NUnit.Framework; using osu.Framework.MathUtils; using osu.Game.Rulesets.Catch.Objects; @@ -29,33 +30,15 @@ namespace osu.Game.Rulesets.Catch.Tests if (hitObject is JuiceStream stream) { foreach (var nested in stream.NestedHitObjects) - { - yield return new ConvertValue - { - StartTime = nested.StartTime, - Position = ((CatchHitObject)nested).X * CatchPlayfield.BASE_WIDTH - }; - } + yield return new ConvertValue((CatchHitObject)nested); } else if (hitObject is BananaShower shower) { foreach (var nested in shower.NestedHitObjects) - { - yield return new ConvertValue - { - StartTime = nested.StartTime, - Position = ((CatchHitObject)nested).X * CatchPlayfield.BASE_WIDTH - }; - } + yield return new ConvertValue((CatchHitObject)nested); } else - { - yield return new ConvertValue - { - StartTime = hitObject.StartTime, - Position = ((CatchHitObject)hitObject).X * CatchPlayfield.BASE_WIDTH - }; - } + yield return new ConvertValue((CatchHitObject)hitObject); } protected override Ruleset CreateRuleset() => new CatchRuleset(); @@ -68,8 +51,31 @@ namespace osu.Game.Rulesets.Catch.Tests /// private const float conversion_lenience = 2; - public double StartTime; - public float Position; + [JsonIgnore] + public readonly CatchHitObject HitObject; + + public ConvertValue(CatchHitObject hitObject) + { + HitObject = hitObject; + startTime = 0; + position = 0; + } + + private double startTime; + + public double StartTime + { + get => HitObject?.StartTime ?? startTime; + set => startTime = value; + } + + private float position; + + public float Position + { + get => HitObject?.X * CatchPlayfield.BASE_WIDTH ?? position; + set => position = value; + } public bool Equals(ConvertValue other) => Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience) From f0fbc04d92cbafae7a9a71a8f017cc4794448978 Mon Sep 17 00:00:00 2001 From: HoutarouOreki Date: Fri, 15 Jun 2018 14:11:21 +0200 Subject: [PATCH 046/125] 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 047/125] 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 048/125] 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 049/125] 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 050/125] 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 0d154621b6198a3dc57e4a6507ab44a921ee6d6f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 16:03:00 +0900 Subject: [PATCH 051/125] Cleanup testcase --- .../Visual/TestCaseEditorSeekSnapping.cs | 63 +++++++------------ 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs index 94b99d483c..5ab183f09b 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs @@ -1,8 +1,7 @@ // 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 NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -10,9 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Beatmaps; using OpenTK; @@ -22,8 +18,6 @@ namespace osu.Game.Tests.Visual { public class TestCaseEditorSeekSnapping : EditorClockTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(HitObjectComposer) }; - public TestCaseEditorSeekSnapping() { BeatDivisor.Value = 4; @@ -56,22 +50,13 @@ namespace osu.Game.Tests.Visual Beatmap.Value = new TestWorkingBeatmap(testBeatmap); Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock }; - - testSeekNoSnapping(); - testSeekSnappingOnBeat(); - testSeekSnappingInBetweenBeat(); - testSeekForwardNoSnapping(); - testSeekForwardSnappingOnBeat(); - testSeekForwardSnappingFromInBetweenBeat(); - testSeekBackwardSnappingOnBeat(); - testSeekBackwardSnappingFromInBetweenBeat(); - testSeekingWithFloatingPointBeatLength(); } /// /// Tests whether time is correctly seeked without snapping. /// - private void testSeekNoSnapping() + [Test] + public void TestSeekNoSnapping() { reset(); @@ -94,7 +79,8 @@ namespace osu.Game.Tests.Visual /// Tests whether seeking to exact beat times puts us on the beat time. /// These are the white/yellow ticks on the graph. /// - private void testSeekSnappingOnBeat() + [Test] + public void TestSeekSnappingOnBeat() { reset(); @@ -117,9 +103,9 @@ namespace osu.Game.Tests.Visual /// /// Tests whether seeking to somewhere in the middle between beats puts us on the expected beats. /// For example, snapping between a white/yellow beat should put us on either the yellow or white, depending on which one we're closer too. - /// If /// - private void testSeekSnappingInBetweenBeat() + [Test] + public void TestSeekSnappingInBetweenBeat() { reset(); @@ -140,7 +126,8 @@ namespace osu.Game.Tests.Visual /// /// Tests that when seeking forward with no beat snapping, beats are never explicitly snapped to, nor the next timing point (if we've skipped it). /// - private void testSeekForwardNoSnapping() + [Test] + public void TestSeekForwardNoSnapping() { reset(); @@ -159,7 +146,8 @@ namespace osu.Game.Tests.Visual /// /// Tests that when seeking forward with beat snapping, all beats are snapped to and timing points are never skipped. /// - private void testSeekForwardSnappingOnBeat() + [Test] + public void TestSeekForwardSnappingOnBeat() { reset(); @@ -181,7 +169,8 @@ namespace osu.Game.Tests.Visual /// Tests that when seeking forward from in-between two beats, the next beat or timing point is snapped to, and no beats are skipped. /// This will also test being extremely close to the next beat/timing point, to ensure rounding is not an issue. /// - private void testSeekForwardSnappingFromInBetweenBeat() + [Test] + public void TestSeekForwardSnappingFromInBetweenBeat() { reset(); @@ -214,7 +203,8 @@ namespace osu.Game.Tests.Visual /// /// Tests that when seeking backward with no beat snapping, beats are never explicitly snapped to, nor the next timing point (if we've skipped it). /// - private void testSeekBackwardNoSnapping() + [Test] + public void TestSeekBackwardNoSnapping() { reset(); @@ -236,7 +226,8 @@ namespace osu.Game.Tests.Visual /// /// Tests that when seeking backward with beat snapping, all beats are snapped to and timing points are never skipped. /// - private void testSeekBackwardSnappingOnBeat() + [Test] + public void TestSeekBackwardSnappingOnBeat() { reset(); @@ -259,7 +250,8 @@ namespace osu.Game.Tests.Visual /// Tests that when seeking backward from in-between two beats, the previous beat or timing point is snapped to, and no beats are skipped. /// This will also test being extremely close to the previous beat/timing point, to ensure rounding is not an issue. /// - private void testSeekBackwardSnappingFromInBetweenBeat() + [Test] + public void TestSeekBackwardSnappingFromInBetweenBeat() { reset(); @@ -280,7 +272,8 @@ namespace osu.Game.Tests.Visual /// /// Tests that there are no rounding issues when snapping to beats within a timing point with a floating-point beatlength. /// - private void testSeekingWithFloatingPointBeatLength() + [Test] + public void TestSeekingWithFloatingPointBeatLength() { reset(); @@ -288,7 +281,7 @@ namespace osu.Game.Tests.Visual AddStep("Seek(0)", () => Clock.Seek(0)); - for (int i = 0; i < 20; i++) + for (int i = 0; i < 9; i++) { AddStep("SeekForward, Snap", () => { @@ -298,7 +291,7 @@ namespace osu.Game.Tests.Visual AddAssert("Time > lastTime", () => Clock.CurrentTime > lastTime); } - for (int i = 0; i < 20; i++) + for (int i = 0; i < 9; i++) { AddStep("SeekBackward, Snap", () => { @@ -316,16 +309,6 @@ namespace osu.Game.Tests.Visual AddStep("Reset", () => Clock.Seek(0)); } - private class TestHitObjectComposer : HitObjectComposer - { - public TestHitObjectComposer(Ruleset ruleset) - : base(ruleset) - { - } - - protected override IReadOnlyList CompositionTools => new ICompositionTool[0]; - } - private class TimingPointVisualiser : CompositeDrawable { private readonly double length; From ffc5d7bd4378c8aa61ac3a2a2e4645ae59504849 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 16:28:17 +0900 Subject: [PATCH 052/125] Fix some incorrect test case values --- osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs index 5ab183f09b..d6771ebd21 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs @@ -210,15 +210,13 @@ namespace osu.Game.Tests.Visual AddStep("Seek(450)", () => Clock.Seek(450)); AddStep("SeekBackward", () => Clock.SeekBackward()); - AddAssert("Time = 425", () => Clock.CurrentTime == 425); + AddAssert("Time = 400", () => Clock.CurrentTime == 400); AddStep("SeekBackward", () => Clock.SeekBackward()); - AddAssert("Time = 375", () => Clock.CurrentTime == 375); + AddAssert("Time = 350", () => Clock.CurrentTime == 350); AddStep("SeekBackward", () => Clock.SeekBackward()); - AddAssert("Time = 325", () => Clock.CurrentTime == 325); + AddAssert("Time = 150", () => Clock.CurrentTime == 150); AddStep("SeekBackward", () => Clock.SeekBackward()); - AddAssert("Time = 125", () => Clock.CurrentTime == 125); - AddStep("SeekBackward", () => Clock.SeekBackward()); - AddAssert("Time = 25", () => Clock.CurrentTime == 25); + AddAssert("Time = 50", () => Clock.CurrentTime == 50); AddStep("SeekBackward", () => Clock.SeekBackward()); AddAssert("Time = 0", () => Clock.CurrentTime == 0); } From 01b909eaa7d2eed0e98795c935651c0d8edcb930 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 17:05:18 +0900 Subject: [PATCH 053/125] Add testfixture annotation --- osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs index d6771ebd21..dace6e20ef 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs @@ -16,6 +16,7 @@ using OpenTK.Graphics; namespace osu.Game.Tests.Visual { + [TestFixture] public class TestCaseEditorSeekSnapping : EditorClockTestCase { public TestCaseEditorSeekSnapping() From dbc50e35d58998313e7c022852fe81dacb424e8a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 18:02:26 +0900 Subject: [PATCH 054/125] Fix the timeline and editor fighting over track seeking --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index e993d36551..5624d2e69f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -62,9 +62,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } /// - /// The track's time in the previous frame. + /// The timeline's last scroll position. /// - private double lastTrackTime; + private double lastScrollPosition; /// /// Whether the user is currently dragging the timeline. @@ -100,20 +100,20 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline // 1) The user scrolls on this timeline: We want the track to follow us // 2) The user changes the track time through some other means (scrolling in the editor or overview timeline): We want to follow the track time - // The simplest way to cover both cases is by checking that inter-frame track times are identical - if (adjustableClock.CurrentTime == lastTrackTime) + // The simplest way to cover both cases is by checking whether the inter-frame timeline positions are identical + if (Current != lastScrollPosition) { - // The track hasn't been seeked externally + // The timeline has moved, seek the track seekTrackToCurrent(); } else { - // The track has been seeked externally + // The timeline hasn't moved, scroll to the track time scrollToTrackTime(); } } - lastTrackTime = adjustableClock.CurrentTime; + lastScrollPosition = Current; void seekTrackToCurrent() { From 6d318d35ee8096884707666e2b6a09451daa7824 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 18:56:54 +0900 Subject: [PATCH 055/125] Fix not being able to seek by other means during flick-scroll --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 5624d2e69f..59be7dac65 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -62,9 +62,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } /// - /// The timeline's last scroll position. + /// The timeline's scroll position in the last frame. /// - private double lastScrollPosition; + private float lastScrollPosition; + + /// + /// The track time in the last frame. + /// + private double lastTrackTime; /// /// Whether the user is currently dragging the timeline. @@ -100,20 +105,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline // 1) The user scrolls on this timeline: We want the track to follow us // 2) The user changes the track time through some other means (scrolling in the editor or overview timeline): We want to follow the track time - // The simplest way to cover both cases is by checking whether the inter-frame timeline positions are identical - if (Current != lastScrollPosition) - { - // The timeline has moved, seek the track + // The simplest way to cover both cases is by checking whether the scroll position has changed and the audio hasn't been changed externally + if (Current != lastScrollPosition && adjustableClock.CurrentTime == lastTrackTime) seekTrackToCurrent(); - } else - { - // The timeline hasn't moved, scroll to the track time scrollToTrackTime(); - } } lastScrollPosition = Current; + lastTrackTime = adjustableClock.CurrentTime; void seekTrackToCurrent() { From 54e60d8bc2182c8a6cdd5b78e2ed75e02b2199e7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 19:27:08 +0900 Subject: [PATCH 056/125] Fix test appveyor tests failing due to lack of audio manager --- .../Screens/Edit/Screens/Compose/Timeline/Timeline.cs | 11 +++++++++-- 1 file changed, 9 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 59be7dac65..d0c4afed98 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -117,14 +117,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline void seekTrackToCurrent() { + var track = Beatmap.Value.Track; + if (track is TrackVirtual || !track.IsLoaded) + return; + if (!(Beatmap.Value.Track is TrackVirtual)) adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); } void scrollToTrackTime() { - if (!(Beatmap.Value.Track is TrackVirtual)) - ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + var track = Beatmap.Value.Track; + if (track is TrackVirtual || !track.IsLoaded) + return; + + ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); } } From 9d7e5b492009ed883e99655397cb026a96587fcd Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 20 Jun 2018 17:23:55 +0900 Subject: [PATCH 057/125] Clamp juice stream position --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 2 +- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 2768357034..b0344d9a2d 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps foreach (var nested in juiceStream.NestedHitObjects) { if (nested is TinyDroplet tinyDroplet) - tinyDroplet.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH; + tinyDroplet.X = MathHelper.Clamp(tinyDroplet.X + rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, 0, 1); else if (nested is Droplet) rng.Next(); // osu!stable retrieved a random droplet rotation } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index b2d8e3f8a5..a4c4faacfa 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -89,7 +89,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new TinyDroplet { StartTime = t, - X = X + Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, + X = MathHelper.Clamp(X + Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, 0, 1), Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new Droplet { StartTime = time, - X = X + Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, + X = MathHelper.Clamp(X + Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, 0, 1), Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = Samples, StartTime = spanStartTime + spanDuration, - X = X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH + X = MathHelper.Clamp(X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH, 0, 1) }); } From 516b1c5495a17e89428989ab20aaa269123042ce Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 20 Jun 2018 18:29:23 +0900 Subject: [PATCH 058/125] Fix droplet position clamping --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 8 +++++--- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index b0344d9a2d..7fa0d256da 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -56,10 +56,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps case JuiceStream juiceStream: foreach (var nested in juiceStream.NestedHitObjects) { - if (nested is TinyDroplet tinyDroplet) - tinyDroplet.X = MathHelper.Clamp(tinyDroplet.X + rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, 0, 1); - else if (nested is Droplet) + 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.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index a4c4faacfa..b2d8e3f8a5 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -89,7 +89,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new TinyDroplet { StartTime = t, - X = MathHelper.Clamp(X + Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, 0, 1), + X = X + Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Catch.Objects AddNested(new Droplet { StartTime = time, - X = MathHelper.Clamp(X + Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, 0, 1), + X = X + Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Catch.Objects { Samples = Samples, StartTime = spanStartTime + spanDuration, - X = MathHelper.Clamp(X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH, 0, 1) + X = X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH }); } From 9194fd8dfe89e453819662ad4aafbc3ffe945f94 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 20 Jun 2018 20:08:27 +0900 Subject: [PATCH 059/125] don't expose HyperDashModifier directly --- .../TestCaseCatcherArea.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 59 ++++++++----------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs index 5119260c53..0ba6398ced 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.HyperDashModifier = status ? 2 : 1; + public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperdashState(status ? 2 : 1); } } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 3c0a6aec30..b74d53eef0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -18,7 +18,6 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; -using System.Diagnostics; namespace osu.Game.Rulesets.Catch.UI { @@ -250,21 +249,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); - // An edge case - if (Math.Abs(velocity) <= 1) - { - HyperDashModifier = 1; - } - else - { - hyperDashDirection = Math.Sign(velocity); - hyperDashTargetPosition = target.X; - HyperDashModifier = Math.Abs(velocity); - } + SetHyperdashState(Math.Abs(velocity), target.X); } else { - HyperDashModifier = 1; + SetHyperdashState(); } return validCatch; @@ -279,37 +268,39 @@ namespace osu.Game.Rulesets.Catch.UI /// public bool HyperDashing => hyperDashModifier != 1; + private const float hyperdash_transition_length = 180; + /// - /// The modifier multiplied to the catcher speed. - /// It is always not less than 1 and it is greater than 1 if and only if the catcher is hyper-dashing. + /// Set hyperdash state. /// - public double HyperDashModifier + /// 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) { - get => hyperDashModifier; - set + bool previouslyHyperDashing = HyperDashing; + if (modifier <= 1 || X == targetPosition) { - Trace.Assert(value >= 1); - if (hyperDashModifier == value) return; - hyperDashModifier = value; + hyperDashModifier = 1; + hyperDashDirection = 0; - if (!HyperDashing) + if (previouslyHyperDashing) { - hyperDashDirection = 0; + this.FadeColour(Color4.White, hyperdash_transition_length, Easing.OutQuint); + this.FadeTo(1, hyperdash_transition_length, Easing.OutQuint); } + } + else + { + hyperDashModifier = modifier; + hyperDashDirection = Math.Sign(targetPosition - X); + hyperDashTargetPosition = targetPosition; - const float transition_length = 180; - - if (HyperDashing) + if (!previouslyHyperDashing) { - this.FadeColour(Color4.OrangeRed, transition_length, Easing.OutQuint); - this.FadeTo(0.2f, transition_length, Easing.OutQuint); + this.FadeColour(Color4.OrangeRed, hyperdash_transition_length, Easing.OutQuint); + this.FadeTo(0.2f, hyperdash_transition_length, Easing.OutQuint); Trail = true; } - else - { - this.FadeColour(Color4.White, transition_length, Easing.OutQuint); - this.FadeTo(1, transition_length, Easing.OutQuint); - } } } @@ -373,7 +364,7 @@ namespace osu.Game.Rulesets.Catch.UI hyperDashDirection < 0 && hyperDashTargetPosition > X) { X = hyperDashTargetPosition; - HyperDashModifier = 1; + SetHyperdashState(); } } From a2fa55c4267f783459b855a58457ef77828a1eb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Jun 2018 16:47:05 +0900 Subject: [PATCH 060/125] 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 eb6d6dc2de675c03b58a7ee5f538890ce019f95e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Jun 2018 12:30:40 +0900 Subject: [PATCH 061/125] Improve the visibility of the global loading animation Updates design to match new `osu-web` design. Adds TestCase for visual testing. --- .../Visual/TestCaseLoadingAnimation.cs | 63 +++++++++++++++++++ .../UserInterface/LoadingAnimation.cs | 27 ++++++-- 2 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseLoadingAnimation.cs diff --git a/osu.Game.Tests/Visual/TestCaseLoadingAnimation.cs b/osu.Game.Tests/Visual/TestCaseLoadingAnimation.cs new file mode 100644 index 0000000000..ebbc673d36 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseLoadingAnimation.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; +using OpenTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseLoadingAnimation : GridTestCase + { + public TestCaseLoadingAnimation() + : base(2, 2) + { + LoadingAnimation loading; + + Cell(0).AddRange(new Drawable[] + { + new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both + }, + loading = new LoadingAnimation() + }); + + loading.Show(); + + Cell(1).AddRange(new Drawable[] + { + new Box + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both + }, + loading = new LoadingAnimation() + }); + + loading.Show(); + + Cell(2).AddRange(new Drawable[] + { + new Box + { + Colour = Color4.Gray, + RelativeSizeAxes = Axes.Both + }, + loading = new LoadingAnimation() + }); + + loading.Show(); + + Cell(3).AddRange(new Drawable[] + { + loading = new LoadingAnimation() + }); + + Scheduler.AddDelayed(() => loading.ToggleVisibility(), 200, true); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index 5ea6bce432..3d6c0a54d3 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -4,12 +4,17 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Graphics.UserInterface { public class LoadingAnimation : VisibilityContainer { private readonly SpriteIcon spinner; + private readonly SpriteIcon spinnerShadow; + + private const float spin_duration = 600; + private const float transition_duration = 200; public LoadingAnimation() { @@ -20,12 +25,22 @@ namespace osu.Game.Graphics.UserInterface Children = new Drawable[] { - spinner = new SpriteIcon + spinnerShadow = new SpriteIcon { - Size = new Vector2(20), + RelativeSizeAxes = Axes.Both, + Position = new Vector2(1, 1), Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.fa_spinner + Colour = Color4.Black, + Alpha = 0.4f, + Icon = FontAwesome.fa_circle_o_notch + }, + spinner = new SpriteIcon + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_circle_o_notch } }; } @@ -34,12 +49,12 @@ namespace osu.Game.Graphics.UserInterface { base.LoadComplete(); - spinner.Spin(2000, RotationDirection.Clockwise); + spinner.Spin(spin_duration, RotationDirection.Clockwise); + spinnerShadow.Spin(spin_duration, RotationDirection.Clockwise); } - private const float transition_duration = 500; - protected override void PopIn() => this.FadeIn(transition_duration * 5, Easing.OutQuint); + protected override void PopIn() => this.FadeIn(transition_duration, Easing.OutQuint); protected override void PopOut() => this.FadeOut(transition_duration, Easing.OutQuint); } From 3824354cb8797ff4d039ca8501a48aa31e7fa55f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Jun 2018 14:26:24 +0900 Subject: [PATCH 062/125] Lengthen PopIn transition slightly --- osu.Game/Graphics/UserInterface/LoadingAnimation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index 3d6c0a54d3..cd4aef051d 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -54,7 +54,7 @@ namespace osu.Game.Graphics.UserInterface } - protected override void PopIn() => this.FadeIn(transition_duration, Easing.OutQuint); + protected override void PopIn() => this.FadeIn(transition_duration * 2, Easing.OutQuint); protected override void PopOut() => this.FadeOut(transition_duration, Easing.OutQuint); } From 51600dd0ae7d25e8dfacd2ac64688ff002f72349 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Jun 2018 14:27:36 +0900 Subject: [PATCH 063/125] Improve PlayButton's loading --- osu.Game/Overlays/Direct/PlayButton.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 4b91a3d700..28cc484109 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -10,6 +10,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using OpenTK; using OpenTK.Graphics; namespace osu.Game.Overlays.Direct @@ -48,9 +49,15 @@ namespace osu.Game.Overlays.Direct set { if (value) + { + icon.FadeTo(0.5f, transition_duration, Easing.OutQuint); loadingAnimation.Show(); + } else + { + icon.FadeTo(1, transition_duration, Easing.OutQuint); loadingAnimation.Hide(); + } } } @@ -67,7 +74,10 @@ namespace osu.Game.Overlays.Direct RelativeSizeAxes = Axes.Both, Icon = FontAwesome.fa_play, }, - loadingAnimation = new LoadingAnimation(), + loadingAnimation = new LoadingAnimation + { + Size = new Vector2(15), + }, }); Playing.ValueChanged += playingStateChanged; From 78ccbcabf36b0f6ee2ecb40dcc3230482dd3b504 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Jun 2018 17:34:29 +0900 Subject: [PATCH 064/125] Fix API getting stuck in an endless loop under a certain unauthorized scenario --- osu.Game/Online/API/APIAccess.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 8c5fc58878..c7ba2d4a11 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -148,7 +148,7 @@ namespace osu.Game.Online.API // The Success callback event is fired on the main thread, so we should wait for that to run before proceeding. // Without this, we will end up circulating this Connecting loop multiple times and queueing up many web requests // before actually going online. - while (State != APIState.Online) + while (State > APIState.Offline) Thread.Sleep(500); break; @@ -158,7 +158,6 @@ namespace osu.Game.Online.API if (authentication.RequestAccessToken() == null) { Logout(false); - State = APIState.Offline; continue; } @@ -208,6 +207,14 @@ namespace osu.Game.Online.API { HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout); + // special cases for un-typed but useful message responses. + switch (we.Message) + { + case "Unauthorized": + statusCode = HttpStatusCode.Unauthorized; + break; + } + switch (statusCode) { case HttpStatusCode.Unauthorized: @@ -292,6 +299,7 @@ namespace osu.Game.Online.API password = null; authentication.Clear(); LocalUser.Value = createGuestUser(); + State = APIState.Offline; } private static User createGuestUser() => new User From cd74ec705e020e02b9b5ea22a10354ddd4c4be44 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Jun 2018 20:31:06 +0900 Subject: [PATCH 065/125] Fix possible mis-ordering of scroll position updates 1. Checking whether the scroll position has changed must be done _after_ Current is updated in base.UpdateAfterChildren. This was causing the timeline to sometimes not provide smooth scrolling while the track is not running. 2. We can't just move all code to UpdateAfterChildren to fulfill (1) - we need the code to follow the track time to still run prior to base.UpdateAfterChildren, so that it modifies Current prior to base.UpdateAfterChildren changing to position. --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index d0c4afed98..e6a04bf1e7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -88,21 +88,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline // The extrema of track time should be positioned at the centre of the container when scrolled to the start or end Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - if (handlingDragInput) - { - // The user is dragging - the track should always follow the timeline - seekTrackToCurrent(); - } - else if (adjustableClock.IsRunning) - { - // If the user hasn't provided mouse input but the track is running, always follow the track + // This needs to happen after transforms are updated, but before the scroll position is updated in base.UpdateAfterChildren + if (adjustableClock.IsRunning) scrollToTrackTime(); - } - else + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + if (handlingDragInput) + seekTrackToCurrent(); + else if (!adjustableClock.IsRunning) { - // The track isn't playing, so we want to smooth-scroll once more, and re-enable wheel scrolling - // There are two cases we have to be wary of: - // 1) The user scrolls on this timeline: We want the track to follow us + // The track isn't running. There are two cases we have to be wary of: + // 1) The user flick-drags on this timeline: We want the track to follow us // 2) The user changes the track time through some other means (scrolling in the editor or overview timeline): We want to follow the track time // The simplest way to cover both cases is by checking whether the scroll position has changed and the audio hasn't been changed externally @@ -114,25 +114,25 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline lastScrollPosition = Current; lastTrackTime = adjustableClock.CurrentTime; + } - void seekTrackToCurrent() - { - var track = Beatmap.Value.Track; - if (track is TrackVirtual || !track.IsLoaded) - return; + private void seekTrackToCurrent() + { + var track = Beatmap.Value.Track; + if (track is TrackVirtual || !track.IsLoaded) + return; - if (!(Beatmap.Value.Track is TrackVirtual)) - adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); - } + if (!(Beatmap.Value.Track is TrackVirtual)) + adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + } - void scrollToTrackTime() - { - var track = Beatmap.Value.Track; - if (track is TrackVirtual || !track.IsLoaded) - return; + private void scrollToTrackTime() + { + var track = Beatmap.Value.Track; + if (track is TrackVirtual || !track.IsLoaded) + return; - ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); - } + ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From 563cb46b4aa38773348e8aed6f8367e578352eb3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 12:02:04 +0900 Subject: [PATCH 066/125] Update framework and other nuget dependencies --- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 2 +- osu.Game/osu.Game.csproj | 10 +++++----- osu.TestProject.props | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 29d3b0e394..0289db20f0 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -29,7 +29,7 @@ - + diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index ffe1560627..6ba36a51d1 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(KeyCombination.FromInputState(state)); + bindTarget.UpdateKeyCombination(new KeyCombination(new[] { state.Mouse.ScrollDelta.Y > 0 ? InputKey.MouseWheelUp : InputKey.MouseWheelDown })); finalise(); return true; } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9cc538f70f..9668d40fd5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,12 +14,12 @@ - - - + + + - - + + diff --git a/osu.TestProject.props b/osu.TestProject.props index 8f7128f8b7..c2e6048a60 100644 --- a/osu.TestProject.props +++ b/osu.TestProject.props @@ -11,7 +11,7 @@ - + From 96191fc3cefcebe4866eafbe78a296353d94efd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 13:02:29 +0900 Subject: [PATCH 067/125] Move transition variable back to being local to function --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index b74d53eef0..24edcbfc98 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -268,8 +268,6 @@ namespace osu.Game.Rulesets.Catch.UI /// public bool HyperDashing => hyperDashModifier != 1; - private const float hyperdash_transition_length = 180; - /// /// Set hyperdash state. /// @@ -277,6 +275,8 @@ namespace osu.Game.Rulesets.Catch.UI /// When this catcher crosses this position, this catcher ends hyperdashing. public void SetHyperdashState(double modifier = 1, float targetPosition = -1) { + const float hyperdash_transition_length = 180; + bool previouslyHyperDashing = HyperDashing; if (modifier <= 1 || X == targetPosition) { From b0a1b25983d32a9cd2882292173039ab7d93ed15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 16:32:20 +0900 Subject: [PATCH 068/125] 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 069/125] 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 070/125] 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 071/125] 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 f1dfe04bd9ee23ceb3b763be6b5d08ccb59b0472 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Jun 2018 20:13:44 +0900 Subject: [PATCH 072/125] Fix broken conditional --- osu.Game/Online/API/APIAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index c7ba2d4a11..12935a5ffe 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -148,7 +148,7 @@ namespace osu.Game.Online.API // The Success callback event is fired on the main thread, so we should wait for that to run before proceeding. // Without this, we will end up circulating this Connecting loop multiple times and queueing up many web requests // before actually going online. - while (State > APIState.Offline) + while (State > APIState.Offline && State < APIState.Online) Thread.Sleep(500); break; From 1a8aa6eab10d677a0622b111bbab5d796730b58e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Jun 2018 20:13:55 +0900 Subject: [PATCH 073/125] Fix regression causing new combos to once again not be respected --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 4 ++++ osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 7fa0d256da..8473f5a36c 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -30,7 +30,11 @@ namespace osu.Game.Rulesets.Catch.Beatmaps int index = 0; foreach (var obj in Beatmap.HitObjects.OfType()) + { obj.IndexInBeatmap = index++; + if (obj.LastInCombo && obj.NestedHitObjects.LastOrDefault() is IHasComboInformation lastNested) + lastNested.LastInCombo = true; + } } public const int RNG_SEED = 1337; diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index b2d8e3f8a5..6fe9692c26 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -42,7 +42,6 @@ namespace osu.Game.Rulesets.Catch.Objects protected override void CreateNestedHitObjects() { base.CreateNestedHitObjects(); - createTicks(); } @@ -124,9 +123,6 @@ namespace osu.Game.Rulesets.Catch.Objects X = X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH }); } - - if (NestedHitObjects.LastOrDefault() is IHasComboInformation lastNested) - lastNested.LastInCombo = LastInCombo; } public double EndTime => StartTime + this.SpanCount() * Curve.Distance / Velocity; From 8a81fba1ea6524adf58eaceb02e6d6aa2404e1ae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Jun 2018 20:34:22 +0900 Subject: [PATCH 074/125] Other input states need to be considered for wheel bindings --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 6ba36a51d1..a12f9dee7e 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(new[] { state.Mouse.ScrollDelta.Y > 0 ? InputKey.MouseWheelUp : InputKey.MouseWheelDown })); + bindTarget.UpdateKeyCombination(new KeyCombination(KeyCombination.FromInputState(state).Keys.Append(state.Mouse.ScrollDelta.Y > 0 ? InputKey.MouseWheelUp : InputKey.MouseWheelDown))); finalise(); return true; } From 80501de4b993e894ac48aa02eaa8f112c838cc5c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 22:20:34 +0900 Subject: [PATCH 075/125] Add legacy slider offsets --- .../Beatmaps/CatchBeatmapConverter.cs | 4 +++- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 9 +++++++++ .../Beatmaps/OsuBeatmapConverter.cs | 4 +++- osu.Game.Rulesets.Osu/Objects/Slider.cs | 10 ++++++++++ osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 4 +++- .../Objects/Types/IHasLegacyLastTickOffset.cs | 14 ++++++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Rulesets/Objects/Types/IHasLegacyLastTickOffset.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 46fe8454dc..68a8dfb7d3 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -26,6 +26,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps var positionData = obj as IHasXPosition; var comboData = obj as IHasCombo; var endTime = obj as IHasEndTime; + var legacyOffset = obj as IHasLegacyLastTickOffset; if (curveData != null) { @@ -39,7 +40,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps RepeatSamples = curveData.RepeatSamples, RepeatCount = curveData.RepeatCount, X = (positionData?.X ?? 0) / CatchPlayfield.BASE_WIDTH, - NewCombo = comboData?.NewCombo ?? false + NewCombo = comboData?.NewCombo ?? false, + LegacyLastTickOffset = legacyOffset?.LegacyLastTickOffset ?? 0 }; } else if (endTime != null) diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 6fe9692c26..0344189af5 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -77,6 +77,13 @@ namespace osu.Game.Rulesets.Catch.Objects double time = spanStartTime + timeProgress * spanDuration; + if (LegacyLastTickOffset != null) + { + // If we're the last tick, apply the legacy offset + if (span == this.SpanCount() - 1 && d + tickDistance > length) + time = Math.Max(StartTime + Duration / 2, time - LegacyLastTickOffset.Value); + } + double tinyTickInterval = time - lastDropletTime; while (tinyTickInterval > 100) tinyTickInterval /= 2; @@ -152,5 +159,7 @@ namespace osu.Game.Rulesets.Catch.Objects get { return Curve.CurveType; } set { Curve.CurveType = value; } } + + public double? LegacyLastTickOffset { get; set; } } } diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index 80eb808f6e..405493cde4 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -27,6 +27,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps var endTimeData = original as IHasEndTime; var positionData = original as IHasPosition; var comboData = original as IHasCombo; + var legacyOffset = original as IHasLegacyLastTickOffset; if (curveData != null) { @@ -40,7 +41,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps RepeatSamples = curveData.RepeatSamples, RepeatCount = curveData.RepeatCount, Position = positionData?.Position ?? Vector2.Zero, - NewCombo = comboData?.NewCombo ?? false + NewCombo = comboData?.NewCombo ?? false, + LegacyLastTickOffset = legacyOffset?.LegacyLastTickOffset }; } else if (endTimeData != null) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 7f4407370f..d74c902f4c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.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 System; using OpenTK; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; @@ -45,6 +46,8 @@ namespace osu.Game.Rulesets.Osu.Objects set { Curve.Distance = value; } } + public double? LegacyLastTickOffset { get; set; } + /// /// The position of the cursor at the point of completion of this if it was hit /// with as few movements as possible. This is set and used by difficulty calculation. @@ -91,6 +94,13 @@ namespace osu.Game.Rulesets.Osu.Objects createSliderEnds(); createTicks(); createRepeatPoints(); + + if (LegacyLastTickOffset != null) + { + var lastObject = NestedHitObjects.Last(); + if (!(lastObject is SliderCircle)) + lastObject.StartTime = Math.Max(StartTime + Duration / 2, lastObject.StartTime - LegacyLastTickOffset.Value); + } } private void createSliderEnds() diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 17848d1e6e..ef1eecec3d 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -10,7 +10,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Objects.Legacy { - internal abstract class ConvertSlider : HitObject, IHasCurve + internal abstract class ConvertSlider : HitObject, IHasCurve, IHasLegacyLastTickOffset { /// /// Scoring distance with a speed-adjusted beat length of 1 second. @@ -45,5 +45,7 @@ namespace osu.Game.Rulesets.Objects.Legacy Velocity = scoringDistance / timingPoint.BeatLength; } + + public double LegacyLastTickOffset => 36; } } diff --git a/osu.Game/Rulesets/Objects/Types/IHasLegacyLastTickOffset.cs b/osu.Game/Rulesets/Objects/Types/IHasLegacyLastTickOffset.cs new file mode 100644 index 0000000000..ab2573e933 --- /dev/null +++ b/osu.Game/Rulesets/Objects/Types/IHasLegacyLastTickOffset.cs @@ -0,0 +1,14 @@ +// 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 type of which may require the last tick to be offset. + /// This is specific to osu!stable conversion, and should not be used elsewhere. + /// + public interface IHasLegacyLastTickOffset + { + double LegacyLastTickOffset { get; } + } +} From 8e4dd58e6893560040293925d962309caa91abca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 22:23:19 +0900 Subject: [PATCH 076/125] Restore ignored unit tests --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 89e8361a72..e18a277cba 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; - [TestCase("basic"), Ignore("See: https://github.com/ppy/osu/issues/2232")] + [TestCase("basic")] [TestCase("spinner")] [TestCase("spinner-and-circles")] public new void Test(string name) From de3708ea3aaee6e631bfe0575d973958485fd7d3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 23:43:58 +0900 Subject: [PATCH 077/125] Public + explicitly define test fixtures --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 5 +++-- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 5 +++-- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 5 +++-- osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index e18a277cba..4b95a6754e 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -13,7 +13,8 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { - internal class CatchBeatmapConversionTest : BeatmapConversionTest + [TestFixture] + public class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; @@ -44,7 +45,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..73555dcecb 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -12,7 +12,8 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - internal class ManiaBeatmapConversionTest : BeatmapConversionTest + [TestFixture] + public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -36,7 +37,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..228fcf020f 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -13,7 +13,8 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { - internal class OsuBeatmapConversionTest : BeatmapConversionTest + [TestFixture] + public class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; @@ -43,7 +44,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..db8480c742 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -12,7 +12,8 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - internal class TaikoBeatmapConversionTest : BeatmapConversionTest + [TestFixture] + public class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; @@ -41,7 +42,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 0366b0f081700640209d6eb927d6bf4e97e9043d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 23:46:43 +0900 Subject: [PATCH 078/125] The tail circle will always be the last hitobject --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index d74c902f4c..2ebe5efd0f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -96,11 +96,7 @@ namespace osu.Game.Rulesets.Osu.Objects createRepeatPoints(); if (LegacyLastTickOffset != null) - { - var lastObject = NestedHitObjects.Last(); - if (!(lastObject is SliderCircle)) - lastObject.StartTime = Math.Max(StartTime + Duration / 2, lastObject.StartTime - LegacyLastTickOffset.Value); - } + TailCircle.StartTime = Math.Max(StartTime + Duration / 2, TailCircle.StartTime - LegacyLastTickOffset.Value); } private void createSliderEnds() From 6f65ad33f06e769ea72e3b25e7a5676a699bb1c3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 01:27:33 +0900 Subject: [PATCH 079/125] Output one value per slider nested hitobject --- .../OsuBeatmapConversionTest.cs | 41 +- .../Beatmaps/basic-expected-conversion.json | 374 ++++++++++++------ ...ear-perfect-curve-expected-conversion.json | 23 +- 3 files changed, 287 insertions(+), 151 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 228fcf020f..4139685eaa 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -9,7 +9,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Beatmaps; -using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { @@ -27,17 +26,23 @@ namespace osu.Game.Rulesets.Osu.Tests protected override IEnumerable CreateConvertValue(HitObject hitObject) { - var startPosition = (hitObject as IHasPosition)?.Position ?? new Vector2(256, 192); - var endPosition = (hitObject as Slider)?.EndPosition ?? startPosition; - - yield return new ConvertValue + switch (hitObject) { - StartTime = hitObject.StartTime, - EndTime = (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime, - StartX = startPosition.X, - StartY = startPosition.Y, - EndX = endPosition.X, - EndY = endPosition.Y + case Slider slider: + foreach (var nested in slider.NestedHitObjects) + yield return createConvertValue(nested); + break; + default: + yield return createConvertValue(hitObject); + break; + } + + ConvertValue createConvertValue(HitObject obj) => new ConvertValue + { + StartTime = obj.StartTime, + EndTime = (obj as IHasEndTime)?.EndTime ?? obj.StartTime, + X = (obj as IHasPosition)?.X ?? 256, + Y = (obj as IHasPosition)?.Y ?? 192, }; } @@ -53,17 +58,13 @@ namespace osu.Game.Rulesets.Osu.Tests public double StartTime; public double EndTime; - public float StartX; - public float StartY; - public float EndX; - public float EndY; + public float X; + public float Y; public bool Equals(ConvertValue other) - => Precision.AlmostEquals(StartTime, other.StartTime) + => Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience) && Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience) - && Precision.AlmostEquals(StartX, other.StartX) - && Precision.AlmostEquals(StartY, other.StartY, conversion_lenience) - && Precision.AlmostEquals(EndX, other.EndX, conversion_lenience) - && Precision.AlmostEquals(EndY, other.EndY, conversion_lenience); + && Precision.AlmostEquals(X, other.X, conversion_lenience) + && Precision.AlmostEquals(Y, other.Y, conversion_lenience); } } diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/basic-expected-conversion.json b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/basic-expected-conversion.json index b82fddbe79..491adc2b50 100644 --- a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/basic-expected-conversion.json +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/basic-expected-conversion.json @@ -1,124 +1,256 @@ { "Mappings": [{ - "StartTime": 500, - "Objects": [{ - "StartTime": 500, - "EndTime": 2500, - "StartX": 96, - "StartY": 192, - "EndX": 96, - "EndY": 192 - }] - }, - { - "StartTime": 3000, - "Objects": [{ - "StartTime": 3000, - "EndTime": 4000, - "StartX": 256, - "StartY": 192, - "EndX": 256, - "EndY": 192 - }] - }, - { - "StartTime": 4500, - "Objects": [{ - "StartTime": 4500, - "EndTime": 5500, - "StartX": 256, - "StartY": 192, - "EndX": 256, - "EndY": 192 - }] - }, - { - "StartTime": 6000, - "Objects": [{ - "StartTime": 6000, - "EndTime": 6500, - "StartX": 256, - "StartY": 192, - "EndX": 256, - "EndY": 192 - }] - }, - { - "StartTime": 7000, - "Objects": [{ - "StartTime": 7000, - "EndTime": 8000, - "StartX": 256, - "StartY": 128, - "EndX": 256, - "EndY": 128 - }] - }, - { - "StartTime": 8500, - "Objects": [{ - "StartTime": 8500, - "EndTime": 10999, - "StartX": 32, - "StartY": 192, - "EndX": 508.166229, - "EndY": 153.299271 - }] - }, - { - "StartTime": 11500, - "Objects": [{ - "StartTime": 11500, - "EndTime": 12000, - "StartX": 256, - "StartY": 192, - "EndX": 256, - "EndY": 192 - }] - }, - { - "StartTime": 12500, - "Objects": [{ - "StartTime": 12500, - "EndTime": 16500, - "StartX": 512, - "StartY": 320, - "EndX": 291.1977, - "EndY": 40.799427 - }] - }, - { - "StartTime": 17000, - "Objects": [{ - "StartTime": 17000, - "EndTime": 18000, - "StartX": 256, - "StartY": 256, - "EndX": 256, - "EndY": 256 - }] - }, - { - "StartTime": 18500, - "Objects": [{ - "StartTime": 18500, - "EndTime": 19450, - "StartX": 256, - "StartY": 192, - "EndX": 256, - "EndY": 192 - }] - }, - { - "StartTime": 19875, - "Objects": [{ - "StartTime": 19875, - "EndTime": 23874, - "StartX": 216, - "StartY": 231, - "EndX": 408.720825, - "EndY": 339.810455 - }] - } - ] + "StartTime": 500.0, + "Objects": [{ + "StartTime": 500.0, + "EndTime": 500.0, + "X": 96.0, + "Y": 192.0 + }, { + "StartTime": 1000.0, + "EndTime": 1000.0, + "X": 256.0, + "Y": 192.0 + }, { + "StartTime": 1500.0, + "EndTime": 1500.0, + "X": 416.0, + "Y": 192.0 + }, { + "StartTime": 2000.0, + "EndTime": 2000.0, + "X": 256.0, + "Y": 192.0 + }, { + "StartTime": 2464.0, + "EndTime": 2464.0, + "X": 96.0, + "Y": 192.0 + }] + }, { + "StartTime": 3000.0, + "Objects": [{ + "StartTime": 3000.0, + "EndTime": 4000.0, + "X": 256.0, + "Y": 192.0 + }] + }, { + "StartTime": 4500.0, + "Objects": [{ + "StartTime": 4500.0, + "EndTime": 5500.0, + "X": 256.0, + "Y": 192.0 + }] + }, { + "StartTime": 6000.0, + "Objects": [{ + "StartTime": 6000.0, + "EndTime": 6500.0, + "X": 256.0, + "Y": 192.0 + }] + }, { + "StartTime": 7000.0, + "Objects": [{ + "StartTime": 7000.0, + "EndTime": 7000.0, + "X": 256.0, + "Y": 128.0 + }, { + "StartTime": 7250.0, + "EndTime": 7250.0, + "X": 336.0, + "Y": 128.0 + }, { + "StartTime": 7500.0, + "EndTime": 7500.0, + "X": 256.0, + "Y": 128.0 + }, { + "StartTime": 7750.0, + "EndTime": 7750.0, + "X": 336.0, + "Y": 128.0 + }, { + "StartTime": 7964.0, + "EndTime": 7964.0, + "X": 256.0, + "Y": 128.0 + }] + }, { + "StartTime": 8500.0, + "Objects": [{ + "StartTime": 8500.0, + "EndTime": 8500.0, + "X": 32.0, + "Y": 192.0 + }, { + "StartTime": 9000.0, + "EndTime": 9000.0, + "X": 101.81015, + "Y": 326.4915 + }, { + "StartTime": 9500.0, + "EndTime": 9500.0, + "X": 237.2304, + "Y": 276.282928 + }, { + "StartTime": 10000.0, + "EndTime": 10000.0, + "X": 270.339874, + "Y": 121.1423 + }, { + "StartTime": 10500.0, + "EndTime": 10500.0, + "X": 401.0588, + "Y": 49.1515045 + }, { + "StartTime": 10964.0, + "EndTime": 10964.0, + "X": 508.166229, + "Y": 153.299271 + }] + }, { + "StartTime": 11500.0, + "Objects": [{ + "StartTime": 11500.0, + "EndTime": 12000.0, + "X": 256.0, + "Y": 192.0 + }] + }, { + "StartTime": 12500.0, + "Objects": [{ + "StartTime": 12500.0, + "EndTime": 12500.0, + "X": 512.0, + "Y": 320.0 + }, { + "StartTime": 13000.0, + "EndTime": 13000.0, + "X": 353.235535, + "Y": 300.154449 + }, { + "StartTime": 13500.0, + "EndTime": 13500.0, + "X": 194.471069, + "Y": 280.3089 + }, { + "StartTime": 14000.0, + "EndTime": 14000.0, + "X": 35.7066345, + "Y": 260.463318 + }, { + "StartTime": 14500.0, + "EndTime": 14500.0, + "X": 118.370323, + "Y": 219.009277 + }, { + "StartTime": 15000.0, + "EndTime": 15000.0, + "X": 271.087128, + "Y": 171.285278 + }, { + "StartTime": 15500.0, + "EndTime": 15500.0, + "X": 423.803925, + "Y": 123.561279 + }, { + "StartTime": 16000.0, + "EndTime": 16000.0, + "X": 446.420532, + "Y": 79.60513 + }, { + "StartTime": 16464.0, + "EndTime": 16464.0, + "X": 291.1977, + "Y": 40.799427 + }] + }, { + "StartTime": 17000.0, + "Objects": [{ + "StartTime": 17000.0, + "EndTime": 17000.0, + "X": 256.0, + "Y": 256.0 + }, { + "StartTime": 17250.0, + "EndTime": 17250.0, + "X": 176.0, + "Y": 256.0 + }, { + "StartTime": 17500.0, + "EndTime": 17500.0, + "X": 256.0, + "Y": 256.0 + }, { + "StartTime": 17750.0, + "EndTime": 17750.0, + "X": 176.0, + "Y": 256.0 + }, { + "StartTime": 17964.0, + "EndTime": 17964.0, + "X": 256.0, + "Y": 256.0 + }] + }, { + "StartTime": 18500.0, + "Objects": [{ + "StartTime": 18500.0, + "EndTime": 19450.0, + "X": 256.0, + "Y": 192.0 + }] + }, { + "StartTime": 19875.0, + "Objects": [{ + "StartTime": 19875.0, + "EndTime": 19875.0, + "X": 216.0, + "Y": 231.0 + }, { + "StartTime": 20375.0, + "EndTime": 20375.0, + "X": 317.446747, + "Y": 171.345245 + }, { + "StartTime": 20875.0, + "EndTime": 20875.0, + "X": 270.3294, + "Y": 310.4395 + }, { + "StartTime": 21375.0, + "EndTime": 21375.0, + "X": 119.121056, + "Y": 322.8657 + }, { + "StartTime": 21875.0, + "EndTime": 21875.0, + "X": 124.28746, + "Y": 165.224731 + }, { + "StartTime": 22375.0, + "EndTime": 22375.0, + "X": 240.4715, + "Y": 62.65587 + }, { + "StartTime": 22875.0, + "EndTime": 22875.0, + "X": 398.054047, + "Y": 39.064167 + }, { + "StartTime": 23375.0, + "EndTime": 23375.0, + "X": 439.749878, + "Y": 183.668091 + }, { + "StartTime": 23839.0, + "EndTime": 23839.0, + "X": 408.720825, + "Y": 339.810455 + }] + }] } \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/colinear-perfect-curve-expected-conversion.json b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/colinear-perfect-curve-expected-conversion.json index 7fe038658c..96e4bf1637 100644 --- a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/colinear-perfect-curve-expected-conversion.json +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/colinear-perfect-curve-expected-conversion.json @@ -1,13 +1,16 @@ { - "Mappings": [{ - "StartTime": 118858, - "Objects": [{ - "StartTime": 118858, - "EndTime": 119088, - "StartX": 219, - "StartY": 215, - "EndX": 239.6507, - "EndY": 29.1437378 + "Mappings": [{ + "StartTime": 118858.0, + "Objects": [{ + "StartTime": 118858.0, + "EndTime": 118858.0, + "X": 219.0, + "Y": 215.0 + }, { + "StartTime": 119052.0, + "EndTime": 119052.0, + "X": 239.6507, + "Y": 29.1437378 + }] }] - }] } \ No newline at end of file From 0e6cc78d9aef5b5c5db2297baed14fe8bd944aae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 01:28:28 +0900 Subject: [PATCH 080/125] Add slider ticks conversion test --- .../OsuBeatmapConversionTest.cs | 1 + .../slider-ticks-expected-conversion.json | 331 ++++++++++++++++++ .../Testing/Beatmaps/slider-ticks.osu | 20 ++ 3 files changed, 352 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks-expected-conversion.json create mode 100644 osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks.osu diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 4139685eaa..0bcf105575 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests [TestCase("basic")] [TestCase("colinear-perfect-curve")] + [TestCase("slider-ticks")] public new void Test(string name) { base.Test(name); diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks-expected-conversion.json b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks-expected-conversion.json new file mode 100644 index 0000000000..9c049c7cd6 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks-expected-conversion.json @@ -0,0 +1,331 @@ +{ + "Mappings": [{ + "StartTime": 500.0, + "Objects": [{ + "StartTime": 500.0, + "EndTime": 500.0, + "X": 96.0, + "Y": 192.0 + }, { + "StartTime": 624.0, + "EndTime": 624.0, + "X": 105.921242, + "Y": 192.0 + }, { + "StartTime": 749.0, + "EndTime": 749.0, + "X": 115.922493, + "Y": 192.0 + }, { + "StartTime": 874.0, + "EndTime": 874.0, + "X": 125.923737, + "Y": 192.0 + }, { + "StartTime": 999.0, + "EndTime": 999.0, + "X": 135.924988, + "Y": 192.0 + }, { + "StartTime": 1124.0, + "EndTime": 1124.0, + "X": 145.926239, + "Y": 192.0 + }, { + "StartTime": 1249.0, + "EndTime": 1249.0, + "X": 155.92749, + "Y": 192.0 + }, { + "StartTime": 1374.0, + "EndTime": 1374.0, + "X": 165.928741, + "Y": 192.0 + }, { + "StartTime": 1499.0, + "EndTime": 1499.0, + "X": 175.93, + "Y": 192.0 + }, { + "StartTime": 1624.0, + "EndTime": 1624.0, + "X": 185.931244, + "Y": 192.0 + }, { + "StartTime": 1749.0, + "EndTime": 1749.0, + "X": 195.9325, + "Y": 192.0 + }, { + "StartTime": 1874.0, + "EndTime": 1874.0, + "X": 205.933746, + "Y": 192.0 + }, { + "StartTime": 1999.0, + "EndTime": 1999.0, + "X": 215.935, + "Y": 192.0 + }, { + "StartTime": 2124.0, + "EndTime": 2124.0, + "X": 225.936234, + "Y": 192.0 + }, { + "StartTime": 2249.0, + "EndTime": 2249.0, + "X": 235.9375, + "Y": 192.0 + }, { + "StartTime": 2374.0, + "EndTime": 2374.0, + "X": 245.938751, + "Y": 192.0 + }, { + "StartTime": 2499.0, + "EndTime": 2499.0, + "X": 255.94, + "Y": 192.0 + }, { + "StartTime": 2624.0, + "EndTime": 2624.0, + "X": 265.941223, + "Y": 192.0 + }, { + "StartTime": 2749.0, + "EndTime": 2749.0, + "X": 275.9425, + "Y": 192.0 + }, { + "StartTime": 2874.0, + "EndTime": 2874.0, + "X": 285.943756, + "Y": 192.0 + }, { + "StartTime": 2999.0, + "EndTime": 2999.0, + "X": 295.945, + "Y": 192.0 + }, { + "StartTime": 3124.0, + "EndTime": 3124.0, + "X": 305.946259, + "Y": 192.0 + }, { + "StartTime": 3249.0, + "EndTime": 3249.0, + "X": 315.9475, + "Y": 192.0 + }, { + "StartTime": 3374.0, + "EndTime": 3374.0, + "X": 325.94873, + "Y": 192.0 + }, { + "StartTime": 3499.0, + "EndTime": 3499.0, + "X": 335.949982, + "Y": 192.0 + }, { + "StartTime": 3624.0, + "EndTime": 3624.0, + "X": 345.951233, + "Y": 192.0 + }, { + "StartTime": 3749.0, + "EndTime": 3749.0, + "X": 355.952484, + "Y": 192.0 + }, { + "StartTime": 3874.0, + "EndTime": 3874.0, + "X": 365.953766, + "Y": 192.0 + }, { + "StartTime": 3999.0, + "EndTime": 3999.0, + "X": 375.955, + "Y": 192.0 + }, { + "StartTime": 4124.0, + "EndTime": 4124.0, + "X": 385.956238, + "Y": 192.0 + }, { + "StartTime": 4249.0, + "EndTime": 4249.0, + "X": 395.9575, + "Y": 192.0 + }, { + "StartTime": 4374.0, + "EndTime": 4374.0, + "X": 405.95874, + "Y": 192.0 + }, { + "StartTime": 4499.0, + "EndTime": 4499.0, + "X": 415.960022, + "Y": 192.0 + }, { + "StartTime": 4624.0, + "EndTime": 4624.0, + "X": 406.038757, + "Y": 192.0 + }, { + "StartTime": 4749.0, + "EndTime": 4749.0, + "X": 396.0375, + "Y": 192.0 + }, { + "StartTime": 4874.0, + "EndTime": 4874.0, + "X": 386.036255, + "Y": 192.0 + }, { + "StartTime": 4999.0, + "EndTime": 4999.0, + "X": 376.035034, + "Y": 192.0 + }, { + "StartTime": 5124.0, + "EndTime": 5124.0, + "X": 366.033752, + "Y": 192.0 + }, { + "StartTime": 5249.0, + "EndTime": 5249.0, + "X": 356.0325, + "Y": 192.0 + }, { + "StartTime": 5374.0, + "EndTime": 5374.0, + "X": 346.03125, + "Y": 192.0 + }, { + "StartTime": 5499.0, + "EndTime": 5499.0, + "X": 336.030029, + "Y": 192.0 + }, { + "StartTime": 5624.0, + "EndTime": 5624.0, + "X": 326.028748, + "Y": 192.0 + }, { + "StartTime": 5749.0, + "EndTime": 5749.0, + "X": 316.0275, + "Y": 192.0 + }, { + "StartTime": 5874.0, + "EndTime": 5874.0, + "X": 306.026245, + "Y": 192.0 + }, { + "StartTime": 5999.0, + "EndTime": 5999.0, + "X": 296.025, + "Y": 192.0 + }, { + "StartTime": 6124.0, + "EndTime": 6124.0, + "X": 286.023773, + "Y": 192.0 + }, { + "StartTime": 6249.0, + "EndTime": 6249.0, + "X": 276.022522, + "Y": 192.0 + }, { + "StartTime": 6374.0, + "EndTime": 6374.0, + "X": 266.02124, + "Y": 192.0 + }, { + "StartTime": 6499.0, + "EndTime": 6499.0, + "X": 256.02, + "Y": 192.0 + }, { + "StartTime": 6624.0, + "EndTime": 6624.0, + "X": 246.018768, + "Y": 192.0 + }, { + "StartTime": 6749.0, + "EndTime": 6749.0, + "X": 236.017517, + "Y": 192.0 + }, { + "StartTime": 6874.0, + "EndTime": 6874.0, + "X": 226.016251, + "Y": 192.0 + }, { + "StartTime": 6999.0, + "EndTime": 6999.0, + "X": 216.014984, + "Y": 192.0 + }, { + "StartTime": 7124.0, + "EndTime": 7124.0, + "X": 206.013733, + "Y": 192.0 + }, { + "StartTime": 7249.0, + "EndTime": 7249.0, + "X": 196.012512, + "Y": 192.0 + }, { + "StartTime": 7374.0, + "EndTime": 7374.0, + "X": 186.011261, + "Y": 192.0 + }, { + "StartTime": 7499.0, + "EndTime": 7499.0, + "X": 176.01, + "Y": 192.0 + }, { + "StartTime": 7624.0, + "EndTime": 7624.0, + "X": 166.008728, + "Y": 192.0 + }, { + "StartTime": 7749.0, + "EndTime": 7749.0, + "X": 156.0075, + "Y": 192.0 + }, { + "StartTime": 7874.0, + "EndTime": 7874.0, + "X": 146.006256, + "Y": 192.0 + }, { + "StartTime": 7999.0, + "EndTime": 7999.0, + "X": 136.005, + "Y": 192.0 + }, { + "StartTime": 8124.0, + "EndTime": 8124.0, + "X": 126.003738, + "Y": 192.0 + }, { + "StartTime": 8249.0, + "EndTime": 8249.0, + "X": 116.002518, + "Y": 192.0 + }, { + "StartTime": 8374.0, + "EndTime": 8374.0, + "X": 106.001259, + "Y": 192.0 + }, { + "StartTime": 8463.0, + "EndTime": 8463.0, + "X": 96.0, + "Y": 192.0 + }] + }] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks.osu b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks.osu new file mode 100644 index 0000000000..fd835efbc8 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Resources/Testing/Beatmaps/slider-ticks.osu @@ -0,0 +1,20 @@ +osu file format v14 + +[General] +StackLeniency: 0.7 + +[Difficulty] +HPDrainRate:6 +CircleSize:4 +OverallDifficulty:7 +ApproachRate:8.3 +SliderMultiplier:0.400000005960464 +SliderTickRate:4 + +[TimingPoints] +500,500,4,2,1,50,1,0 +13426,-100,4,3,1,45,0,0 +14884,-100,4,2,1,50,0,0 + +[HitObjects] +96,192,500,6,0,L|416:192,2,320.000004768372 From 10220a61a59abf2c00a9c06d784a5faa0da53a06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Jun 2018 12:18:00 +0900 Subject: [PATCH 081/125] Use playfield size constants where possible --- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 5 +++-- osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 0bcf105575..3fa039d946 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -8,6 +8,7 @@ using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Osu.Tests @@ -42,8 +43,8 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = obj.StartTime, EndTime = (obj as IHasEndTime)?.EndTime ?? obj.StartTime, - X = (obj as IHasPosition)?.X ?? 256, - Y = (obj as IHasPosition)?.Y ?? 192, + X = (obj as IHasPosition)?.X ?? OsuPlayfield.BASE_SIZE.X / 2, + Y = (obj as IHasPosition)?.Y ?? OsuPlayfield.BASE_SIZE.Y / 2, }; } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 324d0502c1..bb0bd891b3 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -6,6 +6,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using System; using System.Collections.Generic; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Replays; using osu.Game.Users; @@ -18,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Replays /// /// Constants (for spinners). /// - protected static readonly Vector2 SPINNER_CENTRE = new Vector2(256, 192); + protected static readonly Vector2 SPINNER_CENTRE = OsuPlayfield.BASE_SIZE / 2; protected const float SPIN_RADIUS = 50; /// From f8acd9e4512dd5ec1efe7c62660517d55451c25b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Jun 2018 12:59:19 +0900 Subject: [PATCH 082/125] Cleanup --- osu.Game/Graphics/UserInterface/LoadingAnimation.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index cd4aef051d..8d45b03a43 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -27,19 +27,19 @@ namespace osu.Game.Graphics.UserInterface { spinnerShadow = new SpriteIcon { - RelativeSizeAxes = Axes.Both, - Position = new Vector2(1, 1), Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Position = new Vector2(1, 1), Colour = Color4.Black, Alpha = 0.4f, Icon = FontAwesome.fa_circle_o_notch }, spinner = new SpriteIcon { - RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Icon = FontAwesome.fa_circle_o_notch } }; @@ -53,7 +53,6 @@ namespace osu.Game.Graphics.UserInterface spinnerShadow.Spin(spin_duration, RotationDirection.Clockwise); } - protected override void PopIn() => this.FadeIn(transition_duration * 2, Easing.OutQuint); protected override void PopOut() => this.FadeOut(transition_duration, Easing.OutQuint); From b88c4464cb7eee25ae7c6791b881df7ba192f898 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Jun 2018 16:02:49 +0900 Subject: [PATCH 083/125] 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 084/125] 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 085/125] 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 e197ebe4c52a91cd9ff58a7cdbc367172efae2c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 01:55:09 +0900 Subject: [PATCH 086/125] 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 087/125] 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 088/125] 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 089/125] 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 090/125] 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 091/125] 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 092/125] 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 093/125] 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 094/125] 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 095/125] 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 096/125] 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 097/125] 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 0ef5b8f464697d6bed9648acbeab67b2f3f0c4b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 28 Jun 2018 19:19:00 +0900 Subject: [PATCH 098/125] 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 099/125] 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 100/125] 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 101/125] 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 102/125] 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 103/125] 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 104/125] 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 105/125] 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 106/125] 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 107/125] 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 108/125] 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 109/125] 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 110/125] 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 111/125] 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 112/125] 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 113/125] 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 114/125] 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 115/125] 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 116/125] 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 117/125] 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 118/125] 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 119/125] 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 06bd3d48151af534b9df05c9e784eca59f0914b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 29 Jun 2018 20:28:28 +0900 Subject: [PATCH 120/125] 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 121/125] 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 122/125] 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 98fb2e03c0bcf3ebc47e65855d82ab6ada6bf04e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jul 2018 18:03:15 +0900 Subject: [PATCH 123/125] 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 f007e71c87369e7e07e65fe5c1fdb2dae23d6ba2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 2 Jul 2018 12:31:41 +0900 Subject: [PATCH 124/125] 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 125/125] 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;