1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-26 16:12:54 +08:00

Merge pull request #12303 from smoogipoo/fix-last-control-point-segmenting

Make last control point not able to make an implicit segment
This commit is contained in:
Dean Herbert 2021-04-06 13:35:55 +09:00 committed by GitHub
commit 784552022f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 105 additions and 1 deletions

View File

@ -23,6 +23,7 @@ namespace osu.Game.Rulesets.Osu.Tests
[TestCase("repeat-slider")]
[TestCase("uneven-repeat-slider")]
[TestCase("old-stacking")]
[TestCase("multi-segment-slider")]
public void Test(string name) => base.Test(name);
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)

View File

@ -0,0 +1,36 @@
{
"Mappings": [{
"StartTime": 347893,
"Objects": [{
"StartTime": 347893,
"EndTime": 347893,
"X": 329,
"Y": 245,
"StackOffset": {
"X": 0,
"Y": 0
}
},
{
"StartTime": 348193,
"EndTime": 348193,
"X": 183.0447,
"Y": 245.24292,
"StackOffset": {
"X": 0,
"Y": 0
}
},
{
"StartTime": 348457,
"EndTime": 348457,
"X": 329,
"Y": 245,
"StackOffset": {
"X": 0,
"Y": 0
}
}
]
}]
}

View File

@ -0,0 +1,17 @@
osu file format v14
[General]
Mode: 0
[Difficulty]
CircleSize:4
OverallDifficulty:7
ApproachRate:8
SliderMultiplier:2
SliderTickRate:1
[TimingPoints]
337093,300,4,2,1,40,1,0
[HitObjects]
329,245,347893,2,0,B|319:311|199:343|183:245|183:245,2,200,8|8|8,0:0|0:0|0:0,0:0:0:0:

View File

@ -707,6 +707,39 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.That(third.ControlPoints[5].Type.Value, Is.EqualTo(null));
Assert.That(third.ControlPoints[6].Position.Value, Is.EqualTo(new Vector2(480, 0)));
Assert.That(third.ControlPoints[6].Type.Value, Is.EqualTo(null));
// Last control point duplicated
var fourth = ((IHasPath)decoded.HitObjects[3]).Path;
Assert.That(fourth.ControlPoints[0].Position.Value, Is.EqualTo(Vector2.Zero));
Assert.That(fourth.ControlPoints[0].Type.Value, Is.EqualTo(PathType.Bezier));
Assert.That(fourth.ControlPoints[1].Position.Value, Is.EqualTo(new Vector2(1, 1)));
Assert.That(fourth.ControlPoints[1].Type.Value, Is.EqualTo(null));
Assert.That(fourth.ControlPoints[2].Position.Value, Is.EqualTo(new Vector2(2, 2)));
Assert.That(fourth.ControlPoints[2].Type.Value, Is.EqualTo(null));
Assert.That(fourth.ControlPoints[3].Position.Value, Is.EqualTo(new Vector2(3, 3)));
Assert.That(fourth.ControlPoints[3].Type.Value, Is.EqualTo(null));
Assert.That(fourth.ControlPoints[4].Position.Value, Is.EqualTo(new Vector2(3, 3)));
Assert.That(fourth.ControlPoints[4].Type.Value, Is.EqualTo(null));
// Last control point in segment duplicated
var fifth = ((IHasPath)decoded.HitObjects[4]).Path;
Assert.That(fifth.ControlPoints[0].Position.Value, Is.EqualTo(Vector2.Zero));
Assert.That(fifth.ControlPoints[0].Type.Value, Is.EqualTo(PathType.Bezier));
Assert.That(fifth.ControlPoints[1].Position.Value, Is.EqualTo(new Vector2(1, 1)));
Assert.That(fifth.ControlPoints[1].Type.Value, Is.EqualTo(null));
Assert.That(fifth.ControlPoints[2].Position.Value, Is.EqualTo(new Vector2(2, 2)));
Assert.That(fifth.ControlPoints[2].Type.Value, Is.EqualTo(null));
Assert.That(fifth.ControlPoints[3].Position.Value, Is.EqualTo(new Vector2(3, 3)));
Assert.That(fifth.ControlPoints[3].Type.Value, Is.EqualTo(null));
Assert.That(fifth.ControlPoints[4].Position.Value, Is.EqualTo(new Vector2(3, 3)));
Assert.That(fifth.ControlPoints[4].Type.Value, Is.EqualTo(null));
Assert.That(fifth.ControlPoints[5].Position.Value, Is.EqualTo(new Vector2(4, 4)));
Assert.That(fifth.ControlPoints[5].Type.Value, Is.EqualTo(PathType.Bezier));
Assert.That(fifth.ControlPoints[6].Position.Value, Is.EqualTo(new Vector2(5, 5)));
Assert.That(fifth.ControlPoints[6].Type.Value, Is.EqualTo(null));
}
}
}

View File

@ -9,3 +9,9 @@ osu file format v128
// Implicit multi-segment
32,192,3000,6,0,B|32:384|256:384|256:192|256:192|256:0|512:0|512:192,1,800
// Last control point duplicated
0,0,4000,2,0,B|1:1|2:2|3:3|3:3,2,200
// Last control point in segment duplicated
0,0,5000,2,0,B|1:1|2:2|3:3|3:3|B|4:4|5:5,2,200

View File

@ -329,7 +329,13 @@ namespace osu.Game.Beatmaps.Formats
if (point.Type.Value != null)
{
if (point.Type.Value != lastType)
// We've reached a new segment!
// To preserve compatibility with osu-stable as much as possible, segments with the same type are converted to use implicit segments by duplicating the control point.
// One exception to this is when the last control point of the last segment was itself a duplicate, which can't be supported by osu-stable.
bool lastPointWasDuplicate = i > 1 && pathData.Path.ControlPoints[i - 1].Position.Value == pathData.Path.ControlPoints[i - 2].Position.Value;
if (lastPointWasDuplicate || point.Type.Value != lastType)
{
switch (point.Type.Value)
{

View File

@ -336,9 +336,14 @@ namespace osu.Game.Rulesets.Objects.Legacy
while (++endIndex < vertices.Length - endPointLength)
{
// Keep incrementing while an implicit segment doesn't need to be started
if (vertices[endIndex].Position.Value != vertices[endIndex - 1].Position.Value)
continue;
// The last control point of each segment is not allowed to start a new implicit segment.
if (endIndex == vertices.Length - endPointLength - 1)
continue;
// Force a type on the last point, and return the current control point set as a segment.
vertices[endIndex - 1].Type.Value = type;
yield return vertices.AsMemory().Slice(startIndex, endIndex - startIndex);