mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Prioritise hyperfruit over non-hyperfruit if simultaneous
In case of simultaneous hyperfruit and non-hyperfruit - which happen to occur on some aspire maps - the desired behaviour is to hyperdash. This did not previously occur, due to annoying details in how `HitObjectContainer` is structured. `HitObjectContainer`'s drawable comparer determines the order of updating the objects. One could say that forcing the hyperfruit to be updated last, after normal fruit, could help; unfortunately this is complicated by the existence of juice streams and the fact that while a juice stream can be terminated by a normal fruit that is coincidental with a hyperfruit, the two are not comparable directly using the comparer in any feasible way. Therefore, apply a `Catcher`-level workaround that intends to handle this locally; in short, if a hyperdash was toggled in a given frame, it cannot be toggled off again in the same frame. This yields the desired behaviour.
This commit is contained in:
parent
bb198e0c5a
commit
fcb6f40666
@ -126,6 +126,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
private Color4 hyperDashColour = DEFAULT_HYPER_DASH_COLOUR;
|
||||
|
||||
private double? lastHyperDashStartTime;
|
||||
private double hyperDashModifier = 1;
|
||||
private int hyperDashDirection;
|
||||
private float hyperDashTargetPosition;
|
||||
@ -233,16 +234,23 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
// droplet doesn't affect the catcher state
|
||||
if (hitObject is TinyDroplet) return;
|
||||
|
||||
if (result.IsHit && hitObject.HyperDashTarget is CatchHitObject target)
|
||||
// if a hyper fruit was already handled this frame, just go where it says to go.
|
||||
// this special-cases some aspire maps that have doubled-up objects (one hyper, one not) at the same time instant.
|
||||
// handling this "properly" elsewhere is impossible as there is no feasible way to ensure
|
||||
// that the hyperfruit gets judged second (especially if it coincides with a last fruit in a juice stream).
|
||||
if (lastHyperDashStartTime != Time.Current)
|
||||
{
|
||||
double timeDifference = target.StartTime - hitObject.StartTime;
|
||||
double positionDifference = target.EffectiveX - X;
|
||||
double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
|
||||
if (result.IsHit && hitObject.HyperDashTarget is CatchHitObject target)
|
||||
{
|
||||
double timeDifference = target.StartTime - hitObject.StartTime;
|
||||
double positionDifference = target.EffectiveX - X;
|
||||
double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
|
||||
|
||||
SetHyperDashState(Math.Abs(velocity) / BASE_DASH_SPEED, target.EffectiveX);
|
||||
SetHyperDashState(Math.Abs(velocity) / BASE_DASH_SPEED, target.EffectiveX);
|
||||
}
|
||||
else
|
||||
SetHyperDashState();
|
||||
}
|
||||
else
|
||||
SetHyperDashState();
|
||||
|
||||
if (result.IsHit)
|
||||
CurrentState = hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle;
|
||||
@ -292,6 +300,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
if (wasHyperDashing)
|
||||
runHyperDashStateTransition(false);
|
||||
|
||||
lastHyperDashStartTime = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -301,6 +311,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
if (!wasHyperDashing)
|
||||
runHyperDashStateTransition(true);
|
||||
|
||||
lastHyperDashStartTime = Time.Current;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user