From 98d8b26a9c24dee403ba9d7199d0652910c72c0b Mon Sep 17 00:00:00 2001 From: Nitrous Date: Sat, 29 Jan 2022 21:49:40 +0800 Subject: [PATCH] move `ModAlternate` to `OsuModAlternate` and check if intro has ended --- osu.Game.Rulesets.Osu/Mods/OsuModAlternate.cs | 67 ++++++++++++++-- osu.Game/Rulesets/Mods/ModAlternate.cs | 76 ------------------- 2 files changed, 61 insertions(+), 82 deletions(-) delete mode 100644 osu.Game/Rulesets/Mods/ModAlternate.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAlternate.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAlternate.cs index 34802bab43..f366481c7d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAlternate.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAlternate.cs @@ -1,31 +1,63 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Play; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModAlternate : ModAlternate + public class OsuModAlternate : Mod, IApplicableToDrawableRuleset, IApplicableToPlayer, IUpdatableByPlayfield { + public override string Name => @"Alternate"; + public override string Acronym => @"AL"; + public override string Description => @"Don't use the same key twice in a row!"; + public override double ScoreMultiplier => 1.0; + public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay) }; + public override ModType Type => ModType.DifficultyIncrease; + public override IconUsage? Icon => FontAwesome.Solid.Keyboard; + + /// + /// Whether incoming input must be checked by . + /// + public bool CanIntercept => !isBreakTime.Value && introEnded; + + private bool introEnded; + private double earliestStartTime; + private IBindable isBreakTime; private const double flash_duration = 1000; private OsuAction? lastActionPressed; private DrawableRuleset ruleset; - public override void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { ruleset = drawableRuleset; - base.ApplyToDrawableRuleset(drawableRuleset); + drawableRuleset.KeyBindingInputManager.Add(new InputInterceptor(this)); + + var firstHitObject = ruleset.Objects.FirstOrDefault(); + earliestStartTime = (firstHitObject?.StartTime ?? 0) - (firstHitObject?.HitWindows.WindowFor(HitResult.Meh) ?? 0); } - protected override void Reset() + public void ApplyToPlayer(Player player) { - lastActionPressed = null; + isBreakTime = player.IsBreakTime.GetBoundCopy(); + isBreakTime.ValueChanged += e => + { + if (e.NewValue) + lastActionPressed = null; + }; } - protected override bool OnPressed(OsuAction key) + private bool onPressed(OsuAction key) { if (lastActionPressed == key) { @@ -37,5 +69,28 @@ namespace osu.Game.Rulesets.Osu.Mods return false; } + + public void Update(Playfield playfield) + { + if (!introEnded) + introEnded = playfield.Clock.CurrentTime > earliestStartTime; + } + + private class InputInterceptor : Component, IKeyBindingHandler + { + private readonly OsuModAlternate mod; + + public InputInterceptor(OsuModAlternate mod) + { + this.mod = mod; + } + + public bool OnPressed(KeyBindingPressEvent e) + => mod.CanIntercept && mod.onPressed(e.Action); + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + } } } diff --git a/osu.Game/Rulesets/Mods/ModAlternate.cs b/osu.Game/Rulesets/Mods/ModAlternate.cs deleted file mode 100644 index 17d8b92469..0000000000 --- a/osu.Game/Rulesets/Mods/ModAlternate.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Bindings; -using osu.Framework.Input.Events; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; - -namespace osu.Game.Rulesets.Mods -{ - public abstract class ModAlternate : Mod - { - public override string Name => @"Alternate"; - public override string Acronym => @"AL"; - public override string Description => @"Don't use the same key twice in a row!"; - public override double ScoreMultiplier => 1.0; - public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay) }; - public override ModType Type => ModType.DifficultyIncrease; - public override IconUsage? Icon => FontAwesome.Solid.Keyboard; - } - - public abstract class ModAlternate : ModAlternate, IApplicableToDrawableRuleset, IApplicableToPlayer - where THitObject : HitObject - where TAction : struct - { - /// - /// Whether incoming input must be checked by . - /// - public bool CanIntercept => !isBreakTime.Value; - - private IBindable isBreakTime; - - public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) - { - drawableRuleset.KeyBindingInputManager.Add(new InputInterceptor(this)); - } - - public void ApplyToPlayer(Player player) - { - isBreakTime = player.IsBreakTime.GetBoundCopy(); - isBreakTime.ValueChanged += e => - { - if (e.NewValue) - Reset(); - }; - } - - protected abstract void Reset(); - - protected abstract bool OnPressed(TAction key); - - private class InputInterceptor : Component, IKeyBindingHandler - { - private readonly ModAlternate mod; - - public InputInterceptor(ModAlternate mod) - { - this.mod = mod; - } - - public bool OnPressed(KeyBindingPressEvent e) - { - return mod.CanIntercept && mod.OnPressed(e.Action); - } - - public void OnReleased(KeyBindingReleaseEvent e) - { - } - } - } -}