Implement partial judgements + make Result non-nullable.

This commit is contained in:
smoogipooo
2017-03-29 17:57:36 +09:00
parent e8efdcfe0f
commit 3050039972
11 changed files with 63 additions and 11 deletions

View File

@ -38,7 +38,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
Colour = AccentColour, Colour = AccentColour,
Hit = () => Hit = () =>
{ {
if (Judgement.Result.HasValue) return false; if (Judgement.Result != HitResult.None) return false;
Judgement.PositionOffset = Vector2.Zero; //todo: set to correct value Judgement.PositionOffset = Vector2.Zero; //todo: set to correct value
UpdateJudgement(true); UpdateJudgement(true);

View File

@ -47,7 +47,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key) protected override bool HandleKeyPress(Key key)
{ {
return !Judgement.Result.HasValue && UpdateJudgement(true); return Judgement.Result == HitResult.None && UpdateJudgement(true);
} }
} }
} }

View File

@ -68,7 +68,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key) protected override bool HandleKeyPress(Key key)
{ {
if (Judgement.Result.HasValue) if (Judgement.Result != HitResult.None)
return false; return false;
validKeyPressed = HitKeys.Contains(key); validKeyPressed = HitKeys.Contains(key);

View File

@ -5,6 +5,7 @@ using OpenTK.Input;
using System; using System;
using System.Linq; using System.Linq;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Game.Modes.Objects.Drawables;
namespace osu.Game.Modes.Taiko.Objects.Drawable namespace osu.Game.Modes.Taiko.Objects.Drawable
{ {
@ -27,7 +28,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override void CheckJudgement(bool userTriggered) protected override void CheckJudgement(bool userTriggered)
{ {
if (!Judgement.Result.HasValue) if (Judgement.Result == HitResult.None)
{ {
base.CheckJudgement(userTriggered); base.CheckJudgement(userTriggered);
return; return;
@ -45,7 +46,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key) protected override bool HandleKeyPress(Key key)
{ {
// Check if we've handled the first key // Check if we've handled the first key
if (!Judgement.Result.HasValue) if (Judgement.Result == HitResult.None)
{ {
// First key hasn't been handled yet, attempt to handle it // First key hasn't been handled yet, attempt to handle it
bool handled = base.HandleKeyPress(key); bool handled = base.HandleKeyPress(key);

View File

@ -64,7 +64,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key) protected override bool HandleKeyPress(Key key)
{ {
if (Judgement.Result.HasValue) if (Judgement.Result != HitResult.None)
return false; return false;
UpdateJudgement(true); UpdateJudgement(true);

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Scoring;
namespace osu.Game.Modes.Judgements
{
/// <summary>
/// Inidicates that the judgement this is attached to is a partial judgement and the scoring value may change.
/// <para>
/// This judgement will be continually processed by <see cref="DrawableHitObject{TObject, TJudgement}.CheckJudgement(bool)"/>
/// unless the result is a miss and will trigger a full re-process of the <see cref="ScoreProcessor"/> when changed.
/// </para>
/// </summary>
public interface IPartialJudgement
{
/// <summary>
/// Indicates that this partial judgement has changed and requires a full re-process of the <see cref="ScoreProcessor"/>.
/// <para>
/// This is set to false once the judgement has been re-processed.
/// </para>
/// </summary>
bool Changed { get; set; }
}
}

View File

@ -10,7 +10,7 @@ namespace osu.Game.Modes.Judgements
/// <summary> /// <summary>
/// Whether this judgement is the result of a hit or a miss. /// Whether this judgement is the result of a hit or a miss.
/// </summary> /// </summary>
public HitResult? Result; public HitResult Result;
/// <summary> /// <summary>
/// The offset at which this judgement occurred. /// The offset at which this judgement occurred.

View File

@ -93,16 +93,26 @@ namespace osu.Game.Modes.Objects.Drawables
/// <returns>Whether a hit was processed.</returns> /// <returns>Whether a hit was processed.</returns>
protected bool UpdateJudgement(bool userTriggered) protected bool UpdateJudgement(bool userTriggered)
{ {
if (Judgement.Result != null) IPartialJudgement partial = Judgement as IPartialJudgement;
// Never re-process non-partial hits, or partial judgements that were previously judged as misses
if (Judgement.Result != HitResult.None && (partial == null || Judgement.Result == HitResult.Miss))
return false; return false;
// Update the judgement state
double endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; double endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
Judgement.TimeOffset = Time.Current - endTime; Judgement.TimeOffset = Time.Current - endTime;
// Update the judgement state
bool hadResult = Judgement.Result != HitResult.None;
CheckJudgement(userTriggered); CheckJudgement(userTriggered);
if (Judgement.Result == null) // Don't process judgements with no result
if (Judgement.Result == HitResult.None)
return false;
// Don't process judgements that previously had results but the results were unchanged
if (hadResult && partial?.Changed != true)
return false; return false;
switch (Judgement.Result) switch (Judgement.Result)
@ -117,6 +127,9 @@ namespace osu.Game.Modes.Objects.Drawables
OnJudgement?.Invoke(this); OnJudgement?.Invoke(this);
if (partial != null)
partial.Changed = false;
return true; return true;
} }

View File

@ -7,8 +7,19 @@ namespace osu.Game.Modes.Objects.Drawables
{ {
public enum HitResult public enum HitResult
{ {
/// <summary>
/// Indicates that the object has not been judged yet.
/// </summary>
[Description("")]
None,
/// <summary>
/// Indicates that the object has been judged as a miss.
/// </summary>
[Description(@"Miss")] [Description(@"Miss")]
Miss, Miss,
/// <summary>
/// Indicates that the object has been judged as a hit.
/// </summary>
[Description(@"Hit")] [Description(@"Hit")]
Hit, Hit,
} }

View File

@ -149,7 +149,7 @@ namespace osu.Game.Modes.UI
public event Action<TJudgement> OnJudgement; public event Action<TJudgement> OnJudgement;
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
protected override bool AllObjectsJudged => Playfield.HitObjects.Children.All(h => h.Judgement.Result.HasValue); protected override bool AllObjectsJudged => Playfield.HitObjects.Children.All(h => h.Judgement.Result != HitResult.None);
/// <summary> /// <summary>
/// The playfield. /// The playfield.

View File

@ -97,6 +97,7 @@
<Compile Include="IO\Legacy\SerializationWriter.cs" /> <Compile Include="IO\Legacy\SerializationWriter.cs" />
<Compile Include="IPC\ScoreIPCChannel.cs" /> <Compile Include="IPC\ScoreIPCChannel.cs" />
<Compile Include="Modes\Judgements\DrawableJudgement.cs" /> <Compile Include="Modes\Judgements\DrawableJudgement.cs" />
<Compile Include="Modes\Judgements\IPartialJudgement.cs" />
<Compile Include="Modes\LegacyReplay.cs" /> <Compile Include="Modes\LegacyReplay.cs" />
<Compile Include="Modes\Mods\IApplicableMod.cs" /> <Compile Include="Modes\Mods\IApplicableMod.cs" />
<Compile Include="Modes\Mods\ModType.cs" /> <Compile Include="Modes\Mods\ModType.cs" />