11package funkin .backend .chart ;
22
3- import funkin .backend .system .Conductor ;
43import funkin .backend .chart .ChartData ;
54import flixel .util .FlxColor ;
65import haxe .io .Path ;
@@ -13,12 +12,68 @@ import sys.FileSystem;
1312
1413using StringTools ;
1514
15+ enum abstract ChartFormat (Int ) {
16+ var CODENAME = 0 ;
17+ var LEGACY = 1 ; // also used by many other engines (old Psych, Kade and more) - Nex
18+ var VSLICE = 2 ;
19+ var PSYCH_NEW = 3 ;
20+
21+ @:to public function toString (): String {
22+ return switch (cast (this , ChartFormat )) {
23+ case CODENAME : " CODENAME" ;
24+ case LEGACY : " LEGACY" ;
25+ case VSLICE : " VSLICE" ;
26+ case PSYCH_NEW : " PSYCH_NEW" ;
27+ }
28+ }
29+
30+ public static function fromString (str : String , def : ChartFormat = ChartFormat .LEGACY ) {
31+ str = str .toLowerCase ();
32+ str = StringTools .replace (str , " " , " " );
33+ str = StringTools .replace (str , " _" , " " );
34+ str = StringTools .replace (str , " ." , " " );
35+
36+ if (StringTools .startsWith (str , " psychv1" ) || StringTools .startsWith (str , " psych1" ))
37+ return PSYCH_NEW ;
38+
39+ return switch (str ) {
40+ case " codename" | " codenameengine" : CODENAME ;
41+ case " newpsych" | " psychnew" : PSYCH_NEW ;
42+ default : def ;
43+ }
44+ }
45+ }
46+
1647class Chart {
1748 /**
1849 * Default background colors for songs without bg color
1950 */
2051 public inline static var defaultColor : FlxColor = 0xFF9271FD ;
2152
53+ public static function cleanSongData (data : Dynamic ): Dynamic {
54+ if (Reflect .hasField (data , " song" )) {
55+ var field : Dynamic = Reflect .field (data , " song" );
56+ if (field != null && Type .typeof (field ) == TObject ) // Cant use Reflect.isObject, because it detects strings for some reason
57+ return field ;
58+ }
59+ return data ;
60+ }
61+
62+ public static function detectChartFormat (data : Dynamic ): ChartFormat {
63+ var __temp : Dynamic ; // imma reuse this var so the program doesnt have to get values multiple times - Nex
64+
65+ if ((__temp = data .codenameChart ) == true || __temp == " true" )
66+ return CODENAME ;
67+
68+ if (Reflect .hasField (data , " version" ) && Reflect .hasField (data , " scrollSpeed" ))
69+ return VSLICE ;
70+
71+ if ((__temp = cleanSongData (data ).format ) != null && __temp is String && StringTools .startsWith (__temp , " psych_v1" ))
72+ return PSYCH_NEW ;
73+
74+ return LEGACY ;
75+ }
76+
2277 public static function loadEventsJson (songName : String ) {
2378 var path = Paths .file (' songs/ ${songName .toLowerCase ()}/events.json' );
2479 var data : Array <ChartEvent > = null ;
@@ -33,8 +88,9 @@ class Chart {
3388 }
3489
3590 public static function loadChartMeta (songName : String , difficulty : String = " normal" , fromMods : Bool = true ) {
36- var metaPath = Paths .file (' songs/ ${songName .toLowerCase ()}/meta.json' );
37- var metaDiffPath = Paths .file (' songs/ ${songName .toLowerCase ()}/meta- ${difficulty .toLowerCase ()}.json' );
91+ var songNameLower = songName .toLowerCase ();
92+ var metaPath = Paths .file (' songs/ ${songNameLower }/meta.json' );
93+ var metaDiffPath = Paths .file (' songs/ ${songNameLower }/meta- ${difficulty .toLowerCase ()}.json' );
3894
3995 var data : ChartMetaData = null ;
4096 var fromMods : Bool = fromMods ;
@@ -67,7 +123,7 @@ class Chart {
67123 data .setFieldDefault (" parsedColor" , data .color .getColorFromDynamic ().getDefault (defaultColor ));
68124
69125 if (data .difficulties .length <= 0 ) {
70- data .difficulties = [for (f in Paths .getFolderContent (' songs/ ${songName . toLowerCase () }/charts/' , false , ! fromMods )) if (Path .extension (f = f .toUpperCase ()) == " JSON" ) Path .withoutExtension (f )];
126+ data .difficulties = [for (f in Paths .getFolderContent (' songs/ ${songNameLower }/charts/' , false , ! fromMods )) if (Path .extension (f = f .toUpperCase ()) == " JSON" ) Path .withoutExtension (f )];
71127 if (data .difficulties .length == 3 ) {
72128 var hasHard = false , hasNormal = false , hasEasy = false ;
73129 for (d in data .difficulties ) {
@@ -116,12 +172,12 @@ class Chart {
116172 Logs .trace (' Could not parse chart for song ${songName } ( $difficulty ): ${Std .string (e )}' , ERROR , RED );
117173 }
118174
119- if ( data != null ) {
120- /**
121- * CHART CONVERSION
122- */
123- # if REGION
124- if ( Reflect . hasField ( data , " codenameChart " ) && Reflect . field ( data , " codenameChart " ) == true ) {
175+ /**
176+ * CHART CONVERSION
177+ */
178+ #if REGION
179+ if ( data != null ) switch ( detectChartFormat ( data )) {
180+ case CODENAME :
125181 // backward compat on events since its caused problems
126182 var eventTypesToString : Map <Int , String > = [
127183 - 1 => " HScript Call" ,
@@ -132,28 +188,23 @@ class Chart {
132188 ];
133189
134190 if (data .events == null ) data .events = [];
135- for (event in cast (data .events , Array <Dynamic >)) {
136- if (Reflect .hasField (event , " type" )) {
137- if (event .type != null )
138- event .name = eventTypesToString [event .type ];
139- Reflect .deleteField (event , " type" );
140- }
191+ for (event in cast (data .events , Array <Dynamic >)) if (Reflect .hasField (event , " type" )) {
192+ if (event .type != null )
193+ event .name = eventTypesToString [event .type ];
194+ Reflect .deleteField (event , " type" );
141195 }
142196
143- // codename chart
144197 base = data ;
145- } else {
146- // base game chart
147- FNFLegacyParser .parse (data , base );
148- }
149- #end
198+ case PSYCH_NEW : PsychParser .parse (data , base );
199+ case VSLICE : // TODO
200+ case LEGACY : FNFLegacyParser .parse (data , base );
150201 }
202+ #end
151203
152- if ( base . meta == null )
153- base .meta = loadChartMeta ( songName , difficulty , base .fromMods ) ;
204+ var loadedMeta = loadChartMeta ( songName , difficulty , base . fromMods );
205+ if ( base .meta == null ) base .meta = loadedMeta ;
154206 else {
155- var loadedMeta = loadChartMeta (songName , difficulty , base .fromMods );
156- for (field in Reflect .fields (base .meta )) {
207+ for (field in Reflect .fields (base .meta )) {
157208 var f = Reflect .field (base .meta , field );
158209 if (f != null )
159210 Reflect .setField (loadedMeta , field , f );
@@ -249,4 +300,4 @@ typedef ChartSaveSettings = {
249300 var ? saveEventsInChart : Bool ;
250301 var ? prettyPrint : Bool ;
251302 var ? folder : String ;
252- }
303+ }
0 commit comments