diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index d253b9893f..3f57dd860a 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -150,6 +150,7 @@ namespace osu.Game.Rulesets.Catch new CatchModFloatingFruits(), new CatchModMuted(), new CatchModNoScope(), + new CatchModHoldToWalk(), }; case ModType.System: diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHoldToWalk.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHoldToWalk.cs new file mode 100644 index 0000000000..b2f80bf0ea --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHoldToWalk.cs @@ -0,0 +1,80 @@ +// 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.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; +using osu.Game.Screens.Play; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public partial class CatchModHoldToWalk : Mod, IApplicableToDrawableRuleset, IApplicableToPlayer + { + public override string Name => "Hold to Walk"; + public override string Acronym => "HW"; + public override LocalisableString Description => "Hold the Dash key to walk!"; + public override double ScoreMultiplier => 1; + public override IconUsage? Icon => FontAwesome.Solid.Running; + public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax) }; + + private DrawableCatchRuleset drawableRuleset = null!; + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + this.drawableRuleset = (DrawableCatchRuleset)drawableRuleset; + } + + public void ApplyToPlayer(Player player) + { + if (!drawableRuleset.HasReplayLoaded.Value) + { + var catchPlayfield = (CatchPlayfield)drawableRuleset.Playfield; + catchPlayfield.Catcher.Dashing = true; + catchPlayfield.CatcherArea.Add(new InvertDashInputHelper(catchPlayfield.CatcherArea)); + } + } + + private partial class InvertDashInputHelper : Drawable, IKeyBindingHandler + { + private readonly CatcherArea catcherArea; + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + + public InvertDashInputHelper(CatcherArea catcherArea) + { + this.catcherArea = catcherArea; + + RelativeSizeAxes = Axes.Both; + } + + public bool OnPressed(KeyBindingPressEvent e) + { + switch (e.Action) + { + case CatchAction.MoveLeft or CatchAction.MoveRight: + break; + + case CatchAction.Dash: + catcherArea.Catcher.Dashing = false; + return true; + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + if (e.Action == CatchAction.Dash) + catcherArea.Catcher.Dashing = true; + } + } + } +}