diff --git a/osu.Game.Mode.Osu/OsuScoreProcessor.cs b/osu.Game.Mode.Osu/OsuScoreProcessor.cs index 8ff053f96f..177844297e 100644 --- a/osu.Game.Mode.Osu/OsuScoreProcessor.cs +++ b/osu.Game.Mode.Osu/OsuScoreProcessor.cs @@ -3,10 +3,60 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using osu.Game.Modes.Objects.Drawables; +using osu.Game.Modes.Osu.Objects.Drawables; namespace osu.Game.Modes.Osu { class OsuScoreProcessor : ScoreProcessor { + public override void AddJudgement(JudgementInfo judgement) + { + base.AddJudgement(judgement); + + switch (judgement.Result) + { + case HitResult.Hit: + Combo.Value++; + break; + case HitResult.Miss: + Combo.Value = 0; + break; + } + } + protected override void UpdateCalculations() + { + base.UpdateCalculations(); + + int score = 0; + int maxScore = 0; + + foreach (OsuJudgementInfo j in Judgements) + { + switch (j.Score) + { + case OsuScoreResult.Miss: + maxScore += 300; + break; + case OsuScoreResult.Hit50: + score += 50; + maxScore += 300; + break; + case OsuScoreResult.Hit100: + score += 100; + maxScore += 300; + break; + case OsuScoreResult.Hit300: + score += 300; + maxScore += 300; + break; + } + + + } + + TotalScore.Value = score; + Accuracy.Value = (double)score / maxScore; + } } } diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index 3508d6c3a6..f00a24d79e 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -13,9 +13,7 @@ namespace osu.Game.Modes.Objects.Drawables { public abstract class DrawableHitObject : Container, IStateful { - //todo: move to a more central implementation. this logic should not be at a drawable level. - public Action OnHit; - public Action OnMiss; + public event Action OnJudgement; public Container ChildObjects; @@ -73,14 +71,14 @@ namespace osu.Game.Modes.Objects.Drawables { default: State = ArmedState.Hit; - OnHit?.Invoke(this, Judgement); break; case HitResult.Miss: State = ArmedState.Miss; - OnMiss?.Invoke(this, Judgement); break; } + OnJudgement?.Invoke(this, Judgement); + return true; } diff --git a/osu.Game/Modes/ScoreProcesssor.cs b/osu.Game/Modes/ScoreProcesssor.cs index 9d7eace60e..efae0bd40b 100644 --- a/osu.Game/Modes/ScoreProcesssor.cs +++ b/osu.Game/Modes/ScoreProcesssor.cs @@ -6,11 +6,35 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using osu.Framework.Configuration; +using osu.Game.Modes.Objects.Drawables; namespace osu.Game.Modes { public class ScoreProcessor { public virtual Score GetScore() => new Score(); + + public BindableDouble TotalScore = new BindableDouble { MinValue = 0 }; + + public BindableDouble Accuracy = new BindableDouble { MinValue = 0, MaxValue = 1 }; + + public BindableInt Combo = new BindableInt(); + + public List Judgements = new List(); + + public virtual void AddJudgement(JudgementInfo judgement) + { + Judgements.Add(judgement); + UpdateCalculations(); + } + + /// + /// Update any values that potentially need post-processing on a judgement change. + /// + protected virtual void UpdateCalculations() + { + + } } } diff --git a/osu.Game/Modes/UI/ComboCounter.cs b/osu.Game/Modes/UI/ComboCounter.cs index 0d34d5dd9a..b150111387 100644 --- a/osu.Game/Modes/UI/ComboCounter.cs +++ b/osu.Game/Modes/UI/ComboCounter.cs @@ -262,5 +262,13 @@ namespace osu.Game.Modes.UI (d as ComboCounter).DisplayedCount = CurrentValue; } } + + public void Set(ulong value) + { + if (value == 0) + Roll(); + else + Count = value; + } } } diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index d37cf545a8..5d70fd71a0 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -14,8 +14,9 @@ namespace osu.Game.Modes.UI { public abstract class HitRenderer : Container { - public Action OnHit; - public Action OnMiss; + public event Action OnJudgement; + + protected void TriggerOnJudgement(JudgementInfo j) => OnJudgement?.Invoke(j); protected Playfield Playfield; @@ -68,22 +69,13 @@ namespace osu.Game.Modes.UI if (drawableObject == null) continue; - drawableObject.OnHit = onHit; - drawableObject.OnMiss = onMiss; + drawableObject.OnJudgement += onJudgement; Playfield.Add(drawableObject); } } - private void onMiss(DrawableHitObject obj, JudgementInfo judgement) - { - OnMiss?.Invoke(obj.HitObject); - } - - private void onHit(DrawableHitObject obj, JudgementInfo judgement) - { - OnHit?.Invoke(obj.HitObject); - } + private void onJudgement(DrawableHitObject o, JudgementInfo j) => TriggerOnJudgement(j); protected abstract DrawableHitObject GetVisualRepresentation(T h); } diff --git a/osu.Game/Modes/UI/ScoreOverlay.cs b/osu.Game/Modes/UI/ScoreOverlay.cs index 9f29ff63ff..c7441483f8 100644 --- a/osu.Game/Modes/UI/ScoreOverlay.cs +++ b/osu.Game/Modes/UI/ScoreOverlay.cs @@ -49,7 +49,10 @@ namespace osu.Game.Modes.UI public void BindProcessor(ScoreProcessor processor) { - + //bind processor bindables to combocounter, score display etc. + processor.TotalScore.ValueChanged += delegate { ScoreCounter?.Set((ulong)processor.TotalScore.Value); }; + processor.Accuracy.ValueChanged += delegate { AccuracyCounter?.Set((float)processor.Accuracy.Value); }; + processor.Combo.ValueChanged += delegate { ComboCounter?.Set((ulong)processor.Combo.Value); }; } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 262e5c5fbc..1fa652afec 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -91,8 +91,7 @@ namespace osu.Game.Screens.Play var hitRenderer = ruleset.CreateHitRendererWith(beatmap.HitObjects); - hitRenderer.OnHit += delegate (HitObject h) { scoreOverlay.OnHit(h); }; - hitRenderer.OnMiss += delegate (HitObject h) { scoreOverlay.OnMiss(h); }; + hitRenderer.OnJudgement += scoreProcessor.AddJudgement; if (Autoplay) hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Hit));