Skip to content

Commit adee473

Browse files
committed
fix: 之前对HXD的实现有误,未考虑到HXD实际是:h和:x的合体
SXD/SXC也可能存在类似的机制,但目前还没研究清楚,所以先不弄上。
1 parent 8f5c0d4 commit adee473

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

generator/chu/UgcGenerator.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ private string Serialize(ChuChart ugc)
207207
if (n.Type is "HLD" or "HXD" && durTicks > 0)
208208
sb.AppendLine($"#{durTicks}>s");
209209
}
210+
211+
if (n.Type is "HXD") // or "SXD" or "SXC") // HXD等于:h加上同位置的:x,因此需要单独emit一个:x主行
212+
sb.AppendLine($"#{m}'{o}:x{ucode[1..3]}{C2U_ChrExtras.GetValueOrDefault(n.Tag, "C")}");
210213
}
211214
return sb.ToString();
212215
}

parser/chu/UgcParser.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@ protected Rational T(int ugcBar, int ugcTick)
4141
// 为了实现从上述 T函数 中的换算,所必要的信息。来自于ugc文件中的 @BEAT 字段
4242
private List<(int, Rational)> _ugcBeats = [];
4343

44+
private Dictionary<(Rational, int, int), ChuNote[]> _HXD_Dict = new();
45+
4446
public override (ChuChart, List<Alert>) Parse(string text)
4547
{
4648
var chart = new ChuChart();
4749
var alerts = new List<Alert>();
4850
_ugcFlags = new();
4951
_ugcBeats = [];
52+
_HXD_Dict = new();
5053
var lines = text.Replace("\r\n", "\n").Split('\n');
5154
var inHeader = true;
5255

@@ -376,6 +379,18 @@ private int ParseNoteLine(string[] lines, int idx, ChuChart chart, List<Alert> a
376379
note.Type = "CHR";
377380
var extraRaw = code.Length > 3 ? code[3..] : "";
378381
note.Tag = U2C_ChrExtras.GetValueOrDefault(extraRaw, extraRaw);
382+
383+
// HXD等于:h加上同位置的:x,因此需要检查有没有同位置的:x,如果有,则修改它的属性同时,不要添加我们自己
384+
if (_HXD_Dict.Remove((note.Time, note.Cell, note.Width), out var dictNotes) && dictNotes.Length > 0 && dictNotes[0].Type is "HLD") // or "SLD" or "SLC")
385+
{
386+
foreach (var hldNote in dictNotes)
387+
{
388+
hldNote.Type = ToExType(hldNote.Type);
389+
hldNote.Tag = note.Tag;
390+
}
391+
return null; // 告诉上层,不要添加我们自己
392+
}
393+
else _HXD_Dict[(note.Time, note.Cell, note.Width)] = [note];
379394
}
380395
return note;
381396
}
@@ -444,11 +459,13 @@ private int ParseHoldOrSlideNote(char noteType, string[] lines, int idx, string
444459
var startTime = previousNote.Time;
445460
ParseCellWidth(code, 1, previousNote, alerts, idx + 1, chart);
446461
if (isAir) ParseHeightAndColor(previousNote, code[3..], alerts, idx+1, noteType.ToString());
462+
var startPos = (startTime, previousNote.Cell, previousNote.Width);
447463
previousNote.EndCell = previousNote.Cell;
448464
previousNote.EndWidth = previousNote.Width;
449465
previousNote.EndHeight = previousNote.Height;
450466

451467
bool foundFirst = false;
468+
List<ChuNote> resultNotes = [];
452469
while (idx + 1 < lines.Length)
453470
{ // 循环处理所有的跟随行。idx始终指向上一条已经处理完的行。
454471
var nextLine = lines[idx + 1].Trim();
@@ -493,6 +510,7 @@ private int ParseHoldOrSlideNote(char noteType, string[] lines, int idx, string
493510
alerts.Add(new Alert(Warning, $"无法找到 Air Slide 的前驱音符", (chart, note.Time), idx + 1, lines[idx]));
494511
}
495512

513+
resultNotes.Add(note);
496514
chart.Notes.Add(note);
497515
previousNote = note;
498516
idx++;
@@ -502,6 +520,21 @@ private int ParseHoldOrSlideNote(char noteType, string[] lines, int idx, string
502520
if (!foundFirst)
503521
alerts.Add(new Alert(Warning, $"SLD 音符缺少时长跟随行") { Line = idx + 1, RelevantNote = lines[idx] });
504522

523+
if (noteType is 'h') // or 's')
524+
{ // HXD等于:h加上同位置的:x,因此需要检查有没有同位置的:x,如果有,应该删除之
525+
if (_HXD_Dict.Remove(startPos, out var dictNotes) && dictNotes is [{ Type: "CHR" }])
526+
{
527+
var chrNote = dictNotes[0];
528+
foreach (var note in resultNotes)
529+
{
530+
note.Type = ToExType(note.Type);
531+
note.Tag = chrNote.Tag;
532+
}
533+
chart.Notes.Remove(chrNote);
534+
}
535+
else _HXD_Dict[startPos] = resultNotes.ToArray();
536+
}
537+
505538
return idx;
506539
}
507540

utils/ChuUtils.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,13 @@ public static bool IsChainContinueSegments(ChuNote n) // 返回 true 表示当
115115
"AHX" => "AHD",
116116
_ => n.Type
117117
};
118+
119+
public static string ToExType(string type) => type switch
120+
{
121+
"HLD" => "HXD",
122+
"SLD" => "SXD",
123+
"SLC" => "SXC",
124+
// "AHD" => "AHX",
125+
_ => throw Utils.Fail()
126+
};
118127
}

0 commit comments

Comments
 (0)