2021-02-05 13:31:22 +08:00
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
|
2022-06-17 15:37:17 +08:00
|
|
|
#nullable disable
|
|
|
|
|
2023-07-18 11:31:21 +08:00
|
|
|
using System;
|
2023-07-20 02:28:04 +08:00
|
|
|
using System.Linq;
|
2021-02-05 13:31:22 +08:00
|
|
|
using osu.Game.Rulesets.Objects;
|
|
|
|
using osu.Game.Rulesets.Objects.Drawables;
|
|
|
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
2021-02-08 19:12:33 +08:00
|
|
|
using osu.Game.Rulesets.UI;
|
2021-02-05 13:31:22 +08:00
|
|
|
|
|
|
|
namespace osu.Game.Rulesets.Osu.UI
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Ensures that <see cref="HitObject"/>s are hit in order of appearance. The classic note lock.
|
|
|
|
/// <remarks>
|
|
|
|
/// Hits will be blocked until the previous <see cref="HitObject"/>s have been judged.
|
|
|
|
/// </remarks>
|
|
|
|
/// </summary>
|
2023-07-20 02:44:28 +08:00
|
|
|
public class LegacyHitPolicy : IHitPolicy
|
2021-02-05 13:31:22 +08:00
|
|
|
{
|
2021-02-08 19:12:33 +08:00
|
|
|
public IHitObjectContainer HitObjectContainer { get; set; }
|
2021-02-05 13:31:22 +08:00
|
|
|
|
|
|
|
public void HandleHit(DrawableHitObject hitObject)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-07-18 11:31:21 +08:00
|
|
|
public ClickAction CheckHittable(DrawableHitObject hitObject, double time)
|
2021-02-05 13:31:22 +08:00
|
|
|
{
|
2023-07-20 02:28:04 +08:00
|
|
|
var aliveObjects = HitObjectContainer.AliveObjects.ToList();
|
|
|
|
int index = aliveObjects.IndexOf(hitObject);
|
2023-07-18 11:31:21 +08:00
|
|
|
|
|
|
|
if (index > 0)
|
2021-02-05 13:31:22 +08:00
|
|
|
{
|
2023-07-20 02:28:04 +08:00
|
|
|
var previousHitObject = (DrawableOsuHitObject)aliveObjects[index - 1];
|
2023-07-18 11:31:21 +08:00
|
|
|
if (previousHitObject.HitObject.StackHeight > 0 && !previousHitObject.AllJudged)
|
|
|
|
return ClickAction.Ignore;
|
|
|
|
}
|
2021-02-05 13:31:22 +08:00
|
|
|
|
2023-07-20 02:28:04 +08:00
|
|
|
foreach (DrawableHitObject testObject in aliveObjects)
|
2023-07-18 11:31:21 +08:00
|
|
|
{
|
|
|
|
if (testObject.AllJudged)
|
|
|
|
continue;
|
2021-02-05 13:31:22 +08:00
|
|
|
|
2023-07-18 11:31:21 +08:00
|
|
|
// if we found the object being checked, we can move on to the final timing test.
|
|
|
|
if (testObject == hitObject)
|
|
|
|
break;
|
2021-02-05 13:31:22 +08:00
|
|
|
|
2023-07-18 11:31:21 +08:00
|
|
|
// for all other objects, we check for validity and block the hit if any are still valid.
|
|
|
|
// 3ms of extra leniency to account for slightly unsnapped objects.
|
|
|
|
if (testObject.HitObject.GetEndTime() + 3 < hitObject.HitObject.StartTime)
|
|
|
|
return ClickAction.Shake;
|
|
|
|
}
|
2021-02-05 13:31:22 +08:00
|
|
|
|
2023-07-18 11:31:21 +08:00
|
|
|
// stable has `const HitObjectManager.HITTABLE_RANGE = 400;`, which is only used for notelock code.
|
|
|
|
// probably not a coincidence that this is equivalent to lazer's OsuHitWindows.MISS_WINDOW.
|
2021-02-05 13:31:22 +08:00
|
|
|
|
2023-07-18 11:31:21 +08:00
|
|
|
// TODO stable compares to 200 when autopilot is enabled, instead of 400.
|
|
|
|
return Math.Abs(hitObject.HitObject.StartTime - time) < 400 ? ClickAction.Hit : ClickAction.Shake;
|
2021-02-05 13:31:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|