mirror of https://github.com/ppy/osu
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 @@ public CatcherAnimationState CurrentState
|
||||||
|
|
||||||
private Color4 hyperDashColour = DEFAULT_HYPER_DASH_COLOUR;
|
private Color4 hyperDashColour = DEFAULT_HYPER_DASH_COLOUR;
|
||||||
|
|
||||||
|
private double? lastHyperDashStartTime;
|
||||||
private double hyperDashModifier = 1;
|
private double hyperDashModifier = 1;
|
||||||
private int hyperDashDirection;
|
private int hyperDashDirection;
|
||||||
private float hyperDashTargetPosition;
|
private float hyperDashTargetPosition;
|
||||||
|
@ -233,16 +234,23 @@ public void OnNewResult(DrawableCatchHitObject drawableObject, JudgementResult r
|
||||||
// droplet doesn't affect the catcher state
|
// droplet doesn't affect the catcher state
|
||||||
if (hitObject is TinyDroplet) return;
|
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;
|
if (result.IsHit && hitObject.HyperDashTarget is CatchHitObject target)
|
||||||
double positionDifference = target.EffectiveX - X;
|
{
|
||||||
double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
|
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)
|
if (result.IsHit)
|
||||||
CurrentState = hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle;
|
CurrentState = hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle;
|
||||||
|
@ -292,6 +300,8 @@ public void SetHyperDashState(double modifier = 1, float targetPosition = -1)
|
||||||
|
|
||||||
if (wasHyperDashing)
|
if (wasHyperDashing)
|
||||||
runHyperDashStateTransition(false);
|
runHyperDashStateTransition(false);
|
||||||
|
|
||||||
|
lastHyperDashStartTime = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -301,6 +311,8 @@ public void SetHyperDashState(double modifier = 1, float targetPosition = -1)
|
||||||
|
|
||||||
if (!wasHyperDashing)
|
if (!wasHyperDashing)
|
||||||
runHyperDashStateTransition(true);
|
runHyperDashStateTransition(true);
|
||||||
|
|
||||||
|
lastHyperDashStartTime = Time.Current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue