1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-21 07:33:15 +08:00

Merge pull request #4486 from smoogipoo/catch-hr-fixes

Fix catch HR inaccuracies
This commit is contained in:
Dean Herbert 2019-03-19 15:47:30 +09:00 committed by GitHub
commit 1b192d722b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -15,41 +15,66 @@ namespace osu.Game.Rulesets.Catch.Mods
public override double ScoreMultiplier => 1.12; public override double ScoreMultiplier => 1.12;
public override bool Ranked => true; public override bool Ranked => true;
private float lastStartX; private float? lastPosition;
private int lastStartTime; private double lastStartTime;
public void ApplyToHitObject(HitObject hitObject) public void ApplyToHitObject(HitObject hitObject)
{ {
if (!(hitObject is Fruit))
return;
var catchObject = (CatchHitObject)hitObject; var catchObject = (CatchHitObject)hitObject;
float position = catchObject.X; float position = catchObject.X;
int startTime = (int)hitObject.StartTime; double startTime = hitObject.StartTime;
if (lastStartX == 0) if (lastPosition == null)
{ {
lastStartX = position; lastPosition = position;
lastStartTime = startTime; lastStartTime = startTime;
return; return;
} }
float diff = lastStartX - position; float positionDiff = position - lastPosition.Value;
int timeDiff = startTime - lastStartTime; double timeDiff = startTime - lastStartTime;
if (timeDiff > 1000) if (timeDiff > 1000)
{ {
lastStartX = position; lastPosition = position;
lastStartTime = startTime; lastStartTime = startTime;
return; return;
} }
if (diff == 0) if (positionDiff == 0)
{
applyRandomOffset(ref position, timeDiff / 4d);
catchObject.X = position;
return;
}
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
applyOffset(ref position, positionDiff);
catchObject.X = position;
lastPosition = position;
lastStartTime = startTime;
}
/// <summary>
/// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield.
/// </summary>
/// <param name="position">The position which the offset should be applied to.</param>
/// <param name="maxOffset">The maximum offset, cannot exceed 20px.</param>
private void applyRandomOffset(ref float position, double maxOffset)
{ {
bool right = RNG.NextBool(); bool right = RNG.NextBool();
float rand = Math.Min(20, (float)RNG.NextDouble(0, maxOffset)) / CatchPlayfield.BASE_WIDTH;
float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4d)) / CatchPlayfield.BASE_WIDTH;
if (right) if (right)
{ {
// Clamp to the right bound
if (position + rand <= 1) if (position + rand <= 1)
position += rand; position += rand;
else else
@ -57,35 +82,33 @@ namespace osu.Game.Rulesets.Catch.Mods
} }
else else
{ {
// Clamp to the left bound
if (position - rand >= 0) if (position - rand >= 0)
position -= rand; position -= rand;
else else
position += rand; position += rand;
} }
catchObject.X = position;
return;
} }
if (Math.Abs(diff) < timeDiff / 3d) /// <summary>
/// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield.
/// </summary>
/// <param name="position">The position which the offset should be applied to.</param>
/// <param name="amount">The amount to offset by.</param>
private void applyOffset(ref float position, float amount)
{ {
if (diff > 0) if (amount > 0)
{ {
if (position - diff > 0) // Clamp to the right bound
position -= diff; if (position + amount < 1)
position += amount;
} }
else else
{ {
if (position - diff < 1) // Clamp to the left bound
position -= diff; if (position + amount > 0)
position += amount;
} }
} }
catchObject.X = position;
lastStartX = position;
lastStartTime = startTime;
}
} }
} }