From d63b1a5cc53045cfb7c17be326700fa846626381 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 16 Mar 2017 14:54:39 +0900 Subject: [PATCH 1/8] 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 33124d2849a151d385aa8533ec1ae3408ad06bb4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 17 Mar 2017 01:21:59 +0900 Subject: [PATCH 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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; ///