// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable disable using System; using System.Linq; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI { /// /// Ensures that s are hit in order of appearance. The classic note lock. /// /// Hits will be blocked until the previous s have been judged. /// /// public class LegacyHitPolicy : IHitPolicy { public IHitObjectContainer HitObjectContainer { get; set; } public void HandleHit(DrawableHitObject hitObject) { } public ClickAction CheckHittable(DrawableHitObject hitObject, double time) { var aliveObjects = HitObjectContainer.AliveObjects.ToList(); int index = aliveObjects.IndexOf(hitObject); if (index > 0) { var previousHitObject = (DrawableOsuHitObject)aliveObjects[index - 1]; if (previousHitObject.HitObject.StackHeight > 0 && !previousHitObject.AllJudged) return ClickAction.Ignore; } foreach (DrawableHitObject testObject in aliveObjects) { if (testObject.AllJudged) continue; // if we found the object being checked, we can move on to the final timing test. if (testObject == hitObject) break; // 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; } // 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. // TODO stable compares to 200 when autopilot is enabled, instead of 400. return Math.Abs(hitObject.HitObject.StartTime - time) < 400 ? ClickAction.Hit : ClickAction.Shake; } } }