mirror of
https://github.com/ppy/osu.git
synced 2025-01-07 22:22:59 +08:00
Merge pull request #2876 from smoogipoo/more-mania-conversion-fixes
Fix more instances of osu!mania beatmap conversion failing
This commit is contained in:
commit
c194618df3
@ -5,6 +5,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -13,11 +15,10 @@ using osu.Game.Tests.Beatmaps;
|
|||||||
namespace osu.Game.Rulesets.Mania.Tests
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class ManiaBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
public class ManiaBeatmapConversionTest : BeatmapConversionTest<ManiaConvertMapping, ConvertValue>
|
||||||
{
|
{
|
||||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";
|
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";
|
||||||
|
|
||||||
[NonParallelizable]
|
|
||||||
[TestCase("basic")]
|
[TestCase("basic")]
|
||||||
public new void Test(string name)
|
public new void Test(string name)
|
||||||
{
|
{
|
||||||
@ -34,9 +35,35 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override ManiaConvertMapping CreateConvertMapping() => new ManiaConvertMapping(Converter);
|
||||||
|
|
||||||
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ManiaConvertMapping : ConvertMapping<ConvertValue>, IEquatable<ManiaConvertMapping>
|
||||||
|
{
|
||||||
|
public uint RandomW;
|
||||||
|
public uint RandomX;
|
||||||
|
public uint RandomY;
|
||||||
|
public uint RandomZ;
|
||||||
|
|
||||||
|
public ManiaConvertMapping()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManiaConvertMapping(IBeatmapConverter converter)
|
||||||
|
{
|
||||||
|
var maniaConverter = (ManiaBeatmapConverter)converter;
|
||||||
|
RandomW = maniaConverter.Random.W;
|
||||||
|
RandomX = maniaConverter.Random.X;
|
||||||
|
RandomY = maniaConverter.Random.Y;
|
||||||
|
RandomZ = maniaConverter.Random.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ;
|
||||||
|
public override bool Equals(ConvertMapping<ConvertValue> other) => base.Equals(other) && Equals(other as ManiaConvertMapping);
|
||||||
|
}
|
||||||
|
|
||||||
public struct ConvertValue : IEquatable<ConvertValue>
|
public struct ConvertValue : IEquatable<ConvertValue>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -5,6 +5,7 @@ using osu.Game.Rulesets.Mania.Objects;
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -28,8 +29,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
public int TargetColumns;
|
public int TargetColumns;
|
||||||
public readonly bool IsForCurrentRuleset;
|
public readonly bool IsForCurrentRuleset;
|
||||||
|
|
||||||
|
// Internal for testing purposes
|
||||||
|
internal FastRandom Random { get; private set; }
|
||||||
|
|
||||||
private Pattern lastPattern = new Pattern();
|
private Pattern lastPattern = new Pattern();
|
||||||
private FastRandom random;
|
|
||||||
|
|
||||||
private ManiaBeatmap beatmap;
|
private ManiaBeatmap beatmap;
|
||||||
|
|
||||||
@ -62,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
||||||
|
|
||||||
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
||||||
random = new FastRandom(seed);
|
Random = new FastRandom(seed);
|
||||||
|
|
||||||
return base.ConvertBeatmap(original);
|
return base.ConvertBeatmap(original);
|
||||||
}
|
}
|
||||||
@ -100,7 +103,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
private double lastTime;
|
private double lastTime;
|
||||||
private Vector2 lastPosition;
|
private Vector2 lastPosition;
|
||||||
private PatternType lastStair;
|
private PatternType lastStair = PatternType.Stair;
|
||||||
private void recordNote(double time, Vector2 position)
|
private void recordNote(double time, Vector2 position)
|
||||||
{
|
{
|
||||||
lastTime = time;
|
lastTime = time;
|
||||||
@ -115,12 +118,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// <returns>The hit objects generated.</returns>
|
/// <returns>The hit objects generated.</returns>
|
||||||
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original, IBeatmap originalBeatmap)
|
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original, IBeatmap originalBeatmap)
|
||||||
{
|
{
|
||||||
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap);
|
var generator = new SpecificBeatmapPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap);
|
||||||
|
|
||||||
Pattern newPattern = generator.Generate();
|
foreach (var newPattern in generator.Generate())
|
||||||
lastPattern = newPattern;
|
{
|
||||||
|
lastPattern = newPattern;
|
||||||
|
|
||||||
return newPattern.HitObjects;
|
foreach (var obj in newPattern.HitObjects)
|
||||||
|
yield return obj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -138,27 +144,44 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
Patterns.PatternGenerator conversion = null;
|
Patterns.PatternGenerator conversion = null;
|
||||||
|
|
||||||
if (distanceData != null)
|
if (distanceData != null)
|
||||||
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap);
|
{
|
||||||
|
var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap);
|
||||||
|
conversion = generator;
|
||||||
|
|
||||||
|
for (double time = original.StartTime; !Precision.DefinitelyBigger(time, generator.EndTime); time += generator.SegmentDuration)
|
||||||
|
{
|
||||||
|
recordNote(time, positionData?.Position ?? Vector2.Zero);
|
||||||
|
computeDensity(time);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (endTimeData != null)
|
else if (endTimeData != null)
|
||||||
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, originalBeatmap);
|
{
|
||||||
|
conversion = new EndTimeObjectPatternGenerator(Random, original, beatmap, originalBeatmap);
|
||||||
|
|
||||||
|
recordNote(endTimeData.EndTime, new Vector2(256, 192));
|
||||||
|
computeDensity(endTimeData.EndTime);
|
||||||
|
}
|
||||||
else if (positionData != null)
|
else if (positionData != null)
|
||||||
{
|
{
|
||||||
computeDensity(original.StartTime);
|
computeDensity(original.StartTime);
|
||||||
|
|
||||||
conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair, originalBeatmap);
|
conversion = new HitObjectPatternGenerator(Random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair, originalBeatmap);
|
||||||
|
|
||||||
recordNote(original.StartTime, positionData.Position);
|
recordNote(original.StartTime, positionData.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversion == null)
|
if (conversion == null)
|
||||||
return null;
|
yield break;
|
||||||
|
|
||||||
Pattern newPattern = conversion.Generate();
|
foreach (var newPattern in conversion.Generate())
|
||||||
|
{
|
||||||
|
lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern;
|
||||||
|
lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair;
|
||||||
|
|
||||||
lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern;
|
foreach (var obj in newPattern.HitObjects)
|
||||||
lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair;
|
yield return obj;
|
||||||
|
|
||||||
return newPattern.HitObjects;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -171,7 +194,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Pattern Generate()
|
public override IEnumerable<Pattern> Generate()
|
||||||
|
{
|
||||||
|
yield return generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pattern generate()
|
||||||
{
|
{
|
||||||
var endTimeData = HitObject as IHasEndTime;
|
var endTimeData = HitObject as IHasEndTime;
|
||||||
var positionData = HitObject as IHasXPosition;
|
var positionData = HitObject as IHasXPosition;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
@ -24,8 +25,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float osu_base_scoring_distance = 100;
|
private const float osu_base_scoring_distance = 100;
|
||||||
|
|
||||||
private readonly double endTime;
|
public readonly double EndTime;
|
||||||
private readonly double segmentDuration;
|
public readonly double SegmentDuration;
|
||||||
|
|
||||||
private readonly int spanCount;
|
private readonly int spanCount;
|
||||||
|
|
||||||
private PatternType convertType;
|
private PatternType convertType;
|
||||||
@ -52,53 +54,81 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// The duration of the osu! hit object
|
// The duration of the osu! hit object
|
||||||
double osuDuration = distance / osuVelocity;
|
double osuDuration = distance / osuVelocity;
|
||||||
|
|
||||||
endTime = hitObject.StartTime + osuDuration;
|
EndTime = hitObject.StartTime + osuDuration;
|
||||||
segmentDuration = (endTime - HitObject.StartTime) / spanCount;
|
SegmentDuration = (EndTime - HitObject.StartTime) / spanCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Pattern Generate()
|
public override IEnumerable<Pattern> Generate()
|
||||||
|
{
|
||||||
|
var originalPattern = generate();
|
||||||
|
|
||||||
|
if (originalPattern.HitObjects.Count() == 1)
|
||||||
|
{
|
||||||
|
yield return originalPattern;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to split the intermediate pattern into two new patterns:
|
||||||
|
// 1. A pattern containing all objects that do not end at our EndTime.
|
||||||
|
// 2. A pattern containing all objects that end at our EndTime. This will be used for further pattern generation.
|
||||||
|
var intermediatePattern = new Pattern();
|
||||||
|
var endTimePattern = new Pattern();
|
||||||
|
|
||||||
|
foreach (var obj in originalPattern.HitObjects)
|
||||||
|
{
|
||||||
|
if (!Precision.AlmostEquals(EndTime, (obj as IHasEndTime)?.EndTime ?? obj.StartTime))
|
||||||
|
intermediatePattern.Add(obj);
|
||||||
|
else
|
||||||
|
endTimePattern.Add(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return intermediatePattern;
|
||||||
|
yield return endTimePattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pattern generate()
|
||||||
{
|
{
|
||||||
if (TotalColumns == 1)
|
if (TotalColumns == 1)
|
||||||
{
|
{
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
addToPattern(pattern, 0, HitObject.StartTime, endTime);
|
addToPattern(pattern, 0, HitObject.StartTime, EndTime);
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spanCount > 1)
|
if (spanCount > 1)
|
||||||
{
|
{
|
||||||
if (segmentDuration <= 90)
|
if (SegmentDuration <= 90)
|
||||||
return generateRandomHoldNotes(HitObject.StartTime, 1);
|
return generateRandomHoldNotes(HitObject.StartTime, 1);
|
||||||
|
|
||||||
if (segmentDuration <= 120)
|
if (SegmentDuration <= 120)
|
||||||
{
|
{
|
||||||
convertType |= PatternType.ForceNotStack;
|
convertType |= PatternType.ForceNotStack;
|
||||||
return generateRandomNotes(HitObject.StartTime, spanCount + 1);
|
return generateRandomNotes(HitObject.StartTime, spanCount + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segmentDuration <= 160)
|
if (SegmentDuration <= 160)
|
||||||
return generateStair(HitObject.StartTime);
|
return generateStair(HitObject.StartTime);
|
||||||
|
|
||||||
if (segmentDuration <= 200 && ConversionDifficulty > 3)
|
if (SegmentDuration <= 200 && ConversionDifficulty > 3)
|
||||||
return generateRandomMultipleNotes(HitObject.StartTime);
|
return generateRandomMultipleNotes(HitObject.StartTime);
|
||||||
|
|
||||||
double duration = endTime - HitObject.StartTime;
|
double duration = EndTime - HitObject.StartTime;
|
||||||
if (duration >= 4000)
|
if (duration >= 4000)
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
||||||
|
|
||||||
if (segmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart)
|
if (SegmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart)
|
||||||
return generateTiledHoldNotes(HitObject.StartTime);
|
return generateTiledHoldNotes(HitObject.StartTime);
|
||||||
|
|
||||||
return generateHoldAndNormalNotes(HitObject.StartTime);
|
return generateHoldAndNormalNotes(HitObject.StartTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segmentDuration <= 110)
|
if (SegmentDuration <= 110)
|
||||||
{
|
{
|
||||||
if (PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
convertType |= PatternType.ForceNotStack;
|
convertType |= PatternType.ForceNotStack;
|
||||||
else
|
else
|
||||||
convertType &= ~PatternType.ForceNotStack;
|
convertType &= ~PatternType.ForceNotStack;
|
||||||
return generateRandomNotes(HitObject.StartTime, segmentDuration < 80 ? 1 : 2);
|
return generateRandomNotes(HitObject.StartTime, SegmentDuration < 80 ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
@ -148,7 +178,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, EndTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is can't be combined with the above loop due to RNG
|
// This is can't be combined with the above loop due to RNG
|
||||||
@ -156,7 +186,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
while (pattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, EndTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -193,7 +223,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
lastColumn = nextColumn;
|
lastColumn = nextColumn;
|
||||||
startTime += segmentDuration;
|
startTime += SegmentDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -223,7 +253,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
for (int i = 0; i <= spanCount; i++)
|
for (int i = 0; i <= spanCount; i++)
|
||||||
{
|
{
|
||||||
addToPattern(pattern, column, startTime, startTime);
|
addToPattern(pattern, column, startTime, startTime);
|
||||||
startTime += segmentDuration;
|
startTime += SegmentDuration;
|
||||||
|
|
||||||
// Check if we're at the borders of the stage, and invert the pattern if so
|
// Check if we're at the borders of the stage, and invert the pattern if so
|
||||||
if (increasing)
|
if (increasing)
|
||||||
@ -284,7 +314,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
|
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
startTime += segmentDuration;
|
startTime += SegmentDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -372,8 +402,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
while (pattern.ColumnHasObject(nextColumn))
|
while (pattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, EndTime);
|
||||||
startTime += segmentDuration;
|
startTime += SegmentDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -402,7 +432,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the hold note
|
// Create the hold note
|
||||||
addToPattern(pattern, holdColumn, startTime, endTime);
|
addToPattern(pattern, holdColumn, startTime, EndTime);
|
||||||
|
|
||||||
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
int noteCount;
|
int noteCount;
|
||||||
@ -434,7 +464,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
pattern.Add(rowPattern);
|
pattern.Add(rowPattern);
|
||||||
rowPattern.Clear();
|
rowPattern.Clear();
|
||||||
|
|
||||||
startTime += segmentDuration;
|
startTime += SegmentDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -452,7 +482,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (curveData == null)
|
if (curveData == null)
|
||||||
return HitObject.Samples;
|
return HitObject.Samples;
|
||||||
|
|
||||||
double segmentTime = (endTime - HitObject.StartTime) / spanCount;
|
double segmentTime = (EndTime - HitObject.StartTime) / spanCount;
|
||||||
|
|
||||||
int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
|
int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
|
||||||
return curveData.RepeatSamples[index];
|
return curveData.RepeatSamples[index];
|
||||||
|
@ -24,7 +24,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
endTime = endtimeData?.EndTime ?? 0;
|
endTime = endtimeData?.EndTime ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Pattern Generate()
|
public override IEnumerable<Pattern> Generate()
|
||||||
|
{
|
||||||
|
yield return generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pattern generate()
|
||||||
{
|
{
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -82,127 +83,133 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8)
|
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8)
|
||||||
convertType |= PatternType.Mirror;
|
convertType |= PatternType.Mirror;
|
||||||
else
|
else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP))
|
||||||
convertType |= PatternType.Gathered;
|
convertType |= PatternType.Gathered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Pattern Generate()
|
public override IEnumerable<Pattern> Generate()
|
||||||
{
|
{
|
||||||
if (TotalColumns == 1)
|
yield return generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pattern generate()
|
||||||
|
{
|
||||||
|
var pattern = new Pattern();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var pattern = new Pattern();
|
if (TotalColumns == 1)
|
||||||
addToPattern(pattern, 0);
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0;
|
|
||||||
|
|
||||||
if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any())
|
|
||||||
{
|
|
||||||
// Generate a new pattern by copying the last hit objects in reverse-column order
|
|
||||||
var pattern = new Pattern();
|
|
||||||
|
|
||||||
for (int i = RandomStart; i < TotalColumns; i++)
|
|
||||||
if (PreviousPattern.ColumnHasObject(i))
|
|
||||||
addToPattern(pattern, RandomStart + TotalColumns - i - 1);
|
|
||||||
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
|
||||||
// If we convert to 7K + 1, let's not overload the special key
|
|
||||||
&& (TotalColumns != 8 || lastColumn != 0)
|
|
||||||
// Make sure the last column was not the centre column
|
|
||||||
&& (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
|
|
||||||
{
|
|
||||||
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
|
||||||
var pattern = new Pattern();
|
|
||||||
|
|
||||||
int column = RandomStart + TotalColumns - lastColumn - 1;
|
|
||||||
addToPattern(pattern, column);
|
|
||||||
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any())
|
|
||||||
{
|
|
||||||
// Generate a new pattern by placing on the already filled columns
|
|
||||||
var pattern = new Pattern();
|
|
||||||
|
|
||||||
for (int i = RandomStart; i < TotalColumns; i++)
|
|
||||||
if (PreviousPattern.ColumnHasObject(i))
|
|
||||||
addToPattern(pattern, i);
|
|
||||||
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((convertType & PatternType.Stair) > 0 && PreviousPattern.HitObjects.Count() == 1)
|
|
||||||
{
|
|
||||||
// Generate a new pattern by placing on the next column, cycling back to the start if there is no "next"
|
|
||||||
var pattern = new Pattern();
|
|
||||||
|
|
||||||
int targetColumn = lastColumn + 1;
|
|
||||||
if (targetColumn == TotalColumns)
|
|
||||||
{
|
{
|
||||||
targetColumn = RandomStart;
|
addToPattern(pattern, 0);
|
||||||
StairType = PatternType.ReverseStair;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
addToPattern(pattern, targetColumn);
|
int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0;
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((convertType & PatternType.ReverseStair) > 0 && PreviousPattern.HitObjects.Count() == 1)
|
if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any())
|
||||||
{
|
|
||||||
// Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous"
|
|
||||||
var pattern = new Pattern();
|
|
||||||
|
|
||||||
int targetColumn = lastColumn - 1;
|
|
||||||
if (targetColumn == RandomStart - 1)
|
|
||||||
{
|
{
|
||||||
targetColumn = TotalColumns - 1;
|
// Generate a new pattern by copying the last hit objects in reverse-column order
|
||||||
StairType = PatternType.Stair;
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
|
if (PreviousPattern.ColumnHasObject(i))
|
||||||
|
addToPattern(pattern, RandomStart + TotalColumns - i - 1);
|
||||||
|
|
||||||
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
addToPattern(pattern, targetColumn);
|
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
||||||
return pattern;
|
// If we convert to 7K + 1, let's not overload the special key
|
||||||
}
|
&& (TotalColumns != 8 || lastColumn != 0)
|
||||||
|
// Make sure the last column was not the centre column
|
||||||
|
&& (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
|
||||||
|
{
|
||||||
|
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
||||||
|
int column = RandomStart + TotalColumns - lastColumn - 1;
|
||||||
|
addToPattern(pattern, column);
|
||||||
|
|
||||||
if ((convertType & PatternType.KeepSingle) > 0)
|
return pattern;
|
||||||
return generateRandomNotes(1);
|
}
|
||||||
|
|
||||||
|
if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any())
|
||||||
|
{
|
||||||
|
// Generate a new pattern by placing on the already filled columns
|
||||||
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
|
if (PreviousPattern.ColumnHasObject(i))
|
||||||
|
addToPattern(pattern, i);
|
||||||
|
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PreviousPattern.HitObjects.Count() == 1)
|
||||||
|
{
|
||||||
|
if ((convertType & PatternType.Stair) > 0)
|
||||||
|
{
|
||||||
|
// Generate a new pattern by placing on the next column, cycling back to the start if there is no "next"
|
||||||
|
int targetColumn = lastColumn + 1;
|
||||||
|
if (targetColumn == TotalColumns)
|
||||||
|
targetColumn = RandomStart;
|
||||||
|
|
||||||
|
addToPattern(pattern, targetColumn);
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((convertType & PatternType.ReverseStair) > 0)
|
||||||
|
{
|
||||||
|
// Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous"
|
||||||
|
int targetColumn = lastColumn - 1;
|
||||||
|
if (targetColumn == RandomStart - 1)
|
||||||
|
targetColumn = TotalColumns - 1;
|
||||||
|
|
||||||
|
addToPattern(pattern, targetColumn);
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((convertType & PatternType.KeepSingle) > 0)
|
||||||
|
return pattern = generateRandomNotes(1);
|
||||||
|
|
||||||
|
if ((convertType & PatternType.Mirror) > 0)
|
||||||
|
{
|
||||||
|
if (ConversionDifficulty > 6.5)
|
||||||
|
return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
|
||||||
|
if (ConversionDifficulty > 4)
|
||||||
|
return pattern = generateRandomPatternWithMirrored(0.12, 0.17, 0);
|
||||||
|
return pattern = generateRandomPatternWithMirrored(0.12, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if ((convertType & PatternType.Mirror) > 0)
|
|
||||||
{
|
|
||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
return generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
|
{
|
||||||
|
if ((convertType & PatternType.LowProbability) > 0)
|
||||||
|
return pattern = generateRandomPattern(0.78, 0.42, 0, 0);
|
||||||
|
return pattern = generateRandomPattern(1, 0.62, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (ConversionDifficulty > 4)
|
if (ConversionDifficulty > 4)
|
||||||
return generateRandomPatternWithMirrored(0.12, 0.17, 0);
|
{
|
||||||
return generateRandomPatternWithMirrored(0.12, 0, 0);
|
if ((convertType & PatternType.LowProbability) > 0)
|
||||||
}
|
return pattern = generateRandomPattern(0.35, 0.08, 0, 0);
|
||||||
|
return pattern = generateRandomPattern(0.52, 0.15, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 2)
|
||||||
|
{
|
||||||
|
if ((convertType & PatternType.LowProbability) > 0)
|
||||||
|
return pattern = generateRandomPattern(0.18, 0, 0, 0);
|
||||||
|
return pattern = generateRandomPattern(0.45, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pattern = generateRandomPattern(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
if ((convertType & PatternType.LowProbability) > 0)
|
foreach (var obj in pattern.HitObjects)
|
||||||
return generateRandomPattern(0.78, 0.42, 0, 0);
|
{
|
||||||
return generateRandomPattern(1, 0.62, 0, 0);
|
if ((convertType & PatternType.Stair) > 0 && obj.Column == TotalColumns - 1)
|
||||||
|
StairType = PatternType.ReverseStair;
|
||||||
|
if ((convertType & PatternType.ReverseStair) > 0 && obj.Column == RandomStart)
|
||||||
|
StairType = PatternType.Stair;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConversionDifficulty > 4)
|
|
||||||
{
|
|
||||||
if ((convertType & PatternType.LowProbability) > 0)
|
|
||||||
return generateRandomPattern(0.35, 0.08, 0, 0);
|
|
||||||
return generateRandomPattern(0.52, 0.15, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConversionDifficulty > 2)
|
|
||||||
{
|
|
||||||
if ((convertType & PatternType.LowProbability) > 0)
|
|
||||||
return generateRandomPattern(0.18, 0, 0, 0);
|
|
||||||
return generateRandomPattern(0.45, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return generateRandomPattern(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -103,17 +103,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
HitObject lastObject = OriginalBeatmap.HitObjects.LastOrDefault();
|
HitObject lastObject = OriginalBeatmap.HitObjects.LastOrDefault();
|
||||||
HitObject firstObject = OriginalBeatmap.HitObjects.FirstOrDefault();
|
HitObject firstObject = OriginalBeatmap.HitObjects.FirstOrDefault();
|
||||||
|
|
||||||
double drainTime = (lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0);
|
// Drain time in seconds
|
||||||
drainTime -= OriginalBeatmap.TotalBreakTime;
|
int drainTime = (int)(((lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0) - OriginalBeatmap.TotalBreakTime) / 1000);
|
||||||
|
|
||||||
if (drainTime == 0)
|
if (drainTime == 0)
|
||||||
drainTime = 10000000;
|
drainTime = 10000;
|
||||||
|
|
||||||
// We need this in seconds
|
|
||||||
drainTime /= 1000;
|
|
||||||
|
|
||||||
BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty;
|
BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty;
|
||||||
conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15;
|
conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + (double)OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15;
|
||||||
conversionDifficulty = Math.Min(conversionDifficulty.Value, 12);
|
conversionDifficulty = Math.Min(conversionDifficulty.Value, 12);
|
||||||
|
|
||||||
return conversionDifficulty.Value;
|
return conversionDifficulty.Value;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||||
@ -42,9 +43,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates the pattern for <see cref="HitObject"/>, filled with hit objects.
|
/// Generates the patterns for <see cref="HitObject"/>, each filled with hit objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The <see cref="Pattern"/> containing the hit objects.</returns>
|
/// <returns>The <see cref="Pattern"/>s containing the hit objects.</returns>
|
||||||
public abstract Pattern Generate();
|
public abstract IEnumerable<Pattern> Generate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,15 @@ namespace osu.Game.Rulesets.Mania.MathUtils
|
|||||||
private const uint y = 842502087;
|
private const uint y = 842502087;
|
||||||
private const uint z = 3579807591;
|
private const uint z = 3579807591;
|
||||||
private const uint w = 273326509;
|
private const uint w = 273326509;
|
||||||
private uint _x, _y = y, _z = z, _w = w;
|
|
||||||
|
internal uint X { get; private set; }
|
||||||
|
internal uint Y { get; private set; } = y;
|
||||||
|
internal uint Z { get; private set; } = z;
|
||||||
|
internal uint W { get; private set; } = w;
|
||||||
|
|
||||||
public FastRandom(int seed)
|
public FastRandom(int seed)
|
||||||
{
|
{
|
||||||
_x = (uint)seed;
|
X = (uint)seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FastRandom()
|
public FastRandom()
|
||||||
@ -33,11 +37,11 @@ namespace osu.Game.Rulesets.Mania.MathUtils
|
|||||||
/// <returns>The random value.</returns>
|
/// <returns>The random value.</returns>
|
||||||
public uint NextUInt()
|
public uint NextUInt()
|
||||||
{
|
{
|
||||||
uint t = _x ^ _x << 11;
|
uint t = X ^ X << 11;
|
||||||
_x = _y;
|
X = Y;
|
||||||
_y = _z;
|
Y = Z;
|
||||||
_z = _w;
|
Z = W;
|
||||||
return _w = _w ^ _w >> 19 ^ t ^ t >> 8;
|
return W = W ^ W >> 19 ^ t ^ t >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,103 +1,132 @@
|
|||||||
{
|
{
|
||||||
"Mappings": [{
|
"Mappings": [{
|
||||||
"StartTime": 500,
|
"RandomW": 2659373485,
|
||||||
"Objects": [{
|
"RandomX": 3579807591,
|
||||||
"StartTime": 500,
|
"RandomY": 273326509,
|
||||||
"EndTime": 2500,
|
"RandomZ": 272969173,
|
||||||
"Column": 0
|
"StartTime": 500.0,
|
||||||
},
|
"Objects": [{
|
||||||
{
|
"StartTime": 500.0,
|
||||||
"StartTime": 1500,
|
"EndTime": 2500.0,
|
||||||
"EndTime": 2500,
|
"Column": 0
|
||||||
"Column": 1
|
}, {
|
||||||
}
|
"StartTime": 1500.0,
|
||||||
]
|
"EndTime": 2500.0,
|
||||||
},
|
"Column": 1
|
||||||
{
|
}]
|
||||||
"StartTime": 3000,
|
}, {
|
||||||
"Objects": [{
|
"RandomW": 3083803045,
|
||||||
"StartTime": 3000,
|
"RandomX": 273326509,
|
||||||
"EndTime": 4000,
|
"RandomY": 272969173,
|
||||||
"Column": 2
|
"RandomZ": 2659373485,
|
||||||
}]
|
"StartTime": 3000.0,
|
||||||
},
|
"Objects": [{
|
||||||
{
|
"StartTime": 3000.0,
|
||||||
"StartTime": 4500,
|
"EndTime": 4000.0,
|
||||||
"Objects": [{
|
"Column": 2
|
||||||
"StartTime": 4500,
|
}]
|
||||||
"EndTime": 5500,
|
}, {
|
||||||
"Column": 4
|
"RandomW": 4073554232,
|
||||||
}]
|
"RandomX": 272969173,
|
||||||
},
|
"RandomY": 2659373485,
|
||||||
{
|
"RandomZ": 3083803045,
|
||||||
"StartTime": 6000,
|
"StartTime": 4500.0,
|
||||||
"Objects": [{
|
"Objects": [{
|
||||||
"StartTime": 6000,
|
"StartTime": 4500.0,
|
||||||
"EndTime": 6500,
|
"EndTime": 5500.0,
|
||||||
"Column": 2
|
"Column": 4
|
||||||
}]
|
}]
|
||||||
},
|
}, {
|
||||||
{
|
"RandomW": 3420401969,
|
||||||
"StartTime": 7000,
|
"RandomX": 2659373485,
|
||||||
"Objects": [{
|
"RandomY": 3083803045,
|
||||||
"StartTime": 7000,
|
"RandomZ": 4073554232,
|
||||||
"EndTime": 8000,
|
"StartTime": 6000.0,
|
||||||
"Column": 2
|
"Objects": [{
|
||||||
}]
|
"StartTime": 6000.0,
|
||||||
},
|
"EndTime": 6500.0,
|
||||||
{
|
"Column": 2
|
||||||
"StartTime": 8500,
|
}]
|
||||||
"Objects": [{
|
}, {
|
||||||
"StartTime": 8500,
|
"RandomW": 1129881182,
|
||||||
"EndTime": 11000,
|
"RandomX": 3083803045,
|
||||||
"Column": 0
|
"RandomY": 4073554232,
|
||||||
}]
|
"RandomZ": 3420401969,
|
||||||
},
|
"StartTime": 7000.0,
|
||||||
{
|
"Objects": [{
|
||||||
"StartTime": 11500,
|
"StartTime": 7000.0,
|
||||||
"Objects": [{
|
"EndTime": 8000.0,
|
||||||
"StartTime": 11500,
|
"Column": 2
|
||||||
"EndTime": 12000,
|
}]
|
||||||
"Column": 1
|
}, {
|
||||||
}]
|
"RandomW": 315568458,
|
||||||
},
|
"RandomX": 3420401969,
|
||||||
{
|
"RandomY": 1129881182,
|
||||||
"StartTime": 12500,
|
"RandomZ": 2358617505,
|
||||||
"Objects": [{
|
"StartTime": 8500.0,
|
||||||
"StartTime": 12500,
|
"Objects": [{
|
||||||
"EndTime": 16500,
|
"StartTime": 8500.0,
|
||||||
"Column": 4
|
"EndTime": 11000.0,
|
||||||
}]
|
"Column": 0
|
||||||
},
|
}]
|
||||||
{
|
}, {
|
||||||
"StartTime": 17000,
|
"RandomW": 548134043,
|
||||||
"Objects": [{
|
"RandomX": 1129881182,
|
||||||
"StartTime": 17000,
|
"RandomY": 2358617505,
|
||||||
"EndTime": 18000,
|
"RandomZ": 315568458,
|
||||||
"Column": 2
|
"StartTime": 11500.0,
|
||||||
}]
|
"Objects": [{
|
||||||
},
|
"StartTime": 11500.0,
|
||||||
{
|
"EndTime": 12000.0,
|
||||||
"StartTime": 18500,
|
"Column": 1
|
||||||
"Objects": [{
|
}]
|
||||||
"StartTime": 18500,
|
}, {
|
||||||
"EndTime": 19450,
|
"RandomW": 3979422122,
|
||||||
"Column": 0
|
"RandomX": 548134043,
|
||||||
}]
|
"RandomY": 2810584254,
|
||||||
},
|
"RandomZ": 2250186050,
|
||||||
{
|
"StartTime": 12500.0,
|
||||||
"StartTime": 19875,
|
"Objects": [{
|
||||||
"Objects": [{
|
"StartTime": 12500.0,
|
||||||
"StartTime": 19875,
|
"EndTime": 16500.0,
|
||||||
"EndTime": 23875,
|
"Column": 4
|
||||||
"Column": 1
|
}]
|
||||||
},
|
}, {
|
||||||
{
|
"RandomW": 2466283411,
|
||||||
"StartTime": 19875,
|
"RandomX": 2810584254,
|
||||||
"EndTime": 23875,
|
"RandomY": 2250186050,
|
||||||
"Column": 0
|
"RandomZ": 3979422122,
|
||||||
}
|
"StartTime": 17000.0,
|
||||||
]
|
"Objects": [{
|
||||||
}
|
"StartTime": 17000.0,
|
||||||
]
|
"EndTime": 18000.0,
|
||||||
|
"Column": 2
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"RandomW": 83157665,
|
||||||
|
"RandomX": 2250186050,
|
||||||
|
"RandomY": 3979422122,
|
||||||
|
"RandomZ": 2466283411,
|
||||||
|
"StartTime": 18500.0,
|
||||||
|
"Objects": [{
|
||||||
|
"StartTime": 18500.0,
|
||||||
|
"EndTime": 19450.0,
|
||||||
|
"Column": 0
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"RandomW": 2383087700,
|
||||||
|
"RandomX": 83157665,
|
||||||
|
"RandomY": 2055150192,
|
||||||
|
"RandomZ": 510071020,
|
||||||
|
"StartTime": 19875.0,
|
||||||
|
"Objects": [{
|
||||||
|
"StartTime": 19875.0,
|
||||||
|
"EndTime": 23875.0,
|
||||||
|
"Column": 1
|
||||||
|
}, {
|
||||||
|
"StartTime": 19875.0,
|
||||||
|
"EndTime": 23875.0,
|
||||||
|
"Column": 0
|
||||||
|
}]
|
||||||
|
}]
|
||||||
}
|
}
|
@ -25,6 +25,8 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
|
|
||||||
protected abstract string ResourceAssembly { get; }
|
protected abstract string ResourceAssembly { get; }
|
||||||
|
|
||||||
|
protected IBeatmapConverter Converter { get; private set; }
|
||||||
|
|
||||||
protected void Test(string name)
|
protected void Test(string name)
|
||||||
{
|
{
|
||||||
var ourResult = convert(name);
|
var ourResult = convert(name);
|
||||||
@ -41,14 +43,22 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
Assert.Fail($"A conversion did not generate any hitobjects, but should have, for hitobject at time: {expectedResult.Mappings[mappingCounter].StartTime}\n");
|
Assert.Fail($"A conversion did not generate any hitobjects, but should have, for hitobject at time: {expectedResult.Mappings[mappingCounter].StartTime}\n");
|
||||||
else if (mappingCounter >= expectedResult.Mappings.Count)
|
else if (mappingCounter >= expectedResult.Mappings.Count)
|
||||||
Assert.Fail($"A conversion generated hitobjects, but should not have, for hitobject at time: {ourResult.Mappings[mappingCounter].StartTime}\n");
|
Assert.Fail($"A conversion generated hitobjects, but should not have, for hitobject at time: {ourResult.Mappings[mappingCounter].StartTime}\n");
|
||||||
|
else if (!expectedResult.Mappings[mappingCounter].Equals(ourResult.Mappings[mappingCounter]))
|
||||||
|
{
|
||||||
|
var expectedMapping = expectedResult.Mappings[mappingCounter];
|
||||||
|
var ourMapping = ourResult.Mappings[mappingCounter];
|
||||||
|
|
||||||
|
Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n"
|
||||||
|
+ $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n"
|
||||||
|
+ $"Received: {JsonConvert.SerializeObject(ourMapping)}\n");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var counter = mappingCounter;
|
var ourMapping = ourResult.Mappings[mappingCounter];
|
||||||
|
var expectedMapping = expectedResult.Mappings[mappingCounter];
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
var ourMapping = ourResult.Mappings[counter];
|
|
||||||
var expectedMapping = expectedResult.Mappings[counter];
|
|
||||||
|
|
||||||
int objectCounter = 0;
|
int objectCounter = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -60,10 +70,6 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
else if (objectCounter >= expectedMapping.Objects.Count)
|
else if (objectCounter >= expectedMapping.Objects.Count)
|
||||||
Assert.Fail($"The conversion generated a hitobject, but should not have, for hitobject at time: {ourMapping.StartTime}:\n"
|
Assert.Fail($"The conversion generated a hitobject, but should not have, for hitobject at time: {ourMapping.StartTime}:\n"
|
||||||
+ $"Received: {JsonConvert.SerializeObject(ourMapping.Objects[objectCounter])}\n");
|
+ $"Received: {JsonConvert.SerializeObject(ourMapping.Objects[objectCounter])}\n");
|
||||||
else if (!expectedMapping.Equals(ourMapping))
|
|
||||||
Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n"
|
|
||||||
+ $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n"
|
|
||||||
+ $"Received: {JsonConvert.SerializeObject(ourMapping)}\n");
|
|
||||||
else if (!expectedMapping.Objects[objectCounter].Equals(ourMapping.Objects[objectCounter]))
|
else if (!expectedMapping.Objects[objectCounter].Equals(ourMapping.Objects[objectCounter]))
|
||||||
{
|
{
|
||||||
Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}:\n"
|
Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}:\n"
|
||||||
@ -88,10 +94,11 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
var rulesetInstance = CreateRuleset();
|
var rulesetInstance = CreateRuleset();
|
||||||
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
|
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
|
||||||
|
|
||||||
var result = new ConvertResult();
|
Converter = rulesetInstance.CreateBeatmapConverter(beatmap);
|
||||||
var converter = rulesetInstance.CreateBeatmapConverter(beatmap);
|
|
||||||
|
|
||||||
converter.ObjectConverted += (orig, converted) =>
|
var result = new ConvertResult();
|
||||||
|
|
||||||
|
Converter.ObjectConverted += (orig, converted) =>
|
||||||
{
|
{
|
||||||
converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty));
|
converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty));
|
||||||
|
|
||||||
@ -103,7 +110,7 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
result.Mappings.Add(mapping);
|
result.Mappings.Add(mapping);
|
||||||
};
|
};
|
||||||
|
|
||||||
IBeatmap convertedBeatmap = converter.Convert();
|
IBeatmap convertedBeatmap = Converter.Convert();
|
||||||
rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess();
|
rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
Reference in New Issue
Block a user