General improvements around usage of HitWindows for mania

This commit is contained in:
smoogipoo
2018-02-02 18:47:54 +09:00
parent 558c53a6ba
commit acf20c079c
3 changed files with 50 additions and 42 deletions

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq; using System.Linq;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -212,7 +211,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{ {
if (!userTriggered) if (!userTriggered)
{ {
if (timeOffset > HitObject.HitWindows.Bad / 2) if (!HitObject.HitWindows.CanBeHit(timeOffset))
{ {
AddJudgement(new HoldNoteTailJudgement AddJudgement(new HoldNoteTailJudgement
{ {
@ -224,14 +223,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
return; return;
} }
double offset = Math.Abs(timeOffset); var result = HitObject.HitWindows.ResultFor(timeOffset);
if (result == null)
if (offset > HitObject.HitWindows.Miss / 2)
return; return;
AddJudgement(new HoldNoteTailJudgement AddJudgement(new HoldNoteTailJudgement
{ {
Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss, Result = result.Value,
HasBroken = holdNote.hasBroken HasBroken = holdNote.hasBroken
}); });
} }

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
@ -63,17 +62,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{ {
if (!userTriggered) if (!userTriggered)
{ {
if (timeOffset > HitObject.HitWindows.Bad / 2) if (!HitObject.HitWindows.CanBeHit(timeOffset))
AddJudgement(new ManiaJudgement { Result = HitResult.Miss }); AddJudgement(new ManiaJudgement { Result = HitResult.Miss });
return; return;
} }
double offset = Math.Abs(timeOffset); var result = HitObject.HitWindows.ResultFor(timeOffset);
if (result == null)
if (offset > HitObject.HitWindows.Miss / 2)
return; return;
AddJudgement(new ManiaJudgement { Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss }); AddJudgement(new ManiaJudgement { Result = result.Value });
} }
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -144,57 +145,68 @@ namespace osu.Game.Rulesets.Objects
/// <summary> /// <summary>
/// Retrieves the hit result for a time offset. /// Retrieves the hit result for a time offset.
/// </summary> /// </summary>
/// <param name="hitOffset">The time offset.</param> /// <param name="timeOffset">The time offset. This should always be a positive value indicating the absolute time offset.</param>
/// <returns>The hit result, or null if the time offset results in a miss.</returns> /// <returns>The hit result, or null if <paramref name="timeOffset"/> doesn't result in a judgement.</returns>
public HitResult? ResultFor(double hitOffset) public HitResult? ResultFor(double timeOffset)
{ {
if (hitOffset <= Perfect / 2) timeOffset = Math.Abs(timeOffset);
if (timeOffset <= Perfect / 2)
return HitResult.Perfect; return HitResult.Perfect;
if (hitOffset <= Great / 2) if (timeOffset <= Great / 2)
return HitResult.Great; return HitResult.Great;
if (hitOffset <= Good / 2) if (timeOffset <= Good / 2)
return HitResult.Good; return HitResult.Good;
if (hitOffset <= Ok / 2) if (timeOffset <= Ok / 2)
return HitResult.Ok; return HitResult.Ok;
if (hitOffset <= Bad / 2) if (timeOffset <= Bad / 2)
return HitResult.Meh; return HitResult.Meh;
if (timeOffset <= Miss / 2)
return HitResult.Miss;
return null; return null;
} }
/// <summary> /// <summary>
/// Constructs new hit windows which have been multiplied by a value. /// Given a time offset, whether the <see cref="HitObject"/> can ever be hit in the future.
/// This happens if <paramref name="timeOffset"/> > <see cref="Bad"/>.
/// </summary> /// </summary>
/// <param name="windows">The original hit windows.</param> /// <param name="timeOffset">The time offset.</param>
/// <returns>Whether the <see cref="HitObject"/> can be hit at any point in the future from this time offset.</returns>
public bool CanBeHit(double timeOffset) => timeOffset <= Bad / 2;
/// <summary>
/// Multiplies all hit windows by a value.
/// </summary>
/// <param name="windows">The hit windows to multiply.</param>
/// <param name="value">The value to multiply each hit window by.</param> /// <param name="value">The value to multiply each hit window by.</param>
public static HitWindows operator *(HitWindows windows, double value) public static HitWindows operator *(HitWindows windows, double value)
{ {
return new HitWindows windows.Perfect *= value;
{ windows.Great *= value;
Perfect = windows.Perfect * value, windows.Good *= value;
Great = windows.Great * value, windows.Ok *= value;
Good = windows.Good * value, windows.Bad *= value;
Ok = windows.Ok * value, windows.Miss *= value;
Bad = windows.Bad * value,
Miss = windows.Miss * value return windows;
};
} }
/// <summary> /// <summary>
/// Constructs new hit windows which have been divided by a value. /// Divides all hit windows by a value.
/// </summary> /// </summary>
/// <param name="windows">The original hit windows.</param> /// <param name="windows">The hit windows to divide.</param>
/// <param name="value">The value to divide each hit window by.</param> /// <param name="value">The value to divide each hit window by.</param>
public static HitWindows operator /(HitWindows windows, double value) public static HitWindows operator /(HitWindows windows, double value)
{ {
return new HitWindows windows.Perfect /= value;
{ windows.Great /= value;
Perfect = windows.Perfect / value, windows.Good /= value;
Great = windows.Great / value, windows.Ok /= value;
Good = windows.Good / value, windows.Bad /= value;
Ok = windows.Ok / value, windows.Miss /= value;
Bad = windows.Bad / value,
Miss = windows.Miss / value return windows;
};
} }
} }
} }