1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +08:00

Merge pull request #21544 from Pasi4K5/random-mod-slider-flip

Allow random mod to flip sliders
This commit is contained in:
Dean Herbert 2022-12-07 15:41:29 +09:00 committed by GitHub
commit 8a2c784c11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 22 deletions

View File

@ -65,6 +65,11 @@ namespace osu.Game.Rulesets.Osu.Mods
flowDirection = !flowDirection;
}
if (positionInfos[i].HitObject is Slider slider && random.NextDouble() < 0.5)
{
OsuHitObjectGenerationUtils.FlipSliderHorizontally(slider);
}
if (i == 0)
{
positionInfos[i].DistanceFromPrevious = (float)(random.NextDouble() * OsuPlayfield.BASE_SIZE.Y / 2);

View File

@ -116,18 +116,10 @@ namespace osu.Game.Rulesets.Osu.Utils
{
osuObject.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - osuObject.X, osuObject.Position.Y);
if (!(osuObject is Slider slider))
if (osuObject is not Slider slider)
return;
// No need to update the head and tail circles, since slider handles that when the new slider path is set
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - h.Position.X, h.Position.Y));
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(h => h.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - h.Position.X, h.Position.Y));
var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position, p.Type)).ToArray();
foreach (var point in controlPoints)
point.Position = new Vector2(-point.Position.X, point.Position.Y);
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
FlipSliderHorizontally(slider);
}
/// <summary>
@ -138,18 +130,13 @@ namespace osu.Game.Rulesets.Osu.Utils
{
osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y);
if (!(osuObject is Slider slider))
if (osuObject is not Slider slider)
return;
// No need to update the head and tail circles, since slider handles that when the new slider path is set
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(nested.X, slider.Y - (nested.Y - slider.Y));
static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(point.Position.X, -point.Position.Y);
var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position, p.Type)).ToArray();
foreach (var point in controlPoints)
point.Position = new Vector2(point.Position.X, -point.Position.Y);
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
modifySlider(slider, flipNestedObject, flipControlPoint);
}
/// <summary>
@ -160,14 +147,31 @@ namespace osu.Game.Rulesets.Osu.Utils
public static void RotateSlider(Slider slider, float rotation)
{
void rotateNestedObject(OsuHitObject nested) => nested.Position = rotateVector(nested.Position - slider.Position, rotation) + slider.Position;
void rotateControlPoint(PathControlPoint point) => point.Position = rotateVector(point.Position, rotation);
modifySlider(slider, rotateNestedObject, rotateControlPoint);
}
/// <summary>
/// Flips the slider about its start position horizontally.
/// </summary>
public static void FlipSliderHorizontally(Slider slider)
{
void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.X - (nested.X - slider.X), nested.Y);
static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y);
modifySlider(slider, flipNestedObject, flipControlPoint);
}
private static void modifySlider(Slider slider, Action<OsuHitObject> modifyNestedObject, Action<PathControlPoint> modifyControlPoint)
{
// No need to update the head and tail circles, since slider handles that when the new slider path is set
slider.NestedHitObjects.OfType<SliderTick>().ForEach(rotateNestedObject);
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(rotateNestedObject);
slider.NestedHitObjects.OfType<SliderTick>().ForEach(modifyNestedObject);
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(modifyNestedObject);
var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position, p.Type)).ToArray();
foreach (var point in controlPoints)
point.Position = rotateVector(point.Position, rotation);
modifyControlPoint(point);
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
}