@@ -12,7 +12,7 @@ public class UgcGenerator : IGenerator<ChuChart>
1212 private int RSL = 480 * 4 ;
1313 private List < Alert > alerts = [ ] ;
1414 public List < ( string , string ) > ExtraHeaders = [ ] ;
15-
15+
1616 private int useTil = 0 ; // 当前的 @USETIL 值
1717
1818 /**
@@ -45,7 +45,7 @@ private List<ChuNote> SortedNotesForConnectingPrevious(ChuChart chart)
4545 // 2. 遍历 chart.Notes,对每个 ChuNote 以 DFS 方式把它本身以及它所有 Next 子孙依次加入结果。
4646 var result = new List < ChuNote > ( chart . Notes . Count ) ;
4747 var visited = new HashSet < ChuNote > ( ) ;
48- foreach ( var root in chart . Notes . Where ( x=> x . TargetNote == null ) ) Dfs ( root ) ;
48+ foreach ( var root in chart . Notes . Where ( x => x . TargetNote == null ) ) Dfs ( root ) ;
4949 return result ;
5050
5151 void Dfs ( ChuNote n )
@@ -86,12 +86,24 @@ void Dfs(ChuNote n)
8686 }
8787 // 为了实现从上述 T函数 中的换算,所必要的信息。可通过CalcUgcBeats函数算出。
8888 private List < ( int , int , int ) > _ugcBeats = [ ] ;
89-
90- private void FillUgcBeats ( List < MET > metList )
89+
90+ private void FillUgcBeats ( ChuChart chart )
9191 {
9292 _ugcBeats = [ ] ;
93- foreach ( var met in metList )
93+ foreach ( var origMet in chart . MetList )
9494 {
95+ var met = origMet ;
96+ if ( met . Numerator <= 0 )
97+ {
98+ // See https://github.com/MuNET-OSS/MuConvert/pull/7#discussion_r4217218971 ,
99+ // in official game, met.Numerator == 0 means there should be no "beat lines", which cannot be easily implemented in Umiguri.
100+ // But this will cause DivideByZeroException in the `T` function, so we just force met.Numerator to be equals with met.Denominator.
101+ alerts . Add ( new Alert ( Alert . LEVEL . Info , $ "UgcGenerator 不支持使用MET拍号的分子小于等于0,来取消节拍提示线的语法。" +
102+ $ "该处MET已被等效为\" MET { met . Time . WholePart } { ( met . Time . FractionPart * 384 ) . Round ( ) } { met . Denominator } { met . Denominator } \" ,即节拍提示线还是会正常显示。",
103+ ( chart , met . Time ) , relevantNote : $ "MET { met . Time . WholePart } { ( met . Time . FractionPart * 384 ) . Round ( ) } { met . Denominator } { met . Numerator } ") ) ;
104+ met = met with { Numerator = met . Denominator } ;
105+ }
106+
95107 if ( _ugcBeats . Count == 0 )
96108 {
97109 if ( met . Time > 0 ) _ugcBeats . Add ( ( 0 , 4 , 4 ) ) ; // 鲁棒性,补 @BEAT 0 4 4。不能continue,因为马上还要添加显式的那一条。
@@ -112,13 +124,15 @@ private void FillUgcBeats(List<MET> metList)
112124 }
113125 _ugcBeats . Add ( ( ugcBar , met . Numerator , met . Denominator ) ) ;
114126 }
127+
128+ if ( _ugcBeats . Count == 0 ) _ugcBeats . Add ( ( 0 , 4 , 4 ) ) ;
115129 }
116130
117131 private string Serialize ( ChuChart ugc )
118132 {
119133 ugc . Sort ( ) ;
120- FillUgcBeats ( ugc . MetList ) ;
121-
134+ FillUgcBeats ( ugc ) ;
135+
122136 var sb = new StringBuilder ( ) ;
123137 sb . AppendLine ( $ "' Created with MuConvert v{ Utils . AppVersion } ") ;
124138 sb . AppendLine ( "@VER\t 8" ) ;
@@ -161,15 +175,15 @@ private string Serialize(ChuChart ugc)
161175 tilList [ ( ( t . Time + t . Duration ) . CanonicalForm , groupId ) ] = 1 ;
162176 }
163177 }
164-
178+
165179 foreach ( var s in tilList . ToList ( )
166- . OrderBy ( x=> ( x . Key . time , x . Key . groupId ) ) )
167- {
168- var ( m , o ) = T ( s . Key . time ) ;
180+ . OrderBy ( x => ( x . Key . time , x . Key . groupId ) ) )
181+ {
182+ var ( m , o ) = T ( s . Key . time ) ;
169183 sb . AppendLine ( FormattableString . Invariant ( $ "@TIL\t { s . Key . groupId } \t { m } '{ o } \t { s . Value : 0.00000} ") ) ;
170184 }
171185 #endregion
172-
186+
173187 sb . AppendLine ( "@MAINTIL\t 0" ) ; // 用户没有通过ExtraHeaders指定,则提供一个默认值
174188 sb . AppendLine ( "@ENDHEAD" ) ;
175189 sb . AppendLine ( ) ;
@@ -232,7 +246,7 @@ private void AppendFollowerLines(StringBuilder sb, ChuNote n)
232246 }
233247
234248 private static string EncodeAirHeight ( decimal value ) => IToH36 ( Math . Clamp ( ( int ) Math . Round ( Height_ToUgc ( value ) * 10 ) , 0 , 1295 ) ) . PadLeft ( 2 , '0' ) ;
235-
249+
236250 private string AirColor ( ChuNote n )
237251 {
238252 var color = AirColor_ToUgc ( n ) ;
@@ -241,7 +255,7 @@ private string AirColor(ChuNote n)
241255 return color ;
242256 }
243257 private string CrushColor ( ChuNote n ) => AirCrush_Color_ToUgc [ n . Color ] ;
244- private string CrushInterval ( Rational ? crushInterval ) =>
258+ private string CrushInterval ( Rational ? crushInterval ) =>
245259 crushInterval != null ? Utils . Tick ( crushInterval . Value , RSL ) . ToString ( ) : "$" ;
246260
247261 private string UCode ( ChuNote n )
0 commit comments