Skip to content

Commit

Permalink
Merge pull request #18596 from hlysine/fix-random-mod-slider
Browse files Browse the repository at this point in the history
Fix random mod generating off-screen sliders
  • Loading branch information
peppy authored Jul 8, 2022
2 parents 113fdf5 + de224e7 commit 8071335
Showing 1 changed file with 35 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,27 @@ private static Vector2 clampSliderToPlayfield(WorkingObject workingObject)
var slider = (Slider)workingObject.HitObject;
var possibleMovementBounds = calculatePossibleMovementBounds(slider);

// The slider rotation applied in computeModifiedPosition might make it impossible to fit the slider into the playfield
// For example, a long horizontal slider will be off-screen when rotated by 90 degrees
// In this case, limit the rotation to either 0 or 180 degrees
if (possibleMovementBounds.Width < 0 || possibleMovementBounds.Height < 0)
{
float currentRotation = getSliderRotation(slider);
float diff1 = getAngleDifference(workingObject.RotationOriginal, currentRotation);
float diff2 = getAngleDifference(workingObject.RotationOriginal + MathF.PI, currentRotation);

if (diff1 < diff2)
{
RotateSlider(slider, workingObject.RotationOriginal - getSliderRotation(slider));
}
else
{
RotateSlider(slider, workingObject.RotationOriginal + MathF.PI - getSliderRotation(slider));
}

possibleMovementBounds = calculatePossibleMovementBounds(slider);
}

var previousPosition = workingObject.PositionModified;

// Clamp slider position to the placement area
Expand Down Expand Up @@ -353,6 +374,18 @@ private static float getSliderRotation(Slider slider)
return MathF.Atan2(endPositionVector.Y, endPositionVector.X);
}

/// <summary>
/// Get the absolute difference between 2 angles measured in Radians.
/// </summary>
/// <param name="angle1">The first angle</param>
/// <param name="angle2">The second angle</param>
/// <returns>The absolute difference with interval <c>[0, MathF.PI)</c></returns>
private static float getAngleDifference(float angle1, float angle2)
{
float diff = MathF.Abs(angle1 - angle2) % (MathF.PI * 2);
return MathF.Min(diff, MathF.PI * 2 - diff);
}

public class ObjectPositionInfo
{
/// <summary>
Expand Down Expand Up @@ -395,6 +428,7 @@ public ObjectPositionInfo(OsuHitObject hitObject)

private class WorkingObject
{
public float RotationOriginal { get; }
public Vector2 PositionOriginal { get; }
public Vector2 PositionModified { get; set; }
public Vector2 EndPositionModified { get; set; }
Expand All @@ -405,6 +439,7 @@ private class WorkingObject
public WorkingObject(ObjectPositionInfo positionInfo)
{
PositionInfo = positionInfo;
RotationOriginal = HitObject is Slider slider ? getSliderRotation(slider) : 0;
PositionModified = PositionOriginal = HitObject.Position;
EndPositionModified = HitObject.EndPosition;
}
Expand Down

0 comments on commit 8071335

Please sign in to comment.