mirror of
https://github.com/ppy/osu.git
synced 2025-01-31 23:52:55 +08:00
Throw exceptions and let LegacyDecoder handle them
This commit is contained in:
parent
54ee0cabd8
commit
ac2060f1cf
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.IO.File;
|
using osu.Framework.IO.File;
|
||||||
using osu.Framework.Logging;
|
|
||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
using osu.Game.Rulesets.Objects.Legacy;
|
using osu.Game.Rulesets.Objects.Legacy;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
@ -292,10 +291,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
EventType type;
|
EventType type;
|
||||||
|
|
||||||
if (!Enum.TryParse(split[0], out type))
|
if (!Enum.TryParse(split[0], out type))
|
||||||
{
|
throw new InvalidDataException($@"Unknown event type: {split[0]}");
|
||||||
Logger.Log($"Unknown beatmap event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -323,90 +319,79 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
private void handleTimingPoint(string line)
|
private void handleTimingPoint(string line)
|
||||||
{
|
{
|
||||||
try
|
string[] split = line.Split(',');
|
||||||
|
|
||||||
|
double time = getOffsetTime(Parsing.ParseDouble(split[0].Trim()));
|
||||||
|
double beatLength = Parsing.ParseDouble(split[1].Trim());
|
||||||
|
double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1;
|
||||||
|
|
||||||
|
TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple;
|
||||||
|
if (split.Length >= 3)
|
||||||
|
timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)Parsing.ParseInt(split[2]);
|
||||||
|
|
||||||
|
LegacySampleBank sampleSet = defaultSampleBank;
|
||||||
|
if (split.Length >= 4)
|
||||||
|
sampleSet = (LegacySampleBank)Parsing.ParseInt(split[3]);
|
||||||
|
|
||||||
|
int customSampleBank = 0;
|
||||||
|
if (split.Length >= 5)
|
||||||
|
customSampleBank = Parsing.ParseInt(split[4]);
|
||||||
|
|
||||||
|
int sampleVolume = defaultSampleVolume;
|
||||||
|
if (split.Length >= 6)
|
||||||
|
sampleVolume = Parsing.ParseInt(split[5]);
|
||||||
|
|
||||||
|
bool timingChange = true;
|
||||||
|
if (split.Length >= 7)
|
||||||
|
timingChange = split[6][0] == '1';
|
||||||
|
|
||||||
|
bool kiaiMode = false;
|
||||||
|
bool omitFirstBarSignature = false;
|
||||||
|
|
||||||
|
if (split.Length >= 8)
|
||||||
{
|
{
|
||||||
string[] split = line.Split(',');
|
EffectFlags effectFlags = (EffectFlags)Parsing.ParseInt(split[7]);
|
||||||
|
kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai);
|
||||||
double time = getOffsetTime(Parsing.ParseDouble(split[0].Trim()));
|
omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine);
|
||||||
double beatLength = Parsing.ParseDouble(split[1].Trim());
|
|
||||||
double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1;
|
|
||||||
|
|
||||||
TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple;
|
|
||||||
if (split.Length >= 3)
|
|
||||||
timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)Parsing.ParseInt(split[2]);
|
|
||||||
|
|
||||||
LegacySampleBank sampleSet = defaultSampleBank;
|
|
||||||
if (split.Length >= 4)
|
|
||||||
sampleSet = (LegacySampleBank)Parsing.ParseInt(split[3]);
|
|
||||||
|
|
||||||
int customSampleBank = 0;
|
|
||||||
if (split.Length >= 5)
|
|
||||||
customSampleBank = Parsing.ParseInt(split[4]);
|
|
||||||
|
|
||||||
int sampleVolume = defaultSampleVolume;
|
|
||||||
if (split.Length >= 6)
|
|
||||||
sampleVolume = Parsing.ParseInt(split[5]);
|
|
||||||
|
|
||||||
bool timingChange = true;
|
|
||||||
if (split.Length >= 7)
|
|
||||||
timingChange = split[6][0] == '1';
|
|
||||||
|
|
||||||
bool kiaiMode = false;
|
|
||||||
bool omitFirstBarSignature = false;
|
|
||||||
|
|
||||||
if (split.Length >= 8)
|
|
||||||
{
|
|
||||||
EffectFlags effectFlags = (EffectFlags)Parsing.ParseInt(split[7]);
|
|
||||||
kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai);
|
|
||||||
omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
string stringSampleSet = sampleSet.ToString().ToLowerInvariant();
|
|
||||||
if (stringSampleSet == @"none")
|
|
||||||
stringSampleSet = @"normal";
|
|
||||||
|
|
||||||
if (timingChange)
|
|
||||||
{
|
|
||||||
var controlPoint = CreateTimingControlPoint();
|
|
||||||
controlPoint.Time = time;
|
|
||||||
controlPoint.BeatLength = beatLength;
|
|
||||||
controlPoint.TimeSignature = timeSignature;
|
|
||||||
|
|
||||||
handleTimingControlPoint(controlPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDifficultyControlPoint(new DifficultyControlPoint
|
|
||||||
{
|
|
||||||
Time = time,
|
|
||||||
SpeedMultiplier = speedMultiplier,
|
|
||||||
AutoGenerated = timingChange
|
|
||||||
});
|
|
||||||
|
|
||||||
handleEffectControlPoint(new EffectControlPoint
|
|
||||||
{
|
|
||||||
Time = time,
|
|
||||||
KiaiMode = kiaiMode,
|
|
||||||
OmitFirstBarLine = omitFirstBarSignature,
|
|
||||||
AutoGenerated = timingChange
|
|
||||||
});
|
|
||||||
|
|
||||||
handleSampleControlPoint(new LegacySampleControlPoint
|
|
||||||
{
|
|
||||||
Time = time,
|
|
||||||
SampleBank = stringSampleSet,
|
|
||||||
SampleVolume = sampleVolume,
|
|
||||||
CustomSampleBank = customSampleBank,
|
|
||||||
AutoGenerated = timingChange
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
|
||||||
|
string stringSampleSet = sampleSet.ToString().ToLowerInvariant();
|
||||||
|
if (stringSampleSet == @"none")
|
||||||
|
stringSampleSet = @"normal";
|
||||||
|
|
||||||
|
if (timingChange)
|
||||||
{
|
{
|
||||||
Logger.Log("A timing point could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important);
|
var controlPoint = CreateTimingControlPoint();
|
||||||
|
controlPoint.Time = time;
|
||||||
|
controlPoint.BeatLength = beatLength;
|
||||||
|
controlPoint.TimeSignature = timeSignature;
|
||||||
|
|
||||||
|
handleTimingControlPoint(controlPoint);
|
||||||
}
|
}
|
||||||
catch (OverflowException)
|
|
||||||
|
handleDifficultyControlPoint(new DifficultyControlPoint
|
||||||
{
|
{
|
||||||
Logger.Log("A timing point could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important);
|
Time = time,
|
||||||
}
|
SpeedMultiplier = speedMultiplier,
|
||||||
|
AutoGenerated = timingChange
|
||||||
|
});
|
||||||
|
|
||||||
|
handleEffectControlPoint(new EffectControlPoint
|
||||||
|
{
|
||||||
|
Time = time,
|
||||||
|
KiaiMode = kiaiMode,
|
||||||
|
OmitFirstBarLine = omitFirstBarSignature,
|
||||||
|
AutoGenerated = timingChange
|
||||||
|
});
|
||||||
|
|
||||||
|
handleSampleControlPoint(new LegacySampleControlPoint
|
||||||
|
{
|
||||||
|
Time = time,
|
||||||
|
SampleBank = stringSampleSet,
|
||||||
|
SampleVolume = sampleVolume,
|
||||||
|
CustomSampleBank = customSampleBank,
|
||||||
|
AutoGenerated = timingChange
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleTimingControlPoint(TimingControlPoint newPoint)
|
private void handleTimingControlPoint(TimingControlPoint newPoint)
|
||||||
|
@ -10,7 +10,6 @@ using osuTK;
|
|||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.IO.File;
|
using osu.Framework.IO.File;
|
||||||
using osu.Framework.Logging;
|
|
||||||
using osu.Game.Storyboards;
|
using osu.Game.Storyboards;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Formats
|
namespace osu.Game.Beatmaps.Formats
|
||||||
@ -85,10 +84,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
EventType type;
|
EventType type;
|
||||||
|
|
||||||
if (!Enum.TryParse(split[0], out type))
|
if (!Enum.TryParse(split[0], out type))
|
||||||
{
|
throw new InvalidDataException($@"Unknown event type: {split[0]}");
|
||||||
Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,6 @@ using osu.Game.Beatmaps.Formats;
|
|||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Logging;
|
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects.Legacy
|
namespace osu.Game.Rulesets.Objects.Legacy
|
||||||
@ -41,208 +40,192 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
public override HitObject Parse(string text)
|
public override HitObject Parse(string text)
|
||||||
{
|
{
|
||||||
try
|
string[] split = text.Split(',');
|
||||||
|
|
||||||
|
Vector2 pos = new Vector2((int)Parsing.ParseFloat(split[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE));
|
||||||
|
|
||||||
|
double startTime = Parsing.ParseDouble(split[2]) + Offset;
|
||||||
|
|
||||||
|
ConvertHitObjectType type = (ConvertHitObjectType)Parsing.ParseInt(split[3]);
|
||||||
|
|
||||||
|
int comboOffset = (int)(type & ConvertHitObjectType.ComboOffset) >> 4;
|
||||||
|
type &= ~ConvertHitObjectType.ComboOffset;
|
||||||
|
|
||||||
|
bool combo = type.HasFlag(ConvertHitObjectType.NewCombo);
|
||||||
|
type &= ~ConvertHitObjectType.NewCombo;
|
||||||
|
|
||||||
|
var soundType = (LegacySoundType)Parsing.ParseInt(split[4]);
|
||||||
|
var bankInfo = new SampleBankInfo();
|
||||||
|
|
||||||
|
HitObject result = null;
|
||||||
|
|
||||||
|
if (type.HasFlag(ConvertHitObjectType.Circle))
|
||||||
{
|
{
|
||||||
string[] split = text.Split(',');
|
result = CreateHit(pos, combo, comboOffset);
|
||||||
|
|
||||||
Vector2 pos = new Vector2((int)Parsing.ParseFloat(split[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE));
|
if (split.Length > 5)
|
||||||
|
readCustomSampleBanks(split[5], bankInfo);
|
||||||
|
}
|
||||||
|
else if (type.HasFlag(ConvertHitObjectType.Slider))
|
||||||
|
{
|
||||||
|
PathType pathType = PathType.Catmull;
|
||||||
|
double? length = null;
|
||||||
|
|
||||||
double startTime = Parsing.ParseDouble(split[2]) + Offset;
|
string[] pointSplit = split[5].Split('|');
|
||||||
|
|
||||||
ConvertHitObjectType type = (ConvertHitObjectType)Parsing.ParseInt(split[3]);
|
int pointCount = 1;
|
||||||
|
foreach (var t in pointSplit)
|
||||||
|
if (t.Length > 1)
|
||||||
|
pointCount++;
|
||||||
|
|
||||||
int comboOffset = (int)(type & ConvertHitObjectType.ComboOffset) >> 4;
|
var points = new Vector2[pointCount];
|
||||||
type &= ~ConvertHitObjectType.ComboOffset;
|
|
||||||
|
|
||||||
bool combo = type.HasFlag(ConvertHitObjectType.NewCombo);
|
int pointIndex = 1;
|
||||||
type &= ~ConvertHitObjectType.NewCombo;
|
|
||||||
|
|
||||||
var soundType = (LegacySoundType)Parsing.ParseInt(split[4]);
|
foreach (string t in pointSplit)
|
||||||
var bankInfo = new SampleBankInfo();
|
|
||||||
|
|
||||||
HitObject result = null;
|
|
||||||
|
|
||||||
if (type.HasFlag(ConvertHitObjectType.Circle))
|
|
||||||
{
|
{
|
||||||
result = CreateHit(pos, combo, comboOffset);
|
if (t.Length == 1)
|
||||||
|
|
||||||
if (split.Length > 5)
|
|
||||||
readCustomSampleBanks(split[5], bankInfo);
|
|
||||||
}
|
|
||||||
else if (type.HasFlag(ConvertHitObjectType.Slider))
|
|
||||||
{
|
|
||||||
PathType pathType = PathType.Catmull;
|
|
||||||
double? length = null;
|
|
||||||
|
|
||||||
string[] pointSplit = split[5].Split('|');
|
|
||||||
|
|
||||||
int pointCount = 1;
|
|
||||||
foreach (var t in pointSplit)
|
|
||||||
if (t.Length > 1)
|
|
||||||
pointCount++;
|
|
||||||
|
|
||||||
var points = new Vector2[pointCount];
|
|
||||||
|
|
||||||
int pointIndex = 1;
|
|
||||||
|
|
||||||
foreach (string t in pointSplit)
|
|
||||||
{
|
{
|
||||||
if (t.Length == 1)
|
switch (t)
|
||||||
{
|
{
|
||||||
switch (t)
|
case @"C":
|
||||||
{
|
pathType = PathType.Catmull;
|
||||||
case @"C":
|
|
||||||
pathType = PathType.Catmull;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case @"B":
|
|
||||||
pathType = PathType.Bezier;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case @"L":
|
|
||||||
pathType = PathType.Linear;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case @"P":
|
|
||||||
pathType = PathType.PerfectCurve;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] temp = t.Split(':');
|
|
||||||
points[pointIndex++] = new Vector2((int)Parsing.ParseDouble(temp[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(temp[1], Parsing.MAX_COORDINATE_VALUE)) - pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// osu-stable special-cased colinear perfect curves to a CurveType.Linear
|
|
||||||
bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y));
|
|
||||||
|
|
||||||
if (points.Length == 3 && pathType == PathType.PerfectCurve && isLinear(points))
|
|
||||||
pathType = PathType.Linear;
|
|
||||||
|
|
||||||
int repeatCount = Parsing.ParseInt(split[6]);
|
|
||||||
|
|
||||||
if (repeatCount > 9000)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high");
|
|
||||||
|
|
||||||
// osu-stable treated the first span of the slider as a repeat, but no repeats are happening
|
|
||||||
repeatCount = Math.Max(0, repeatCount - 1);
|
|
||||||
|
|
||||||
if (split.Length > 7)
|
|
||||||
{
|
|
||||||
length = Math.Max(0, Parsing.ParseDouble(split[7]));
|
|
||||||
if (length == 0)
|
|
||||||
length = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (split.Length > 10)
|
|
||||||
readCustomSampleBanks(split[10], bankInfo);
|
|
||||||
|
|
||||||
// One node for each repeat + the start and end nodes
|
|
||||||
int nodes = repeatCount + 2;
|
|
||||||
|
|
||||||
// Populate node sample bank infos with the default hit object sample bank
|
|
||||||
var nodeBankInfos = new List<SampleBankInfo>();
|
|
||||||
for (int i = 0; i < nodes; i++)
|
|
||||||
nodeBankInfos.Add(bankInfo.Clone());
|
|
||||||
|
|
||||||
// Read any per-node sample banks
|
|
||||||
if (split.Length > 9 && split[9].Length > 0)
|
|
||||||
{
|
|
||||||
string[] sets = split[9].Split('|');
|
|
||||||
|
|
||||||
for (int i = 0; i < nodes; i++)
|
|
||||||
{
|
|
||||||
if (i >= sets.Length)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SampleBankInfo info = nodeBankInfos[i];
|
case @"B":
|
||||||
readCustomSampleBanks(sets[i], info);
|
pathType = PathType.Bezier;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate node sound types with the default hit object sound type
|
|
||||||
var nodeSoundTypes = new List<LegacySoundType>();
|
|
||||||
for (int i = 0; i < nodes; i++)
|
|
||||||
nodeSoundTypes.Add(soundType);
|
|
||||||
|
|
||||||
// Read any per-node sound types
|
|
||||||
if (split.Length > 8 && split[8].Length > 0)
|
|
||||||
{
|
|
||||||
string[] adds = split[8].Split('|');
|
|
||||||
|
|
||||||
for (int i = 0; i < nodes; i++)
|
|
||||||
{
|
|
||||||
if (i >= adds.Length)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int sound;
|
case @"L":
|
||||||
int.TryParse(adds[i], out sound);
|
pathType = PathType.Linear;
|
||||||
nodeSoundTypes[i] = (LegacySoundType)sound;
|
break;
|
||||||
|
|
||||||
|
case @"P":
|
||||||
|
pathType = PathType.PerfectCurve;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the final per-node samples
|
string[] temp = t.Split(':');
|
||||||
var nodeSamples = new List<List<HitSampleInfo>>(nodes);
|
points[pointIndex++] = new Vector2((int)Parsing.ParseDouble(temp[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(temp[1], Parsing.MAX_COORDINATE_VALUE)) - pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// osu-stable special-cased colinear perfect curves to a CurveType.Linear
|
||||||
|
bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y));
|
||||||
|
|
||||||
|
if (points.Length == 3 && pathType == PathType.PerfectCurve && isLinear(points))
|
||||||
|
pathType = PathType.Linear;
|
||||||
|
|
||||||
|
int repeatCount = Parsing.ParseInt(split[6]);
|
||||||
|
|
||||||
|
if (repeatCount > 9000)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high");
|
||||||
|
|
||||||
|
// osu-stable treated the first span of the slider as a repeat, but no repeats are happening
|
||||||
|
repeatCount = Math.Max(0, repeatCount - 1);
|
||||||
|
|
||||||
|
if (split.Length > 7)
|
||||||
|
{
|
||||||
|
length = Math.Max(0, Parsing.ParseDouble(split[7]));
|
||||||
|
if (length == 0)
|
||||||
|
length = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split.Length > 10)
|
||||||
|
readCustomSampleBanks(split[10], bankInfo);
|
||||||
|
|
||||||
|
// One node for each repeat + the start and end nodes
|
||||||
|
int nodes = repeatCount + 2;
|
||||||
|
|
||||||
|
// Populate node sample bank infos with the default hit object sample bank
|
||||||
|
var nodeBankInfos = new List<SampleBankInfo>();
|
||||||
|
for (int i = 0; i < nodes; i++)
|
||||||
|
nodeBankInfos.Add(bankInfo.Clone());
|
||||||
|
|
||||||
|
// Read any per-node sample banks
|
||||||
|
if (split.Length > 9 && split[9].Length > 0)
|
||||||
|
{
|
||||||
|
string[] sets = split[9].Split('|');
|
||||||
|
|
||||||
for (int i = 0; i < nodes; i++)
|
for (int i = 0; i < nodes; i++)
|
||||||
nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i]));
|
|
||||||
|
|
||||||
result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples);
|
|
||||||
|
|
||||||
// The samples are played when the slider ends, which is the last node
|
|
||||||
result.Samples = nodeSamples[nodeSamples.Count - 1];
|
|
||||||
}
|
|
||||||
else if (type.HasFlag(ConvertHitObjectType.Spinner))
|
|
||||||
{
|
|
||||||
double endTime = Math.Max(startTime, Parsing.ParseDouble(split[5]) + Offset);
|
|
||||||
|
|
||||||
result = CreateSpinner(new Vector2(512, 384) / 2, combo, comboOffset, endTime);
|
|
||||||
|
|
||||||
if (split.Length > 6)
|
|
||||||
readCustomSampleBanks(split[6], bankInfo);
|
|
||||||
}
|
|
||||||
else if (type.HasFlag(ConvertHitObjectType.Hold))
|
|
||||||
{
|
|
||||||
// Note: Hold is generated by BMS converts
|
|
||||||
|
|
||||||
double endTime = Math.Max(startTime, Parsing.ParseDouble(split[2]));
|
|
||||||
|
|
||||||
if (split.Length > 5 && !string.IsNullOrEmpty(split[5]))
|
|
||||||
{
|
{
|
||||||
string[] ss = split[5].Split(':');
|
if (i >= sets.Length)
|
||||||
endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0]));
|
break;
|
||||||
readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo);
|
|
||||||
|
SampleBankInfo info = nodeBankInfos[i];
|
||||||
|
readCustomSampleBanks(sets[i], info);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CreateHold(pos, combo, comboOffset, endTime + Offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
// Populate node sound types with the default hit object sound type
|
||||||
|
var nodeSoundTypes = new List<LegacySoundType>();
|
||||||
|
for (int i = 0; i < nodes; i++)
|
||||||
|
nodeSoundTypes.Add(soundType);
|
||||||
|
|
||||||
|
// Read any per-node sound types
|
||||||
|
if (split.Length > 8 && split[8].Length > 0)
|
||||||
{
|
{
|
||||||
Logger.Log($"Unknown hit object type: {type}. Skipped.", level: LogLevel.Error);
|
string[] adds = split[8].Split('|');
|
||||||
return null;
|
|
||||||
|
for (int i = 0; i < nodes; i++)
|
||||||
|
{
|
||||||
|
if (i >= adds.Length)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int sound;
|
||||||
|
int.TryParse(adds[i], out sound);
|
||||||
|
nodeSoundTypes[i] = (LegacySoundType)sound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.StartTime = startTime;
|
// Generate the final per-node samples
|
||||||
|
var nodeSamples = new List<List<HitSampleInfo>>(nodes);
|
||||||
|
for (int i = 0; i < nodes; i++)
|
||||||
|
nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i]));
|
||||||
|
|
||||||
if (result.Samples.Count == 0)
|
result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples);
|
||||||
result.Samples = convertSoundType(soundType, bankInfo);
|
|
||||||
|
|
||||||
FirstObject = false;
|
// The samples are played when the slider ends, which is the last node
|
||||||
|
result.Samples = nodeSamples[nodeSamples.Count - 1];
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
else if (type.HasFlag(ConvertHitObjectType.Spinner))
|
||||||
{
|
{
|
||||||
Logger.Log("A hitobject could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important);
|
double endTime = Math.Max(startTime, Parsing.ParseDouble(split[5]) + Offset);
|
||||||
|
|
||||||
|
result = CreateSpinner(new Vector2(512, 384) / 2, combo, comboOffset, endTime);
|
||||||
|
|
||||||
|
if (split.Length > 6)
|
||||||
|
readCustomSampleBanks(split[6], bankInfo);
|
||||||
}
|
}
|
||||||
catch (OverflowException)
|
else if (type.HasFlag(ConvertHitObjectType.Hold))
|
||||||
{
|
{
|
||||||
Logger.Log("A hitobject could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important);
|
// Note: Hold is generated by BMS converts
|
||||||
|
|
||||||
|
double endTime = Math.Max(startTime, Parsing.ParseDouble(split[2]));
|
||||||
|
|
||||||
|
if (split.Length > 5 && !string.IsNullOrEmpty(split[5]))
|
||||||
|
{
|
||||||
|
string[] ss = split[5].Split(':');
|
||||||
|
endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0]));
|
||||||
|
readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CreateHold(pos, combo, comboOffset, endTime + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
if (result == null)
|
||||||
|
throw new InvalidDataException($"Unknown hit object type: {type}");
|
||||||
|
|
||||||
|
result.StartTime = startTime;
|
||||||
|
|
||||||
|
if (result.Samples.Count == 0)
|
||||||
|
result.Samples = convertSoundType(soundType, bankInfo);
|
||||||
|
|
||||||
|
FirstObject = false;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readCustomSampleBanks(string str, SampleBankInfo bankInfo)
|
private void readCustomSampleBanks(string str, SampleBankInfo bankInfo)
|
||||||
|
Loading…
Reference in New Issue
Block a user