From d63b1a5cc53045cfb7c17be326700fa846626381 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 16 Mar 2017 14:54:39 +0900 Subject: [PATCH 01/12] Add target score computation functionality to ScoreProcessor. --- osu.Game/Modes/ScoreProcessor.cs | 76 ++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/osu.Game/Modes/ScoreProcessor.cs b/osu.Game/Modes/ScoreProcessor.cs index 3900a79485..e4b8d19eab 100644 --- a/osu.Game/Modes/ScoreProcessor.cs +++ b/osu.Game/Modes/ScoreProcessor.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using osu.Game.Modes.Judgements; using osu.Game.Modes.UI; using osu.Game.Modes.Objects; +using osu.Game.Beatmaps; namespace osu.Game.Modes { @@ -42,6 +43,13 @@ namespace osu.Game.Modes /// public readonly BindableInt HighestCombo = new BindableInt(); + protected ScoreProcessor() + { + Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; + + Reset(); + } + public virtual Score GetScore() => new Score { TotalScore = TotalScore, @@ -52,10 +60,16 @@ namespace osu.Game.Modes }; /// - /// Checks if the score is in a failing state. + /// Resets this ScoreProcessor to a stale state. /// - /// Whether the score is in a failing state. - public abstract bool CheckFailed(); + protected virtual void Reset() + { + TotalScore.Value = 0; + Accuracy.Value = 0; + Health.Value = 0; + Combo.Value = 0; + HighestCombo.Value = 0; + } /// /// Notifies subscribers that the score is in a failed state. @@ -64,6 +78,12 @@ namespace osu.Game.Modes { Failed?.Invoke(); } + + /// + /// Checks if the score is in a failing state. + /// + /// Whether the score is in a failing state. + public abstract bool CheckFailed(); } public abstract class ScoreProcessor : ScoreProcessor @@ -87,18 +107,35 @@ namespace osu.Game.Modes protected ScoreProcessor() { - Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; + } + + protected ScoreProcessor(HitRenderer hitRenderer) + { + Judgements.Capacity = hitRenderer.Beatmap.HitObjects.Count; + hitRenderer.OnJudgement += addJudgement; + + ComputeTargets(hitRenderer.Beatmap); Reset(); } - protected ScoreProcessor(HitRenderer hitRenderer) - : this() + public override bool CheckFailed() { - Judgements.Capacity = hitRenderer.Beatmap.HitObjects.Count; - hitRenderer.OnJudgement += addJudgement; + if (!hasFailed && IsFailable) + { + hasFailed = true; + TriggerFailed(); + } + + return hasFailed; } + /// + /// Computes target scoring values for this ScoreProcessor. This is equivalent to performing an auto-play of the score to find the values. + /// + /// The Beatmap containing the objects that will be judged by this ScoreProcessor. + protected virtual void ComputeTargets(Beatmap beatmap) { } + /// /// Adds a judgement to this ScoreProcessor. /// @@ -114,30 +151,11 @@ namespace osu.Game.Modes CheckFailed(); } - public override bool CheckFailed() - { - if (!hasFailed && IsFailable) - { - hasFailed = true; - TriggerFailed(); - } - - return hasFailed; - } - - /// - /// Resets this ScoreProcessor to a stale state. - /// - protected virtual void Reset() + protected override void Reset() { Judgements.Clear(); hasFailed = false; - TotalScore.Value = 0; - Accuracy.Value = 0; - Health.Value = 0; - Combo.Value = 0; - HighestCombo.Value = 0; } /// @@ -146,4 +164,4 @@ namespace osu.Game.Modes /// A new JudgementInfo that triggered this calculation. May be null. protected abstract void UpdateCalculations(TJudgement newJudgement); } -} +} \ No newline at end of file From 0c476388204c61798ea9444ca8b356c4c0ba886f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 16 Mar 2017 16:55:08 +0900 Subject: [PATCH 02/12] Better hit object defaults setting. --- .../Beatmaps/OsuBeatmapProcessor.cs | 5 --- osu.Game.Modes.Osu/Objects/OsuHitObject.cs | 7 +++-- osu.Game.Modes.Osu/Objects/Slider.cs | 13 +++----- osu.Game/Beatmaps/IBeatmapProcessor.cs | 15 +++------ osu.Game/Modes/Objects/HitObject.cs | 6 ++++ osu.Game/Modes/Objects/HitObjectDefaults.cs | 25 +++++++++++++++ osu.Game/Modes/UI/HitRenderer.cs | 31 ++++++++++++++----- osu.Game/osu.Game.csproj | 1 + 8 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 osu.Game/Modes/Objects/HitObjectDefaults.cs diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs index 1f7785f174..08c9d94141 100644 --- a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -8,11 +8,6 @@ namespace osu.Game.Modes.Osu.Beatmaps { internal class OsuBeatmapProcessor : IBeatmapProcessor { - public void SetDefaults(OsuHitObject hitObject, Beatmap beatmap) - { - hitObject.SetDefaultsFromBeatmap(beatmap); - } - public void PostProcess(Beatmap beatmap) { if (beatmap.ComboColors.Count == 0) diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs index cee55a281c..42313a7e71 100644 --- a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs @@ -3,7 +3,6 @@ using osu.Game.Modes.Objects; using OpenTK; -using osu.Game.Beatmaps; using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.Objects.Types; using OpenTK.Graphics; @@ -67,9 +66,11 @@ namespace osu.Game.Modes.Osu.Objects return OsuScoreResult.Miss; } - public virtual void SetDefaultsFromBeatmap(Beatmap beatmap) + public override void ApplyDefaults(HitObjectDefaults defaults) { - Scale = (1.0f - 0.7f * (beatmap.BeatmapInfo.Difficulty.CircleSize - 5) / 5) / 2; + base.ApplyDefaults(defaults); + + Scale = (1.0f - 0.7f * (defaults.Difficulty.CircleSize - 5) / 5) / 2; } } } diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index fdf3658d44..35883ff131 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Beatmaps; using osu.Game.Beatmaps.Samples; using osu.Game.Beatmaps.Timing; using osu.Game.Modes.Objects.Types; @@ -47,19 +46,17 @@ namespace osu.Game.Modes.Osu.Objects public double Velocity; public double TickDistance; - public override void SetDefaultsFromBeatmap(Beatmap beatmap) + public override void ApplyDefaults(HitObjectDefaults defaults) { - base.SetDefaultsFromBeatmap(beatmap); - - var baseDifficulty = beatmap.BeatmapInfo.Difficulty; + base.ApplyDefaults(defaults); ControlPoint overridePoint; - ControlPoint timingPoint = beatmap.TimingInfo.TimingPointAt(StartTime, out overridePoint); + ControlPoint timingPoint = defaults.Timing.TimingPointAt(StartTime, out overridePoint); var velocityAdjustment = overridePoint?.VelocityAdjustment ?? 1; - var baseVelocity = 100 * baseDifficulty.SliderMultiplier / velocityAdjustment; + var baseVelocity = 100 * defaults.Difficulty.SliderMultiplier / velocityAdjustment; Velocity = baseVelocity / timingPoint.BeatLength; - TickDistance = baseVelocity / baseDifficulty.SliderTickRate; + TickDistance = baseVelocity / defaults.Difficulty.SliderTickRate; } public IEnumerable Ticks diff --git a/osu.Game/Beatmaps/IBeatmapProcessor.cs b/osu.Game/Beatmaps/IBeatmapProcessor.cs index 3773f69279..9157a760b1 100644 --- a/osu.Game/Beatmaps/IBeatmapProcessor.cs +++ b/osu.Game/Beatmaps/IBeatmapProcessor.cs @@ -8,17 +8,10 @@ namespace osu.Game.Beatmaps /// /// Processes a post-converted Beatmap. /// - /// The type of HitObject contained in the Beatmap. - public interface IBeatmapProcessor - where T : HitObject + /// The type of HitObject contained in the Beatmap. + public interface IBeatmapProcessor + where TObject : HitObject { - /// - /// Sets default values for a HitObject. - /// - /// The HitObject to set default values for. - /// The Beatmap to extract the default values from. - void SetDefaults(T hitObject, Beatmap beatmap); - /// /// Post-processes a Beatmap to add mode-specific components that aren't added during conversion. /// @@ -26,6 +19,6 @@ namespace osu.Game.Beatmaps /// /// /// The Beatmap to process. - void PostProcess(Beatmap beatmap); + void PostProcess(Beatmap beatmap); } } diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs index e43702e2da..94e1f88b7f 100644 --- a/osu.Game/Modes/Objects/HitObject.cs +++ b/osu.Game/Modes/Objects/HitObject.cs @@ -22,5 +22,11 @@ namespace osu.Game.Modes.Objects /// The sample to be played when this HitObject is hit. /// public HitSampleInfo Sample { get; set; } + + /// + /// Applies default values to this HitObject. + /// + /// The default values to apply. + public virtual void ApplyDefaults(HitObjectDefaults defaults) { } } } diff --git a/osu.Game/Modes/Objects/HitObjectDefaults.cs b/osu.Game/Modes/Objects/HitObjectDefaults.cs new file mode 100644 index 0000000000..7a0d64391e --- /dev/null +++ b/osu.Game/Modes/Objects/HitObjectDefaults.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Timing; +using osu.Game.Database; + +namespace osu.Game.Modes.Objects +{ + /// + /// A set of default Beatmap values for HitObjects to consume. + /// + public class HitObjectDefaults + { + /// + /// The Beatmap timing. + /// + public TimingInfo Timing; + + /// + /// The Beatmap difficulty. + /// + public BaseDifficulty Difficulty; + } +} diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index a0ca2549c0..da47bf2c67 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -9,6 +9,7 @@ using osu.Game.Modes.Judgements; using osu.Game.Modes.Mods; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; +using osu.Game.Modes.Objects.Types; using osu.Game.Screens.Play; using System; using System.Collections.Generic; @@ -86,16 +87,32 @@ namespace osu.Game.Modes.UI { Debug.Assert(beatmap != null, "HitRenderer initialized with a null beatmap."); - // Convert + process the beatmap - Beatmap = CreateBeatmapConverter().Convert(beatmap.Beatmap); - Beatmap.HitObjects.ForEach(h => CreateBeatmapProcessor().SetDefaults(h, Beatmap)); - CreateBeatmapProcessor().PostProcess(Beatmap); - - applyMods(beatmap.Mods.Value); - RelativeSizeAxes = Axes.Both; + + IBeatmapConverter converter = CreateBeatmapConverter(); + IBeatmapProcessor processor = CreateBeatmapProcessor(); + + // Convert the beatmap + Beatmap = converter.Convert(beatmap.Beatmap); + + // Apply defaults + HitObjectDefaults defaults = new HitObjectDefaults + { + Timing = Beatmap.TimingInfo, + Difficulty = Beatmap.BeatmapInfo.BaseDifficulty + }; + + foreach (var h in Beatmap.HitObjects) + h.ApplyDefaults(defaults); + + // Post-process the beatmap + processor.PostProcess(Beatmap); + + // Add mods, should always be the last thing applied to give full control to mods + applyMods(beatmap.Mods.Value); } + /// /// Applies the active mods to this HitRenderer. /// diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 80d5c906e0..d7370078ed 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -100,6 +100,7 @@ + From 9f6f581b6439ebee7c9d96785781b0a6c4745067 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 16 Mar 2017 17:24:41 +0900 Subject: [PATCH 03/12] Pass through method instead of instantiating object. --- osu.Game.Modes.Osu/Objects/OsuHitObject.cs | 8 ++++--- osu.Game.Modes.Osu/Objects/Slider.cs | 11 ++++----- osu.Game/Modes/Objects/HitObject.cs | 7 ++++-- osu.Game/Modes/Objects/HitObjectDefaults.cs | 25 --------------------- osu.Game/Modes/UI/HitRenderer.cs | 9 +------- osu.Game/osu.Game.csproj | 1 - 6 files changed, 17 insertions(+), 44 deletions(-) delete mode 100644 osu.Game/Modes/Objects/HitObjectDefaults.cs diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs index 42313a7e71..9648ba9c87 100644 --- a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs @@ -6,6 +6,8 @@ using OpenTK; using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.Objects.Types; using OpenTK.Graphics; +using osu.Game.Beatmaps.Timing; +using osu.Game.Database; namespace osu.Game.Modes.Osu.Objects { @@ -66,11 +68,11 @@ namespace osu.Game.Modes.Osu.Objects return OsuScoreResult.Miss; } - public override void ApplyDefaults(HitObjectDefaults defaults) + public override void ApplyDefaults(TimingInfo timing, BaseDifficulty difficulty) { - base.ApplyDefaults(defaults); + base.ApplyDefaults(timing, difficulty); - Scale = (1.0f - 0.7f * (defaults.Difficulty.CircleSize - 5) / 5) / 2; + Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } } } diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index 35883ff131..baa6e9442d 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -8,6 +8,7 @@ using osu.Game.Modes.Objects.Types; using System; using System.Collections.Generic; using osu.Game.Modes.Objects; +using osu.Game.Database; namespace osu.Game.Modes.Osu.Objects { @@ -46,17 +47,17 @@ namespace osu.Game.Modes.Osu.Objects public double Velocity; public double TickDistance; - public override void ApplyDefaults(HitObjectDefaults defaults) + public override void ApplyDefaults(TimingInfo timing, BaseDifficulty difficulty) { - base.ApplyDefaults(defaults); + base.ApplyDefaults(timing, difficulty); ControlPoint overridePoint; - ControlPoint timingPoint = defaults.Timing.TimingPointAt(StartTime, out overridePoint); + ControlPoint timingPoint = timing.TimingPointAt(StartTime, out overridePoint); var velocityAdjustment = overridePoint?.VelocityAdjustment ?? 1; - var baseVelocity = 100 * defaults.Difficulty.SliderMultiplier / velocityAdjustment; + var baseVelocity = 100 * difficulty.SliderMultiplier / velocityAdjustment; Velocity = baseVelocity / timingPoint.BeatLength; - TickDistance = baseVelocity / defaults.Difficulty.SliderTickRate; + TickDistance = baseVelocity / difficulty.SliderTickRate; } public IEnumerable Ticks diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs index 94e1f88b7f..7fe30ff1ac 100644 --- a/osu.Game/Modes/Objects/HitObject.cs +++ b/osu.Game/Modes/Objects/HitObject.cs @@ -2,6 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps.Samples; +using osu.Game.Beatmaps.Timing; +using osu.Game.Database; namespace osu.Game.Modes.Objects { @@ -26,7 +28,8 @@ namespace osu.Game.Modes.Objects /// /// Applies default values to this HitObject. /// - /// The default values to apply. - public virtual void ApplyDefaults(HitObjectDefaults defaults) { } + /// The difficulty settings to use. + /// The timing settings to use. + public virtual void ApplyDefaults(TimingInfo timing, BaseDifficulty difficulty) { } } } diff --git a/osu.Game/Modes/Objects/HitObjectDefaults.cs b/osu.Game/Modes/Objects/HitObjectDefaults.cs deleted file mode 100644 index 7a0d64391e..0000000000 --- a/osu.Game/Modes/Objects/HitObjectDefaults.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Timing; -using osu.Game.Database; - -namespace osu.Game.Modes.Objects -{ - /// - /// A set of default Beatmap values for HitObjects to consume. - /// - public class HitObjectDefaults - { - /// - /// The Beatmap timing. - /// - public TimingInfo Timing; - - /// - /// The Beatmap difficulty. - /// - public BaseDifficulty Difficulty; - } -} diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index da47bf2c67..6707f7aa15 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -9,7 +9,6 @@ using osu.Game.Modes.Judgements; using osu.Game.Modes.Mods; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; -using osu.Game.Modes.Objects.Types; using osu.Game.Screens.Play; using System; using System.Collections.Generic; @@ -96,14 +95,8 @@ namespace osu.Game.Modes.UI Beatmap = converter.Convert(beatmap.Beatmap); // Apply defaults - HitObjectDefaults defaults = new HitObjectDefaults - { - Timing = Beatmap.TimingInfo, - Difficulty = Beatmap.BeatmapInfo.BaseDifficulty - }; - foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(defaults); + h.ApplyDefaults(Beatmap.TimingInfo, Beatmap.BeatmapInfo.BaseDifficulty); // Post-process the beatmap processor.PostProcess(Beatmap); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d7370078ed..80d5c906e0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -100,7 +100,6 @@ - From faacac331d8b70810540d766b1bd66fa75b9ed87 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 00:38:40 +0900 Subject: [PATCH 04/12] Fix post-rebase issues. --- osu.Game.Modes.Osu/Objects/OsuHitObject.cs | 2 +- osu.Game.Modes.Osu/Objects/Slider.cs | 2 +- osu.Game/Modes/Objects/HitObject.cs | 2 +- osu.Game/Modes/UI/HitRenderer.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs index 9648ba9c87..bedde7a763 100644 --- a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs @@ -68,7 +68,7 @@ namespace osu.Game.Modes.Osu.Objects return OsuScoreResult.Miss; } - public override void ApplyDefaults(TimingInfo timing, BaseDifficulty difficulty) + public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty) { base.ApplyDefaults(timing, difficulty); diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index baa6e9442d..d94b6534ed 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -47,7 +47,7 @@ namespace osu.Game.Modes.Osu.Objects public double Velocity; public double TickDistance; - public override void ApplyDefaults(TimingInfo timing, BaseDifficulty difficulty) + public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty) { base.ApplyDefaults(timing, difficulty); diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs index 7fe30ff1ac..f2712d92ba 100644 --- a/osu.Game/Modes/Objects/HitObject.cs +++ b/osu.Game/Modes/Objects/HitObject.cs @@ -30,6 +30,6 @@ namespace osu.Game.Modes.Objects /// /// The difficulty settings to use. /// The timing settings to use. - public virtual void ApplyDefaults(TimingInfo timing, BaseDifficulty difficulty) { } + public virtual void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty) { } } } diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index 6707f7aa15..0faa986fc7 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -96,7 +96,7 @@ namespace osu.Game.Modes.UI // Apply defaults foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(Beatmap.TimingInfo, Beatmap.BeatmapInfo.BaseDifficulty); + h.ApplyDefaults(Beatmap.TimingInfo, Beatmap.BeatmapInfo.Difficulty); // Post-process the beatmap processor.PostProcess(Beatmap); From 33124d2849a151d385aa8533ec1ae3408ad06bb4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 01:21:59 +0900 Subject: [PATCH 05/12] Stale -> default. --- osu.Game/Modes/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Modes/ScoreProcessor.cs b/osu.Game/Modes/ScoreProcessor.cs index e4b8d19eab..297b9a98bc 100644 --- a/osu.Game/Modes/ScoreProcessor.cs +++ b/osu.Game/Modes/ScoreProcessor.cs @@ -60,7 +60,7 @@ namespace osu.Game.Modes }; /// - /// Resets this ScoreProcessor to a stale state. + /// Resets this ScoreProcessor to a default state. /// protected virtual void Reset() { From 52c1cd407c2169b6635a775247f195c91e3884ec Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 01:26:03 +0900 Subject: [PATCH 06/12] Minor re-ordering to make Playfield OnJudgement be called before ScoreProcessor's. --- osu.Game/Modes/UI/HitRenderer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index a0ca2549c0..c7afe2f643 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -190,9 +190,10 @@ namespace osu.Game.Modes.UI /// The object that Judgement has been updated for. private void onJudgement(DrawableHitObject judgedObject) { - OnJudgement?.Invoke(judgedObject.Judgement); Playfield.OnJudgement(judgedObject); + OnJudgement?.Invoke(judgedObject.Judgement); + CheckAllJudged(); } From 2394e7ff783b0e733f072c698f77215337ffcc27 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 01:36:30 +0900 Subject: [PATCH 07/12] Make CheckFailed not actually trigger internal things, and make private. --- osu.Game/Modes/ScoreProcessor.cs | 46 +++++++++++++++----------------- osu.Game/Screens/Play/Player.cs | 9 ++----- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/osu.Game/Modes/ScoreProcessor.cs b/osu.Game/Modes/ScoreProcessor.cs index 297b9a98bc..c78d9c4e1a 100644 --- a/osu.Game/Modes/ScoreProcessor.cs +++ b/osu.Game/Modes/ScoreProcessor.cs @@ -43,6 +43,11 @@ namespace osu.Game.Modes /// public readonly BindableInt HighestCombo = new BindableInt(); + /// + /// Whether the score is in a failed state. + /// + public virtual bool HasFailed { get; } + protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; @@ -78,12 +83,6 @@ namespace osu.Game.Modes { Failed?.Invoke(); } - - /// - /// Checks if the score is in a failing state. - /// - /// Whether the score is in a failing state. - public abstract bool CheckFailed(); } public abstract class ScoreProcessor : ScoreProcessor @@ -95,15 +94,12 @@ namespace osu.Game.Modes /// protected readonly List Judgements = new List(); - /// - /// Whether the score is in a failable state. - /// - protected virtual bool IsFailable => Health.Value == Health.MinValue; + public override bool HasFailed => Health.Value == Health.MinValue; /// /// Whether this ScoreProcessor has already failed. /// - private bool hasFailed; + private bool alreadyFailed; protected ScoreProcessor() { @@ -119,17 +115,6 @@ namespace osu.Game.Modes Reset(); } - public override bool CheckFailed() - { - if (!hasFailed && IsFailable) - { - hasFailed = true; - TriggerFailed(); - } - - return hasFailed; - } - /// /// Computes target scoring values for this ScoreProcessor. This is equivalent to performing an auto-play of the score to find the values. /// @@ -148,14 +133,27 @@ namespace osu.Game.Modes judgement.ComboAtHit = (ulong)Combo.Value; - CheckFailed(); + updateFailed(); + } + + /// + /// Checks if the score is in a failing state. + /// + /// Whether the score is in a failing state. + private void updateFailed() + { + if (alreadyFailed || !HasFailed) + return; + + alreadyFailed = true; + TriggerFailed(); } protected override void Reset() { Judgements.Clear(); - hasFailed = false; + alreadyFailed = false; } /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ec8cbb1438..1bde2b004e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -239,14 +239,9 @@ namespace osu.Game.Screens.Play private void onCompletion() { - // Force a final check to see if the player has failed - // Some game modes (e.g. taiko) fail at the end of the map - if (scoreProcessor.CheckFailed()) - { - // If failed, onFail will be invoked which will push a new screen. - // Let's not push the completion screen in this case + // Only show the completion screen if the player hasn't failed + if (scoreProcessor.HasFailed) return; - } Delay(1000); Schedule(delegate From fe11f328e604e06acb4708ab59cf31f516da27c4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 02:00:06 +0900 Subject: [PATCH 08/12] Cleanups. --- osu.Game/Modes/ScoreProcessor.cs | 45 ++++++++++++++------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/osu.Game/Modes/ScoreProcessor.cs b/osu.Game/Modes/ScoreProcessor.cs index c78d9c4e1a..6234af9c5f 100644 --- a/osu.Game/Modes/ScoreProcessor.cs +++ b/osu.Game/Modes/ScoreProcessor.cs @@ -14,7 +14,7 @@ namespace osu.Game.Modes public abstract class ScoreProcessor { /// - /// Invoked when the score is in a failing state. + /// Invoked when the score is in a failed state. /// public event Action Failed; @@ -46,7 +46,12 @@ namespace osu.Game.Modes /// /// Whether the score is in a failed state. /// - public virtual bool HasFailed { get; } + public virtual bool HasFailed => false; + + /// + /// Whether this ScoreProcessor has already triggered the failed state. + /// + private bool alreadyFailed; protected ScoreProcessor() { @@ -74,13 +79,22 @@ namespace osu.Game.Modes Health.Value = 0; Combo.Value = 0; HighestCombo.Value = 0; + + alreadyFailed = false; } /// - /// Notifies subscribers that the score is in a failed state. + /// Checks if the score is in a failed state and notifies subscribers. + /// + /// This can only ever notify subscribers once. + /// /// - protected void TriggerFailed() + protected void UpdateFailed() { + if (alreadyFailed || !HasFailed) + return; + + alreadyFailed = true; Failed?.Invoke(); } } @@ -96,11 +110,6 @@ namespace osu.Game.Modes public override bool HasFailed => Health.Value == Health.MinValue; - /// - /// Whether this ScoreProcessor has already failed. - /// - private bool alreadyFailed; - protected ScoreProcessor() { } @@ -108,6 +117,7 @@ namespace osu.Game.Modes protected ScoreProcessor(HitRenderer hitRenderer) { Judgements.Capacity = hitRenderer.Beatmap.HitObjects.Count; + hitRenderer.OnJudgement += addJudgement; ComputeTargets(hitRenderer.Beatmap); @@ -133,27 +143,12 @@ namespace osu.Game.Modes judgement.ComboAtHit = (ulong)Combo.Value; - updateFailed(); - } - - /// - /// Checks if the score is in a failing state. - /// - /// Whether the score is in a failing state. - private void updateFailed() - { - if (alreadyFailed || !HasFailed) - return; - - alreadyFailed = true; - TriggerFailed(); + UpdateFailed(); } protected override void Reset() { Judgements.Clear(); - - alreadyFailed = false; } /// From d5ec7f15d462473ef5a90c2896a0b10bddbf56f0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 02:00:58 +0900 Subject: [PATCH 09/12] score -> ScoreProcessor. --- osu.Game/Modes/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Modes/ScoreProcessor.cs b/osu.Game/Modes/ScoreProcessor.cs index 6234af9c5f..1a8c1c0763 100644 --- a/osu.Game/Modes/ScoreProcessor.cs +++ b/osu.Game/Modes/ScoreProcessor.cs @@ -14,7 +14,7 @@ namespace osu.Game.Modes public abstract class ScoreProcessor { /// - /// Invoked when the score is in a failed state. + /// Invoked when the ScoreProcessor is in a failed state. /// public event Action Failed; From 9a4af8f1949d3c0ba31e32c934df8fb4eb14f289 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 02:03:12 +0900 Subject: [PATCH 10/12] GetScore -> CreateScore. --- osu.Game/Database/ScoreDatabase.cs | 2 +- osu.Game/Modes/ScoreProcessor.cs | 6 +++++- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/ScoreDatabase.cs b/osu.Game/Database/ScoreDatabase.cs index a8eb5e1886..cfa8e6ac7e 100644 --- a/osu.Game/Database/ScoreDatabase.cs +++ b/osu.Game/Database/ScoreDatabase.cs @@ -39,7 +39,7 @@ namespace osu.Game.Database using (SerializationReader sr = new SerializationReader(s)) { var ruleset = Ruleset.GetRuleset((PlayMode)sr.ReadByte()); - score = ruleset.CreateScoreProcessor().GetScore(); + score = ruleset.CreateScoreProcessor().CreateScore(); /* score.Pass = true;*/ var version = sr.ReadInt32(); diff --git a/osu.Game/Modes/ScoreProcessor.cs b/osu.Game/Modes/ScoreProcessor.cs index 1a8c1c0763..a6e29d53e1 100644 --- a/osu.Game/Modes/ScoreProcessor.cs +++ b/osu.Game/Modes/ScoreProcessor.cs @@ -60,7 +60,11 @@ namespace osu.Game.Modes Reset(); } - public virtual Score GetScore() => new Score + /// + /// Creates a Score applicable to the game mode in which this ScoreProcessor resides. + /// + /// The Score. + public virtual Score CreateScore() => new Score { TotalScore = TotalScore, Combo = Combo, diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 1bde2b004e..674a741d8c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -249,7 +249,7 @@ namespace osu.Game.Screens.Play ValidForResume = false; Push(new Results { - Score = scoreProcessor.GetScore() + Score = scoreProcessor.CreateScore() }); }); } From 88dfdf3f85e857595e8fbda1e4fd91bfe9b37979 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 02:22:52 +0900 Subject: [PATCH 11/12] Add xmldoc. --- osu.Game/Modes/UI/HitRenderer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index c7afe2f643..1971559f49 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -25,6 +25,9 @@ namespace osu.Game.Modes.UI /// public abstract class HitRenderer : Container { + /// + /// Invoked when all the judgeable HitObjects have been judged. + /// public event Action OnAllJudged; /// From a06c195e1f9a4418c67d3b5080725ce7840d5bd1 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 13:23:39 +0900 Subject: [PATCH 12/12] Add reading of KiaiMode/OmitFirstBarLine from legacy control points. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 4 +++- osu.Game/Beatmaps/Timing/ControlPoint.cs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index e7ede36b4b..efdcea4b41 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -197,7 +197,7 @@ namespace osu.Game.Beatmaps.Formats if (split.Length > 2) { - //int kiaiFlags = split.Length > 7 ? Convert.ToInt32(split[7], NumberFormatInfo.InvariantInfo) : 0; + int effectFlags = split.Length > 7 ? Convert.ToInt32(split[7], NumberFormatInfo.InvariantInfo) : 0; double beatLength = double.Parse(split[1].Trim(), NumberFormatInfo.InvariantInfo); cp = new ControlPoint { @@ -205,6 +205,8 @@ namespace osu.Game.Beatmaps.Formats BeatLength = beatLength > 0 ? beatLength : 0, VelocityAdjustment = beatLength < 0 ? -beatLength / 100.0 : 1, TimingChange = split.Length <= 6 || split[6][0] == '1', + KiaiMode = (effectFlags & 1) > 0, + OmitFirstBarLine = (effectFlags & 8) > 0 }; } diff --git a/osu.Game/Beatmaps/Timing/ControlPoint.cs b/osu.Game/Beatmaps/Timing/ControlPoint.cs index bd53928a32..e323412f81 100644 --- a/osu.Game/Beatmaps/Timing/ControlPoint.cs +++ b/osu.Game/Beatmaps/Timing/ControlPoint.cs @@ -16,6 +16,7 @@ namespace osu.Game.Beatmaps.Timing public double VelocityAdjustment; public bool TimingChange; public bool KiaiMode; + public bool OmitFirstBarLine; }