From 396ca9fe9163263ddd60936cc07cef59cdab15f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 26 Nov 2016 16:51:51 +0900 Subject: [PATCH] Remove HitJudgementResolver; reimplement in DrawableHitObject. --- .../Tests/TestCaseHitObjects.cs | 1 - .../Objects/Drawables/DrawableHitCircle.cs | 50 ++++++++++++-- .../Objects/Drawables/DrawableOsuHitObject.cs | 32 +++++---- .../Objects/Drawables/DrawableSlider.cs | 3 +- .../Objects/Drawables/HitExplosion.cs | 7 +- .../Objects/Drawables/Pieces/CirclePiece.cs | 3 +- osu.Game.Mode.Osu/OsuHitJudgementResolver.cs | 41 ------------ osu.Game.Mode.Osu/OsuRuleset.cs | 2 - osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 66 ++++++++++++++----- osu.Game/Modes/Ruleset.cs | 2 - osu.Game/Modes/UI/HitRenderer.cs | 4 +- osu.Game/Screens/Play/Player.cs | 5 -- osu.Game/osu.Game.csproj | 1 - 14 files changed, 115 insertions(+), 104 deletions(-) rename osu.Game/Modes/HitJudgementResolver.cs => osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs (51%) delete mode 100644 osu.Game.Mode.Osu/OsuHitJudgementResolver.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index 11365adafe..0569fcf3c3 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -52,7 +52,6 @@ namespace osu.Desktop.VisualTests.Tests Origin = Anchor.Centre, Depth = -i, State = ArmedState.Hit, - Judgement = new JudgementInfo { Result = HitResult.Hit300 } }; approachContainer.Add(d.ApproachCircle.CreateProxy()); diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs index a0add258f7..dc5d5bf2a6 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -2,6 +2,7 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.ComponentModel; using osu.Framework.Graphics; using osu.Framework.Graphics.Transformations; using osu.Game.Modes.Objects.Drawables; @@ -10,7 +11,7 @@ using OpenTK; namespace osu.Game.Modes.Osu.Objects.Drawables { - public class DrawableHitCircle : DrawableHitObject + public class DrawableHitCircle : DrawableOsuHitObject { private OsuHitObject osuObject; @@ -39,9 +40,12 @@ namespace osu.Game.Modes.Osu.Objects.Drawables circle = new CirclePiece { Colour = osuObject.Colour, - Hit = () => Hit(new JudgementInfo { - UserTriggered = true, - }), + Hit = () => + { + ((PositionalJudgementInfo)Judgement).PositionOffset = Vector2.Zero; //todo: set to correct value + UpdateJudgement(true); + return true; + }, }, number = new NumberPiece(), ring = new RingPiece(), @@ -68,6 +72,38 @@ namespace osu.Game.Modes.Osu.Objects.Drawables UpdateState(State); } + double hit50 = 150; + double hit100 = 80; + double hit300 = 30; + + protected override void CheckJudgement(bool userTriggered) + { + if (!userTriggered) + { + if (Judgement.TimeOffset > hit50) + Judgement.Result = HitResult.Miss; + return; + } + + double hitOffset = Math.Abs(Judgement.TimeOffset); + + if (hitOffset < hit50) + { + Judgement.Result = HitResult.Hit; + + OsuJudgementInfo osuInfo = Judgement as OsuJudgementInfo; + + if (hitOffset < hit300) + osuInfo.Score = OsuScoreResult.Hit300; + else if (hitOffset < hit100) + osuInfo.Score = OsuScoreResult.Hit100; + else if (hitOffset < hit50) + osuInfo.Score = OsuScoreResult.Hit50; + } + else + Judgement.Result = HitResult.Miss; + } + protected override void UpdateState(ArmedState state) { if (!IsLoaded) return; @@ -75,7 +111,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Flush(true); //move to DrawableHitObject ApproachCircle.Flush(true); - double t = osuObject.EndTime + (Judgement?.TimeOffset ?? 0); + double t = osuObject.EndTime + Judgement.TimeOffset; Alpha = 0; @@ -121,7 +157,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables explosion?.Expire(); explosion = null; - Schedule(() => Add(explosion = new HitExplosion(HitResult.Miss))); + Schedule(() => Add(explosion = new HitExplosion((OsuJudgementInfo)Judgement))); FadeOut(800); break; @@ -134,7 +170,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables explode.FadeIn(flash_in); - Schedule(() => Add(explosion = new HitExplosion(Judgement.Result))); + Schedule(() => Add(explosion = new HitExplosion((OsuJudgementInfo)Judgement))); Delay(flash_in, true); diff --git a/osu.Game/Modes/HitJudgementResolver.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs similarity index 51% rename from osu.Game/Modes/HitJudgementResolver.cs rename to osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs index d9f3cc96c1..d416732327 100644 --- a/osu.Game/Modes/HitJudgementResolver.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,34 +1,33 @@ -//Copyright (c) 2007-2016 ppy Pty Ltd . -//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; +using System; using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; -using OpenTK; -namespace osu.Game.Modes +namespace osu.Game.Modes.Osu.Objects.Drawables { - public class HitJudgementResolver + public class DrawableOsuHitObject : DrawableHitObject { - public virtual void CheckJudgement(DrawableHitObject h, JudgementInfo info) + public DrawableOsuHitObject(OsuHitObject hitObject) + : base(hitObject) { - info.Result = HitResult.Hit300; + } + + public override JudgementInfo CreateJudgementInfo() => new OsuJudgementInfo(); + + protected override void UpdateState(ArmedState state) + { + throw new NotImplementedException(); } } - public class JudgementInfo + public class OsuJudgementInfo : PositionalJudgementInfo { - public bool UserTriggered; + public OsuScoreResult Score; public ComboResult Combo; - public HitResult Result; - public double TimeOffset; - public Vector2 PositionOffset; } public enum ComboResult @@ -41,9 +40,8 @@ namespace osu.Game.Modes Perfect } - public enum HitResult + public enum OsuScoreResult { - Ignore, [Description(@"Miss")] Miss, [Description(@"50")] diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs index 50203d48ae..55e4781cd3 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs @@ -5,7 +5,7 @@ using OpenTK; namespace osu.Game.Modes.Osu.Objects.Drawables { - class DrawableSlider : DrawableHitObject + class DrawableSlider : DrawableOsuHitObject { public DrawableSlider(Slider h) : base(h) { @@ -18,7 +18,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Add(new CirclePiece { Colour = h.Colour, - Hit = () => Hit(new JudgementInfo()), Position = h.Curve.PositionAt(i) - h.Position //non-relative? }); } diff --git a/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs b/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs index fac9ab636b..a0ab68fa99 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transformations; +using osu.Game.Modes.Objects.Drawables; using OpenTK; namespace osu.Game.Modes.Osu.Objects.Drawables @@ -12,7 +13,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables private SpriteText line1; private SpriteText line2; - public HitExplosion(HitResult hitResult, ComboResult comboResult = ComboResult.None) + public HitExplosion(OsuJudgementInfo judgement) { AutoSizeAxes = Axes.Both; Anchor = Anchor.Centre; @@ -27,13 +28,13 @@ namespace osu.Game.Modes.Osu.Objects.Drawables { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Text = hitResult.GetDescription(), + Text = judgement.Score.GetDescription(), Font = @"Venera", TextSize = 20, }, line2 = new SpriteText { - Text = comboResult.GetDescription(), + Text = judgement.Combo.GetDescription(), Font = @"Venera", TextSize = 14, } diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs index c326c46553..fd55a8315a 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs @@ -49,8 +49,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - Hit?.Invoke(); - return true; + return Hit?.Invoke() ?? false; } } } \ No newline at end of file diff --git a/osu.Game.Mode.Osu/OsuHitJudgementResolver.cs b/osu.Game.Mode.Osu/OsuHitJudgementResolver.cs deleted file mode 100644 index 6dc240c7af..0000000000 --- a/osu.Game.Mode.Osu/OsuHitJudgementResolver.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -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 OsuHitJudgementResolver : HitJudgementResolver - { - double hit50 = 150; - double hit100 = 80; - double hit300 = 30; - public override void CheckJudgement(DrawableHitObject h, JudgementInfo info) - { - DrawableHitCircle circle = h as DrawableHitCircle; - if (circle != null) - { - if (!info.UserTriggered) - { - if (info.TimeOffset > hit50) - info.Result = HitResult.Miss; - return; - } - - double hitOffset = Math.Abs(info.TimeOffset); - - if (hitOffset < hit300) - info.Result = HitResult.Hit300; - else if (hitOffset < hit100) - info.Result = HitResult.Hit100; - else if (hitOffset < hit50) - info.Result = HitResult.Hit50; - else - info.Result = HitResult.Miss; - } - } - } -} diff --git a/osu.Game.Mode.Osu/OsuRuleset.cs b/osu.Game.Mode.Osu/OsuRuleset.cs index e79cbef748..ac43e5501c 100644 --- a/osu.Game.Mode.Osu/OsuRuleset.cs +++ b/osu.Game.Mode.Osu/OsuRuleset.cs @@ -13,8 +13,6 @@ namespace osu.Game.Modes.Osu { public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay(); - public override HitJudgementResolver CreateHitJudgement() => new OsuHitJudgementResolver(); - public override HitRenderer CreateHitRendererWith(List objects) => new OsuHitRenderer { Objects = objects }; public override HitObjectParser CreateHitObjectParser() => new OsuHitObjectParser(); diff --git a/osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj index d63cc2354a..97b4ebcb99 100644 --- a/osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj +++ b/osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj @@ -41,6 +41,7 @@ + @@ -52,7 +53,6 @@ - diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index 0d8b124be2..3508d6c3a6 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -2,23 +2,26 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.ComponentModel; using System.Diagnostics; using osu.Framework; using osu.Framework.Graphics.Containers; +using OpenTK; +using Container = osu.Framework.Graphics.Containers.Container; 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 Action CheckJudgement; + public Action OnHit; + public Action OnMiss; public Container ChildObjects; - public JudgementInfo Judgement; + protected JudgementInfo Judgement; + + public abstract JudgementInfo CreateJudgementInfo(); public HitObject HitObject; @@ -42,47 +45,55 @@ namespace osu.Game.Modes.Objects.Drawables } } + protected override void LoadComplete() + { + base.LoadComplete(); + + Judgement = CreateJudgementInfo(); + } + /// /// Process a hit of this hitobject. Carries out judgement. /// /// Preliminary judgement information provided by the hit source. /// Whether a hit was processed. - protected bool Hit(JudgementInfo judgement) + protected bool UpdateJudgement(bool userTriggered) { - if (State != ArmedState.Idle) + if (Judgement.Result != null) return false; - judgement.TimeOffset = Time.Current - HitObject.EndTime; + Judgement.TimeOffset = Time.Current - HitObject.EndTime; - CheckJudgement?.Invoke(this, judgement); + CheckJudgement(userTriggered); - if (judgement.Result == HitResult.Ignore) + if (Judgement.Result == null) return false; - Judgement = judgement; - - switch (judgement.Result) + switch (Judgement.Result) { default: State = ArmedState.Hit; - OnHit?.Invoke(this); + OnHit?.Invoke(this, Judgement); break; case HitResult.Miss: State = ArmedState.Miss; - OnMiss?.Invoke(this); + OnMiss?.Invoke(this, Judgement); break; } - return true; } + protected virtual void CheckJudgement(bool userTriggered) + { + + } + protected override void Update() { base.Update(); - if (Time.Current >= HitObject.EndTime && Judgement == null) - Hit(new JudgementInfo()); + UpdateJudgement(false); } protected abstract void UpdateState(ArmedState state); @@ -94,4 +105,23 @@ namespace osu.Game.Modes.Objects.Drawables Hit, Miss } + + public class PositionalJudgementInfo : JudgementInfo + { + public Vector2 PositionOffset; + } + + public class JudgementInfo + { + public HitResult? Result; + public double TimeOffset; + } + + public enum HitResult + { + [Description(@"Miss")] + Miss, + [Description(@"Hit")] + Hit, + } } diff --git a/osu.Game/Modes/Ruleset.cs b/osu.Game/Modes/Ruleset.cs index 6576159f62..d35aab6568 100644 --- a/osu.Game/Modes/Ruleset.cs +++ b/osu.Game/Modes/Ruleset.cs @@ -22,8 +22,6 @@ namespace osu.Game.Modes public abstract HitObjectParser CreateHitObjectParser(); - public virtual HitJudgementResolver CreateHitJudgement() => new HitJudgementResolver(); - public static void Register(Ruleset ruleset) => availableRulesets.TryAdd(ruleset.PlayMode, ruleset.GetType()); protected abstract PlayMode PlayMode { get; } diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index f160356cb4..d37cf545a8 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -75,12 +75,12 @@ namespace osu.Game.Modes.UI } } - private void onMiss(DrawableHitObject obj) + private void onMiss(DrawableHitObject obj, JudgementInfo judgement) { OnMiss?.Invoke(obj.HitObject); } - private void onHit(DrawableHitObject obj) + private void onHit(DrawableHitObject obj, JudgementInfo judgement) { OnHit?.Invoke(obj.HitObject); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a5bbf8c453..66cec7405e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -86,17 +86,12 @@ namespace osu.Game.Screens.Play var scoreOverlay = ruleset.CreateScoreOverlay(); var hitRenderer = ruleset.CreateHitRendererWith(beatmap.HitObjects); - var hitJudgement = ruleset.CreateHitJudgement(); - hitRenderer.OnHit += delegate (HitObject h) { scoreOverlay.OnHit(h); }; hitRenderer.OnMiss += delegate (HitObject h) { scoreOverlay.OnMiss(h); }; if (Autoplay) hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Hit)); - //bind DrawableHitObjects to HitJudgement - hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.CheckJudgement = hitJudgement.CheckJudgement)); - Children = new Drawable[] { new PlayerInputManager(game.Host) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9c2bbf086a..00c46a7ce3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -64,7 +64,6 @@ -