From c6c255718b9a9d65e96f91d8e4e09fb3891f2188 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Mon, 3 Dec 2018 22:37:26 +0300 Subject: [PATCH 1/7] Handle ModAutoplay during score construction in the Player --- osu.Game.Tests/Visual/TestCaseReplay.cs | 2 +- osu.Game/Rulesets/Mods/ModAutoplay.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 15 ++++++++------- osu.Game/Screens/Play/Player.cs | 4 ++-- osu.Game/Screens/Play/ReplayPlayer.cs | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index e0ea613534..2f217d013b 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual // Reset the mods Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); - return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.Replay }); + return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.ReplayScore.Replay }); } } } diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index 932439618d..72ae88d67a 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mods public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; - public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay); + public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplayScore(CreateReplayScore(rulesetContainer.Beatmap)); } public abstract class ModAutoplay : Mod, IApplicableFailOverride diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 5967cad8d1..3dbaf0ce00 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -22,6 +22,7 @@ using osu.Game.Overlays; using osu.Game.Replays; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; namespace osu.Game.Rulesets.UI { @@ -125,7 +126,7 @@ namespace osu.Game.Rulesets.UI protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null; - public Replay Replay { get; private set; } + public Score ReplayScore { get; private set; } /// /// Whether the game is paused. Used to block user input. @@ -135,14 +136,14 @@ namespace osu.Game.Rulesets.UI /// /// Sets a replay to be used, overriding local input. /// - /// The replay, null for local input. - public virtual void SetReplay(Replay replay) + /// The replay, null for local input. + public virtual void SetReplayScore(Score replayScore) { if (ReplayInputManager == null) throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports replay loading is not available"); - Replay = replay; - ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; + ReplayScore = replayScore; + ReplayInputManager.ReplayInputHandler = replayScore != null ? CreateReplayInputHandler(replayScore.Replay) : null; HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null; } @@ -291,9 +292,9 @@ namespace osu.Game.Rulesets.UI mod.ReadFromConfig(config); } - public override void SetReplay(Replay replay) + public override void SetReplayScore(Score replayScore) { - base.SetReplay(replay); + base.SetReplayScore(replayScore); if (ReplayInputManager?.ReplayInputHandler != null) ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index bf44e9e636..7e80bd92c9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -277,7 +277,7 @@ namespace osu.Game.Screens.Play if (!IsCurrentScreen) return; var score = CreateScore(); - if (RulesetContainer.Replay == null) + if (RulesetContainer.ReplayScore == null) scoreManager.Import(score, true); Push(new Results(score)); @@ -289,7 +289,7 @@ namespace osu.Game.Screens.Play protected virtual ScoreInfo CreateScore() { - var score = new ScoreInfo + var score = RulesetContainer?.ReplayScore?.ScoreInfo ?? new ScoreInfo { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset, diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index fe77fd57f2..04cf922d74 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play protected override void LoadComplete() { base.LoadComplete(); - RulesetContainer.SetReplay(score.Replay); + RulesetContainer.SetReplayScore(score); } protected override ScoreInfo CreateScore() => score.ScoreInfo; From 2d0fdc820440e03cbc61dedf6b629c9a72c7abc4 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Sun, 9 Dec 2018 17:39:35 +0300 Subject: [PATCH 2/7] Create ReplayPlayer using Score from the dummy RulesetContainer --- osu.Game.Tests/Visual/TestCaseReplay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index 2f217d013b..0fc4616f56 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -5,7 +5,6 @@ using System.ComponentModel; using System.Linq; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; -using osu.Game.Scoring; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual @@ -23,7 +22,7 @@ namespace osu.Game.Tests.Visual // Reset the mods Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); - return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.ReplayScore.Replay }); + return new ReplayPlayer(dummyRulesetContainer.ReplayScore); } } } From c56d8b75c15d2c0a5f0145d18c3b7d1cf2286223 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jan 2019 17:43:10 +0900 Subject: [PATCH 3/7] Cache slider's endposition --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 26 ++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index d508ec2636..ffb7f7be9e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; using osu.Game.Rulesets.Objects; using System.Linq; +using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -26,8 +27,11 @@ namespace osu.Game.Rulesets.Osu.Objects public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; + private Cached endPositionCache; + + public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1); + public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t); - public override Vector2 EndPosition => Position + this.CurvePositionAt(1); public override int ComboIndex { @@ -56,7 +60,11 @@ namespace osu.Game.Rulesets.Osu.Objects public SliderPath Path { get => PathBindable.Value; - set => PathBindable.Value = value; + set + { + PathBindable.Value = value; + endPositionCache.Invalidate(); + } } public double Distance => Path.Distance; @@ -73,6 +81,8 @@ namespace osu.Game.Rulesets.Osu.Objects if (TailCircle != null) TailCircle.Position = EndPosition; + + endPositionCache.Invalidate(); } } @@ -92,7 +102,17 @@ namespace osu.Game.Rulesets.Osu.Objects public List> NodeSamples { get; set; } = new List>(); - public int RepeatCount { get; set; } + private int repeatCount; + + public int RepeatCount + { + get => repeatCount; + set + { + repeatCount = value; + endPositionCache.Invalidate(); + } + } /// /// The length of one span of this . From 273b14b19cc74a2feb60e0940f60a6f206f1e3e3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jan 2019 18:51:47 +0900 Subject: [PATCH 4/7] Add a maximum length for slider ticks to be generated --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index ffb7f7be9e..2d82f7aecf 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -24,6 +24,12 @@ namespace osu.Game.Rulesets.Osu.Objects /// private const float base_scoring_distance = 100; + /// + /// A very lenient maximum length of a slider for ticks to be generated. + /// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. + /// + private const double max_length_for_ticks = 100000; + public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; @@ -189,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Objects private void createTicks() { - var length = Path.Distance; + var length = Math.Min(max_length_for_ticks, Path.Distance); var tickDistance = MathHelper.Clamp(TickDistance, 0, length); if (tickDistance == 0) return; From 3fa5a33fb1edef5d18861c4dbb04928d6cf5252d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jan 2019 18:58:07 +0900 Subject: [PATCH 5/7] Inline const --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 2d82f7aecf..2af1de7355 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -24,12 +24,6 @@ namespace osu.Game.Rulesets.Osu.Objects /// private const float base_scoring_distance = 100; - /// - /// A very lenient maximum length of a slider for ticks to be generated. - /// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. - /// - private const double max_length_for_ticks = 100000; - public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; @@ -195,7 +189,11 @@ namespace osu.Game.Rulesets.Osu.Objects private void createTicks() { - var length = Math.Min(max_length_for_ticks, Path.Distance); + // A very lenient maximum length of a slider for ticks to be generated. + // This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage. + const double max_length = 100000; + + var length = Math.Min(max_length, Path.Distance); var tickDistance = MathHelper.Clamp(TickDistance, 0, length); if (tickDistance == 0) return; From 7d1163a7d2e3127a9154175578e53eb04bb6cad8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Jan 2019 15:49:23 +0900 Subject: [PATCH 6/7] Remove unnecessary null check --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e02de917eb..14dc644100 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -297,7 +297,7 @@ namespace osu.Game.Screens.Play protected virtual ScoreInfo CreateScore() { - var score = RulesetContainer?.ReplayScore?.ScoreInfo ?? new ScoreInfo + var score = RulesetContainer.ReplayScore?.ScoreInfo ?? new ScoreInfo { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset, From 4a7c6fb19d9c037f1557496c3b989dd8e53a73aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Jan 2019 16:33:35 +0900 Subject: [PATCH 7/7] Fix PP not display on profile overlay --- osu.Game/Scoring/ScoreInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index b863566967..78cc3592c7 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -31,7 +31,7 @@ namespace osu.Game.Scoring [Column(TypeName="DECIMAL(1,4)")] public double Accuracy { get; set; } - [JsonIgnore] + [JsonProperty(@"pp")] public double? PP { get; set; } [JsonProperty("max_combo")]