diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 744b313f70..4e0c12f619 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -7,13 +7,14 @@ using osu.Framework.Input.States; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.UI; using static osu.Game.Input.Handlers.ReplayInputHandler; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByPlayfield + public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByPlayfield, IApplicableToRulesetContainer { 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(); @@ -22,8 +23,8 @@ public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByPlayfi public void Update(Playfield playfield) { - bool hitStill = false; - bool hitOnce = false; + bool requiresHold = false; + bool requiresHit = false; const float relax_leniency = 3; @@ -35,45 +36,54 @@ public void Update(Playfield playfield) double time = osuHit.Clock.CurrentTime; double relativetime = time - osuHit.HitObject.StartTime; - if (osuHit.IsAlive && time >= osuHit.HitObject.StartTime - relax_leniency) - { - if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit) - continue; + if (time < osuHit.HitObject.StartTime - relax_leniency) continue; - hitStill |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; + if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit) + continue; - hitOnce |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime); - } + requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime); + requiresHold |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; } - var osuHitSample = playfield.HitObjects.Objects.First(d => d is DrawableOsuHitObject) as DrawableOsuHitObject; - if (hitOnce) + if (requiresHit) { - hit(osuHitSample, false); - hit(osuHitSample, true); + addAction(false); + addAction(true); } - hit(osuHitSample, hitStill); + + addAction(requiresHold); } private bool wasHit; private bool wasLeft; - private void hit(DrawableOsuHitObject osuHit, bool hitting) + private OsuInputManager osuInputManager; + + private void addAction(bool hitting) { if (wasHit == hitting) return; + wasHit = hitting; var state = new ReplayState { PressedActions = new List() }; + if (hitting) { state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); wasLeft = !wasLeft; } - osuHit.OsuActionInputManager.HandleCustomInput(new InputState(), state); + + osuInputManager.HandleCustomInput(new InputState(), state); + } + + public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + // grab the input manager for future use. + osuInputManager = (OsuInputManager)rulesetContainer.KeyBindingInputManager; } } }