From 7310c38df98396b5c51bb27febc034f26e6e8532 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Fri, 3 Aug 2018 14:03:11 +0200 Subject: [PATCH 1/9] Add relax mod --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 69 ++++++++++++++++++- .../Rulesets/Mods/IUpdatableByHitObject.cs | 12 ++++ .../Rulesets/Mods/IUpdatableByPlayfield.cs | 12 ++++ .../Objects/Drawables/DrawableHitObject.cs | 12 +++- osu.Game/Rulesets/UI/Playfield.cs | 17 ++++- 5 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs create mode 100644 osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 9f9c2a09b6..2e07117734 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -2,14 +2,81 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; +using osu.Framework.Input.States; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +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 + public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByHitObject, IUpdatableByPlayfield { 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(); + + public bool AllowFail => false; + + private bool hitStill; + private bool hitOnce; + + public void Update(DrawableHitObject o) + { + const float relax_leniency = 3; + + if (!(o is DrawableOsuHitObject d)) + return; + + double t = d.Clock.CurrentTime; + + if (t >= d.HitObject.StartTime - relax_leniency) + { + if (d.HitObject is IHasEndTime e && t > e.EndTime || d.IsHit) + return; + + hitStill |= d is DrawableSlider s && (s.Ball.IsHovered || d.IsHovered) || d is DrawableSpinner; + + hitOnce |= d is DrawableHitCircle && d.IsHovered; + } + } + + public void Update(Playfield r) + { + var d = r.HitObjects.Objects.First(h => h is DrawableOsuHitObject) as DrawableOsuHitObject; + if (hitOnce) + { + hit(d, false); + hit(d, true); + } + hit(d, hitStill); + + hitOnce = false; + hitStill = false; + } + + private bool wasHit; + private bool wasLeft; + + private void hit(DrawableOsuHitObject d, bool hitting) + { + if (wasHit == hitting) + return; + wasHit = hitting; + + var l = new ReplayState + { + PressedActions = new List() + }; + if (hitting) + { + l.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); + wasLeft = !wasLeft; + } + d.OsuActionInputManager.HandleCustomInput(new InputState(), l); + } } } diff --git a/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs b/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs new file mode 100644 index 0000000000..657145b911 --- /dev/null +++ b/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Mods +{ + public interface IUpdatableByHitObject : IApplicableMod + { + void Update(DrawableHitObject o); + } +} diff --git a/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs b/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs new file mode 100644 index 0000000000..39781a875d --- /dev/null +++ b/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Mods +{ + public interface IUpdatableByPlayfield : IApplicableMod + { + void Update(Playfield r); + } +} diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index a22aaa784f..31dd5a4a91 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -13,6 +13,8 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; using OpenTK.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Objects.Drawables { @@ -41,6 +43,8 @@ namespace osu.Game.Rulesets.Objects.Drawables public IReadOnlyList Judgements => judgements; private readonly List judgements = new List(); + private WorkingBeatmap beatmap; + /// /// Whether a visible judgement should be displayed when this representation is hit. /// @@ -80,8 +84,9 @@ namespace osu.Game.Rulesets.Objects.Drawables } [BackgroundDependencyLoader] - private void load() + private void load(IBindableBeatmap b) { + beatmap = b.Value; var samples = GetSamples().ToArray(); if (samples.Any()) @@ -132,6 +137,11 @@ namespace osu.Game.Rulesets.Objects.Drawables { base.Update(); + if(beatmap != null) + foreach (var m in beatmap.Mods.Value) + if (m is IUpdatableByHitObject u) + u.Update(this); + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; while (judgements.Count > 0) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 2f44d99e18..7116dc53a9 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -6,6 +6,8 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.UI { @@ -42,9 +44,12 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; } + private WorkingBeatmap beatmap; + [BackgroundDependencyLoader] - private void load() + private void load(IBindableBeatmap b) { + beatmap = b.Value; HitObjects = CreateHitObjectContainer(); HitObjects.RelativeSizeAxes = Axes.Both; @@ -87,5 +92,15 @@ namespace osu.Game.Rulesets.UI /// Creates the container that will be used to contain the s. /// protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer(); + + protected override void Update() + { + base.Update(); + + if (beatmap != null) + foreach (var m in beatmap.Mods.Value) + if (m is IUpdatableByPlayfield u) + u.Update(this); + } } } From 07d6a75e239ed84169b2669eab2b1aee9c40cdc5 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Sat, 4 Aug 2018 00:18:09 +0200 Subject: [PATCH 2/9] Rename variables to be human readable --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 32 +++++++++---------- .../Rulesets/Mods/IUpdatableByHitObject.cs | 2 +- .../Rulesets/Mods/IUpdatableByPlayfield.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 10 +++--- osu.Game/Rulesets/UI/Playfield.cs | 10 +++--- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 2e07117734..296a9f9631 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -24,35 +24,35 @@ namespace osu.Game.Rulesets.Osu.Mods private bool hitStill; private bool hitOnce; - public void Update(DrawableHitObject o) + public void Update(DrawableHitObject drawable) { const float relax_leniency = 3; - if (!(o is DrawableOsuHitObject d)) + if (!(drawable is DrawableOsuHitObject osuHit)) return; - double t = d.Clock.CurrentTime; + double time = osuHit.Clock.CurrentTime; - if (t >= d.HitObject.StartTime - relax_leniency) + if (time >= osuHit.HitObject.StartTime - relax_leniency) { - if (d.HitObject is IHasEndTime e && t > e.EndTime || d.IsHit) + if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit) return; - hitStill |= d is DrawableSlider s && (s.Ball.IsHovered || d.IsHovered) || d is DrawableSpinner; + hitStill |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; - hitOnce |= d is DrawableHitCircle && d.IsHovered; + hitOnce |= osuHit is DrawableHitCircle && osuHit.IsHovered; } } - public void Update(Playfield r) + public void Update(Playfield playfield) { - var d = r.HitObjects.Objects.First(h => h is DrawableOsuHitObject) as DrawableOsuHitObject; + var osuHit = playfield.HitObjects.Objects.First(d => d is DrawableOsuHitObject) as DrawableOsuHitObject; if (hitOnce) { - hit(d, false); - hit(d, true); + hit(osuHit, false); + hit(osuHit, true); } - hit(d, hitStill); + hit(osuHit, hitStill); hitOnce = false; hitStill = false; @@ -61,22 +61,22 @@ namespace osu.Game.Rulesets.Osu.Mods private bool wasHit; private bool wasLeft; - private void hit(DrawableOsuHitObject d, bool hitting) + private void hit(DrawableOsuHitObject osuHit, bool hitting) { if (wasHit == hitting) return; wasHit = hitting; - var l = new ReplayState + var state = new ReplayState { PressedActions = new List() }; if (hitting) { - l.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); + state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); wasLeft = !wasLeft; } - d.OsuActionInputManager.HandleCustomInput(new InputState(), l); + osuHit.OsuActionInputManager.HandleCustomInput(new InputState(), state); } } } diff --git a/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs b/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs index 657145b911..6dd900e9c5 100644 --- a/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs +++ b/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs @@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Mods { public interface IUpdatableByHitObject : IApplicableMod { - void Update(DrawableHitObject o); + void Update(DrawableHitObject drawable); } } diff --git a/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs b/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs index 39781a875d..be879759bd 100644 --- a/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs +++ b/osu.Game/Rulesets/Mods/IUpdatableByPlayfield.cs @@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Mods { public interface IUpdatableByPlayfield : IApplicableMod { - void Update(Playfield r); + void Update(Playfield playfield); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 31dd5a4a91..f060f7382c 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -84,9 +84,9 @@ namespace osu.Game.Rulesets.Objects.Drawables } [BackgroundDependencyLoader] - private void load(IBindableBeatmap b) + private void load(IBindableBeatmap bBeatmap) { - beatmap = b.Value; + beatmap = bBeatmap.Value; var samples = GetSamples().ToArray(); if (samples.Any()) @@ -138,9 +138,9 @@ namespace osu.Game.Rulesets.Objects.Drawables base.Update(); if(beatmap != null) - foreach (var m in beatmap.Mods.Value) - if (m is IUpdatableByHitObject u) - u.Update(this); + foreach (var mod in beatmap.Mods.Value) + if (mod is IUpdatableByHitObject updatable) + updatable.Update(this); var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 7116dc53a9..f7b3736e74 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -47,9 +47,9 @@ namespace osu.Game.Rulesets.UI private WorkingBeatmap beatmap; [BackgroundDependencyLoader] - private void load(IBindableBeatmap b) + private void load(IBindableBeatmap bBeatmap) { - beatmap = b.Value; + beatmap = bBeatmap.Value; HitObjects = CreateHitObjectContainer(); HitObjects.RelativeSizeAxes = Axes.Both; @@ -98,9 +98,9 @@ namespace osu.Game.Rulesets.UI base.Update(); if (beatmap != null) - foreach (var m in beatmap.Mods.Value) - if (m is IUpdatableByPlayfield u) - u.Update(this); + foreach (var mod in beatmap.Mods.Value) + if (mod is IUpdatableByPlayfield updatable) + updatable.Update(this); } } } From b1d1a2400bfc49c47649ea497cb0437a0467abcd Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Sun, 5 Aug 2018 09:52:19 +0200 Subject: [PATCH 3/9] Remove IUpdatableByHitObject completely --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 60 +++++++++---------- .../Rulesets/Mods/IUpdatableByHitObject.cs | 12 ---- .../Objects/Drawables/DrawableHitObject.cs | 12 +--- 3 files changed, 29 insertions(+), 55 deletions(-) delete mode 100644 osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 296a9f9631..e10ddfaec1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Input.States; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.UI; @@ -14,48 +13,45 @@ using static osu.Game.Input.Handlers.ReplayInputHandler; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByHitObject, IUpdatableByPlayfield + public class OsuModRelax : ModRelax, IApplicableFailOverride, IUpdatableByPlayfield { 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(); public bool AllowFail => false; - private bool hitStill; - private bool hitOnce; - - public void Update(DrawableHitObject drawable) - { - const float relax_leniency = 3; - - if (!(drawable is DrawableOsuHitObject osuHit)) - return; - - double time = osuHit.Clock.CurrentTime; - - if (time >= osuHit.HitObject.StartTime - relax_leniency) - { - if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit) - return; - - hitStill |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; - - hitOnce |= osuHit is DrawableHitCircle && osuHit.IsHovered; - } - } - public void Update(Playfield playfield) { - var osuHit = playfield.HitObjects.Objects.First(d => d is DrawableOsuHitObject) as DrawableOsuHitObject; + bool hitStill = false; + bool hitOnce = false; + + const float relax_leniency = 3; + + foreach (var drawable in playfield.HitObjects.Objects) + { + if (!(drawable is DrawableOsuHitObject osuHit)) + continue; + + double time = osuHit.Clock.CurrentTime; + + if (osuHit.IsAlive && time >= osuHit.HitObject.StartTime - relax_leniency) + { + if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit) + continue; + + hitStill |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; + + hitOnce |= osuHit is DrawableHitCircle && osuHit.IsHovered; + } + } + + var osuHitSample = playfield.HitObjects.Objects.First(d => d is DrawableOsuHitObject) as DrawableOsuHitObject; if (hitOnce) { - hit(osuHit, false); - hit(osuHit, true); + hit(osuHitSample, false); + hit(osuHitSample, true); } - hit(osuHit, hitStill); - - hitOnce = false; - hitStill = false; + hit(osuHitSample, hitStill); } private bool wasHit; diff --git a/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs b/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs deleted file mode 100644 index 6dd900e9c5..0000000000 --- a/osu.Game/Rulesets/Mods/IUpdatableByHitObject.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Rulesets.Objects.Drawables; - -namespace osu.Game.Rulesets.Mods -{ - public interface IUpdatableByHitObject : IApplicableMod - { - void Update(DrawableHitObject drawable); - } -} diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index f060f7382c..a22aaa784f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -13,8 +13,6 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; using OpenTK.Graphics; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Objects.Drawables { @@ -43,8 +41,6 @@ namespace osu.Game.Rulesets.Objects.Drawables public IReadOnlyList Judgements => judgements; private readonly List judgements = new List(); - private WorkingBeatmap beatmap; - /// /// Whether a visible judgement should be displayed when this representation is hit. /// @@ -84,9 +80,8 @@ namespace osu.Game.Rulesets.Objects.Drawables } [BackgroundDependencyLoader] - private void load(IBindableBeatmap bBeatmap) + private void load() { - beatmap = bBeatmap.Value; var samples = GetSamples().ToArray(); if (samples.Any()) @@ -137,11 +132,6 @@ namespace osu.Game.Rulesets.Objects.Drawables { base.Update(); - if(beatmap != null) - foreach (var mod in beatmap.Mods.Value) - if (mod is IUpdatableByHitObject updatable) - updatable.Update(this); - var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; while (judgements.Count > 0) From 924bf9174c97ec4deaae8f8d55cee174d0defbc1 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Sun, 5 Aug 2018 09:58:15 +0200 Subject: [PATCH 4/9] Fix overclick in certain situations --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index e10ddfaec1..f0e7891a96 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods continue; double time = osuHit.Clock.CurrentTime; + double relativetime = time - osuHit.HitObject.StartTime; if (osuHit.IsAlive && time >= osuHit.HitObject.StartTime - relax_leniency) { @@ -41,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Mods hitStill |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; - hitOnce |= osuHit is DrawableHitCircle && osuHit.IsHovered; + hitOnce |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime); } } From 870f6bea47cb9f563ffe8d7424c7cd864de6e0d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Aug 2018 18:18:08 +0900 Subject: [PATCH 5/9] Only process alive objects --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index f0e7891a96..744b313f70 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Mods const float relax_leniency = 3; - foreach (var drawable in playfield.HitObjects.Objects) + foreach (var drawable in playfield.HitObjects.AliveObjects) { if (!(drawable is DrawableOsuHitObject osuHit)) continue; From bc22a28fef7c1e773ba7b681559545ace37cdb7b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Aug 2018 18:18:15 +0900 Subject: [PATCH 6/9] Clean up logic and variables --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 44 ++++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-) 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 System.Linq; 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 @@ namespace osu.Game.Rulesets.Osu.Mods 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 @@ namespace osu.Game.Rulesets.Osu.Mods 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; } } } From 442f6795bc8783a158738ea2bc388f6f02f63a9f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Aug 2018 19:33:14 +0900 Subject: [PATCH 7/9] Block user input --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 1 + osu.Game.Rulesets.Osu/OsuInputManager.cs | 31 ++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 4e0c12f619..4047e057cb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -84,6 +84,7 @@ namespace osu.Game.Rulesets.Osu.Mods { // grab the input manager for future use. osuInputManager = (OsuInputManager)rulesetContainer.KeyBindingInputManager; + osuInputManager.AllowUserPresses = false; } } } diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index d9ae836e0a..78ef0ec733 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.ComponentModel; using osu.Framework.Input.Bindings; +using osu.Framework.Input.EventArgs; +using osu.Framework.Input.States; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu @@ -12,8 +14,34 @@ namespace osu.Game.Rulesets.Osu { public IEnumerable PressedActions => KeyBindingContainer.PressedActions; - public OsuInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) + public bool AllowUserPresses { + set => ((OsuKeyBindingContainer)KeyBindingContainer).AllowUserPresses = value; + } + + protected override RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) + => new OsuKeyBindingContainer(ruleset, variant, unique); + + public OsuInputManager(RulesetInfo ruleset) + : base(ruleset, 0, SimultaneousBindingMode.Unique) + { + } + + private class OsuKeyBindingContainer : RulesetKeyBindingContainer + { + public bool AllowUserPresses = true; + + public OsuKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) + : base(ruleset, variant, unique) + { + } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => AllowUserPresses && base.OnKeyDown( state,args); + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => AllowUserPresses && base.OnKeyUp( state,args); + protected override bool OnJoystickPress(InputState state, JoystickEventArgs args) => AllowUserPresses && base.OnJoystickPress( state,args); + protected override bool OnJoystickRelease(InputState state, JoystickEventArgs args) => AllowUserPresses && base.OnJoystickRelease( state,args); + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => AllowUserPresses && base.OnMouseDown( state,args); + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => AllowUserPresses && base.OnMouseUp( state,args); } } @@ -21,6 +49,7 @@ namespace osu.Game.Rulesets.Osu { [Description("Left Button")] LeftButton, + [Description("Right Button")] RightButton } From 41f8609e0fec70f285308adfad8860bfa68bca7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Aug 2018 20:13:14 +0900 Subject: [PATCH 8/9] Also handle OnScroll --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 78ef0ec733..e7bbe755a0 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -36,12 +36,13 @@ namespace osu.Game.Rulesets.Osu { } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => AllowUserPresses && base.OnKeyDown( state,args); - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => AllowUserPresses && base.OnKeyUp( state,args); - protected override bool OnJoystickPress(InputState state, JoystickEventArgs args) => AllowUserPresses && base.OnJoystickPress( state,args); - protected override bool OnJoystickRelease(InputState state, JoystickEventArgs args) => AllowUserPresses && base.OnJoystickRelease( state,args); - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => AllowUserPresses && base.OnMouseDown( state,args); - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => AllowUserPresses && base.OnMouseUp( state,args); + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => AllowUserPresses && base.OnKeyDown(state, args); + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => AllowUserPresses && base.OnKeyUp(state, args); + protected override bool OnJoystickPress(InputState state, JoystickEventArgs args) => AllowUserPresses && base.OnJoystickPress(state, args); + protected override bool OnJoystickRelease(InputState state, JoystickEventArgs args) => AllowUserPresses && base.OnJoystickRelease(state, args); + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => AllowUserPresses && base.OnMouseDown(state, args); + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => AllowUserPresses && base.OnMouseUp(state, args); + protected override bool OnScroll(InputState state) => AllowUserPresses && base.OnScroll(state); } } From fcf98390f56b0e5cca645d8f7f255d9fc1c8731b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 21 Aug 2018 12:10:00 +0900 Subject: [PATCH 9/9] Cleanup --- osu.Game/Rulesets/UI/Playfield.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 7a7ada3435..da14fb54d6 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -56,9 +56,10 @@ namespace osu.Game.Rulesets.UI private WorkingBeatmap beatmap; [BackgroundDependencyLoader] - private void load(IBindableBeatmap bBeatmap) + private void load(IBindableBeatmap beatmap) { - beatmap = bBeatmap.Value; + this.beatmap = beatmap.Value; + HitObjects = CreateHitObjectContainer(); HitObjects.RelativeSizeAxes = Axes.Both;