From 9ea6912520954aa28e6a5b1eb23d16da90716f95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 16:58:56 +0900 Subject: [PATCH 1/2] Improve overall readability of OsuModeRelax --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 45 +++++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 649b01c132..7ebb6fd76d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -19,33 +19,46 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things."; public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray(); + /// + /// How early before a hitobject's start time to trigger a hit. + /// + private const float relax_leniency = 3; + public void Update(Playfield playfield) { bool requiresHold = false; bool requiresHit = false; - const float relax_leniency = 3; + double time = playfield.Clock.CurrentTime; - foreach (var drawable in playfield.HitObjectContainer.AliveObjects) + foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType()) { - if (!(drawable is DrawableOsuHitObject osuHit)) + // we are not yet close enough to the object. + if (time < h.HitObject.StartTime - relax_leniency) + break; + + // already hit or beyond the hittable end time. + if (h.IsHit || (h.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime)) continue; - double time = osuHit.Clock.CurrentTime; - double relativetime = time - osuHit.HitObject.StartTime; - - if (time < osuHit.HitObject.StartTime - relax_leniency) continue; - - if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit) - continue; - - if (osuHit is DrawableHitCircle && osuHit.IsHovered) + switch (h) { - Debug.Assert(osuHit.HitObject.HitWindows != null); - requiresHit |= osuHit.HitObject.HitWindows.CanBeHit(relativetime); - } + case DrawableHitCircle _: + if (!h.IsHovered) + break; - requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner; + Debug.Assert(h.HitObject.HitWindows != null); + requiresHit |= h.HitObject.HitWindows.CanBeHit(time - h.HitObject.StartTime); + break; + + case DrawableSlider slider: + requiresHold |= slider.Ball.IsHovered || h.IsHovered; + break; + + case DrawableSpinner _: + requiresHold = true; + break; + } } if (requiresHit) From cd2d1b06697d5b49fda11240425b8982d2af66b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 17:00:55 +0900 Subject: [PATCH 2/2] Fix 2B maps not playing correctly with relax mod enabled --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 7ebb6fd76d..d971e777ec 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -43,15 +43,15 @@ namespace osu.Game.Rulesets.Osu.Mods switch (h) { - case DrawableHitCircle _: - if (!h.IsHovered) - break; - - Debug.Assert(h.HitObject.HitWindows != null); - requiresHit |= h.HitObject.HitWindows.CanBeHit(time - h.HitObject.StartTime); + case DrawableHitCircle circle: + handleHitCircle(circle); break; case DrawableSlider slider: + // Handles cases like "2B" beatmaps, where sliders may be overlapping and simply holding is not enough. + if (!slider.HeadCircle.IsHit) + handleHitCircle(slider.HeadCircle); + requiresHold |= slider.Ball.IsHovered || h.IsHovered; break; @@ -68,6 +68,15 @@ namespace osu.Game.Rulesets.Osu.Mods } addAction(requiresHold); + + void handleHitCircle(DrawableHitCircle circle) + { + if (!circle.IsHovered) + return; + + Debug.Assert(circle.HitObject.HitWindows != null); + requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime); + } } private bool wasHit;