mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 20:22:55 +08:00
review modifications: maniamodmirror inheritance, reflection utilities, vertical flip option
This commit is contained in:
parent
2e1cd4a389
commit
49160e4482
@ -10,13 +10,9 @@ using osu.Game.Rulesets.Mania.Beatmaps;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
public class ManiaModMirror : Mod, IApplicableToBeatmap
|
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
||||||
{
|
{
|
||||||
public override string Name => "Mirror";
|
|
||||||
public override string Acronym => "MR";
|
|
||||||
public override ModType Type => ModType.Conversion;
|
|
||||||
public override string Description => "Notes are flipped horizontally.";
|
public override string Description => "Notes are flipped horizontally.";
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
|
|
||||||
public void ApplyToBeatmap(IBeatmap beatmap)
|
public void ApplyToBeatmap(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Rulesets.Osu.Utils;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
@ -19,19 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
var osuObject = (OsuHitObject)hitObject;
|
var osuObject = (OsuHitObject)hitObject;
|
||||||
|
|
||||||
osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y);
|
OsuHitObjectGenerationUtils.ReflectOsuHitObjectVertically(osuObject);
|
||||||
|
|
||||||
if (!(hitObject is Slider slider))
|
|
||||||
return;
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position.Value, p.Type.Value)).ToArray();
|
|
||||||
foreach (var point in controlPoints)
|
|
||||||
point.Position.Value = new Vector2(point.Position.Value.X, -point.Position.Value.Y);
|
|
||||||
|
|
||||||
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,34 +2,36 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Rulesets.Osu.Utils;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModMirror : ModMirror, IApplicableToHitObject
|
public class OsuModMirror : ModMirror, IApplicableToHitObject
|
||||||
{
|
{
|
||||||
|
public override string Description => "Reflect the playfield.";
|
||||||
|
|
||||||
|
[SettingSource("Reflect Horizontally", "Reflect the playfield horizontally.")]
|
||||||
|
public Bindable<bool> ReflectY { get; } = new BindableBool(true);
|
||||||
|
[SettingSource("Reflect Vertically", "Reflect the playfield vertically.")]
|
||||||
|
public Bindable<bool> ReflectX { get; } = new BindableBool(false);
|
||||||
|
|
||||||
public void ApplyToHitObject(HitObject hitObject)
|
public void ApplyToHitObject(HitObject hitObject)
|
||||||
{
|
{
|
||||||
|
if (!(ReflectY.Value || ReflectX.Value))
|
||||||
|
return; // TODO deselect the mod if possible so replays and submissions don't have purposeless mods attached.
|
||||||
var osuObject = (OsuHitObject)hitObject;
|
var osuObject = (OsuHitObject)hitObject;
|
||||||
|
if (ReflectY.Value)
|
||||||
osuObject.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - osuObject.X, osuObject.Position.Y);
|
OsuHitObjectGenerationUtils.ReflectOsuHitObjectHorizontally(osuObject);
|
||||||
|
if (ReflectX.Value)
|
||||||
if (!(hitObject is Slider slider))
|
OsuHitObjectGenerationUtils.ReflectOsuHitObjectVertically(osuObject);
|
||||||
return;
|
|
||||||
|
|
||||||
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.Value, p.Type.Value)).ToArray();
|
|
||||||
foreach (var point in controlPoints)
|
|
||||||
point.Position.Value = new Vector2(-point.Position.Value.X, point.Position.Value.Y);
|
|
||||||
|
|
||||||
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Utils
|
namespace osu.Game.Rulesets.Osu.Utils
|
||||||
@ -100,5 +104,53 @@ namespace osu.Game.Rulesets.Osu.Utils
|
|||||||
initial.Length * MathF.Sin(finalAngleRad)
|
initial.Length * MathF.Sin(finalAngleRad)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reflects an OsuHitObject's position horizontally (over the 'y axis').
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="osuObject">The OsuHitObject to be reflected.</param>
|
||||||
|
/// <returns>The reflected OsuHitObject.</returns>
|
||||||
|
public static OsuHitObject ReflectOsuHitObjectHorizontally(OsuHitObject osuObject)
|
||||||
|
{
|
||||||
|
osuObject.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - osuObject.X, osuObject.Position.Y);
|
||||||
|
|
||||||
|
if (!(osuObject is Slider slider))
|
||||||
|
return osuObject;
|
||||||
|
|
||||||
|
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.Value, p.Type.Value)).ToArray();
|
||||||
|
foreach (var point in controlPoints)
|
||||||
|
point.Position.Value = new Vector2(-point.Position.Value.X, point.Position.Value.Y);
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
|
||||||
|
|
||||||
|
return osuObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reflects an OsuHitObject's position vertically (over the 'x axis').
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="osuObject">The OsuHitObject to be reflected.</param>
|
||||||
|
/// <returns>The reflected OsuHitObject.</returns>
|
||||||
|
public static OsuHitObject ReflectOsuHitObjectVertically(OsuHitObject osuObject)
|
||||||
|
{
|
||||||
|
osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y);
|
||||||
|
|
||||||
|
if (!(osuObject is Slider slider))
|
||||||
|
return osuObject;
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position.Value, p.Type.Value)).ToArray();
|
||||||
|
foreach (var point in controlPoints)
|
||||||
|
point.Position.Value = new Vector2(point.Position.Value.X, -point.Position.Value.Y);
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
|
||||||
|
|
||||||
|
return osuObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "Mirror";
|
public override string Name => "Mirror";
|
||||||
public override string Acronym => "MR";
|
public override string Acronym => "MR";
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override string Description => "Flips the beatmap horizontally.";
|
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user