@@ -434,10 +434,11 @@ class FreeplayState extends MusicBeatState
434434
435435class FreeplaySonglist {
436436 public var songs : Array <ChartMetaData > = [];
437+ public static final EXCLUDE_SUBFOLDERS : Array <String > = [' charts' , ' scripts' , ' song' ];
437438
438439 public function new () {}
439440
440- public function getSongsFromSource (source : funkin.backend.assets. AssetSource , useTxt : Bool = true ) {
441+ public function getSongsFromSource (source : funkin.backend.assets. AssetSource , useTxt : Bool = true , ? startDir : String = ' songs/ ' , ? flatten : Bool = true ) {
441442 var songsFound : Array <String > = null ;
442443 if (useTxt ) {
443444 var oldPath = Paths .txt (' freeplaySonglist' );
@@ -448,27 +449,49 @@ class FreeplaySonglist {
448449 songsFound = CoolUtil .coolTextFile (oldPath );
449450 }
450451 }
451- if (songsFound == null ) songsFound = Paths .getFolderDirectories (" songs" , false , source );
452+ // todo: make this better
453+ if (songsFound == null ) {
454+ songsFound = [];
455+ var songDirs = Paths .getFolderDirectories (startDir , false , source );
456+ if (! flatten ) {
457+ for (i in songDirs ) {
458+ var subs = Paths .getFolderDirectories (' $startDir $i ' , false , source ).filter (a -> ! EXCLUDE_SUBFOLDERS .contains (a ));
459+ songsFound .push ((subs .length > 0 ) ? ' $i /' : i );
460+ }
461+ } else {
462+ function poop (a : Array <Dynamic >, startDir : String ) {
463+ for (i in a ) {
464+ var subs = Paths .getFolderDirectories (' $startDir $i ' , false , source ).filter (a -> ! EXCLUDE_SUBFOLDERS .contains (a ));
465+ if (subs .length > 0 ) poop (subs , ' $startDir $i /' );
466+ else songsFound .push (startDir .substr (' songs/' .length ) + i );
467+ }
468+ }
469+ poop (songDirs , startDir );
470+ }
471+ // put folders at the top
472+ songsFound = songsFound .filter (a -> a .endsWith (' /' ))
473+ .concat (songsFound .filter (a -> ! a .endsWith (' /' )));
474+ }
452475 if (songsFound .length > 0 ) {
453- for (s in songsFound ) songs .push (Chart .loadChartMeta (s , source == MODS ));
476+ for (s in songsFound ) songs .push (Chart .loadChartMeta (startDir . substr ( ' songs/ ' . length ) + s , source == MODS ));
454477 return false ;
455478 }
456479 return true ;
457480 }
458481
459- public static function get (useTxt : Bool = true ) {
482+ public static function get (useTxt : Bool = true , ? startDir : String = ' songs/ ' , ? flatten : Bool = true ) {
460483 var songList = new FreeplaySonglist ();
461484
462485 switch (Flags .SONGS_LIST_MOD_MODE ) {
463486 case ' prepend' :
464- songList .getSongsFromSource (MODS , useTxt );
465- songList .getSongsFromSource (SOURCE , useTxt );
487+ songList .getSongsFromSource (MODS , useTxt , startDir , flatten );
488+ songList .getSongsFromSource (SOURCE , useTxt , startDir , flatten );
466489 case ' append' :
467- songList .getSongsFromSource (SOURCE , useTxt );
468- songList .getSongsFromSource (MODS , useTxt );
490+ songList .getSongsFromSource (SOURCE , useTxt , startDir , flatten );
491+ songList .getSongsFromSource (MODS , useTxt , startDir , flatten );
469492 default /* case 'override'*/ :
470- if (songList .getSongsFromSource (MODS , useTxt ))
471- songList .getSongsFromSource (SOURCE , useTxt );
493+ if (songList .getSongsFromSource (MODS , useTxt , startDir , flatten ))
494+ songList .getSongsFromSource (SOURCE , useTxt , startDir , flatten );
472495 }
473496
474497 return songList ;
0 commit comments