diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
index 181536a91e..56826d228c 100644
--- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
@@ -248,37 +248,46 @@ namespace osu.Game.Rulesets.Catch.UI
if (validCatch && fruit.HyperDash)
{
- HyperDashModifier = Math.Abs(fruit.HyperDashTarget.X - fruit.X) / Math.Abs(fruit.HyperDashTarget.StartTime - fruit.StartTime) / BASE_SPEED;
- HyperDashDirection = fruit.HyperDashTarget.X - fruit.X;
+ var target = fruit.HyperDashTarget;
+ double timeDifference = target.StartTime - fruit.StartTime;
+ double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition;
+ double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
+
+ HyperDashing = true;
+ hyperDashModifier = Math.Abs(velocity);
+ hyperDashDirection = (int)Math.Sign(velocity);
+ hyperDashTargetPosition = target.X;
}
else
- HyperDashModifier = 1;
+ {
+ HyperDashing = false;
+ }
return validCatch;
}
+ private double hyperDashModifier = 1;
+ private int hyperDashDirection = 0;
+ private float hyperDashTargetPosition;
+ private bool hyperDashing = false;
+
///
/// Whether we are hypderdashing or not.
///
- public bool HyperDashing => hyperDashModifier != 1;
-
- private double hyperDashModifier = 1;
-
- ///
- /// The direction in which hyperdash is allowed. 0 allows both directions.
- ///
- public double HyperDashDirection;
-
- ///
- /// The speed modifier resultant from hyperdash. Will trigger hyperdash when not equal to 1.
- ///
- public double HyperDashModifier
+ protected bool HyperDashing
{
- get { return hyperDashModifier; }
+ get => hyperDashing;
set
{
- if (value == hyperDashModifier) return;
- hyperDashModifier = value;
+ if (hyperDashing == value) return;
+
+ hyperDashing = value;
+
+ if (!HyperDashing)
+ {
+ hyperDashModifier = 1;
+ hyperDashDirection = 0;
+ }
const float transition_length = 180;
@@ -290,7 +299,6 @@ namespace osu.Game.Rulesets.Catch.UI
}
else
{
- HyperDashDirection = 0;
this.FadeColour(Color4.White, transition_length, Easing.OutQuint);
this.FadeTo(1, transition_length, Easing.OutQuint);
}
@@ -347,12 +355,18 @@ namespace osu.Game.Rulesets.Catch.UI
var direction = Math.Sign(currentDirection);
double dashModifier = Dashing ? 1 : 0.5;
-
- if (hyperDashModifier != 1 && (HyperDashDirection == 0 || direction == Math.Sign(HyperDashDirection)))
- dashModifier = hyperDashModifier;
+ double speed = BASE_SPEED * dashModifier * hyperDashModifier;
Scale = new Vector2(Math.Abs(Scale.X) * direction, Scale.Y);
- X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * BASE_SPEED * dashModifier, 0, 1);
+ X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1);
+
+ // Correct overshooting.
+ if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) ||
+ (hyperDashDirection < 0 && hyperDashTargetPosition > X))
+ {
+ X = hyperDashTargetPosition;
+ HyperDashing = false;
+ }
}
///