diff --git a/default_content/base-game/songs/milf/metadata.json b/default_content/base-game/songs/milf/metadata.json index f4df046d..30739e9e 100644 --- a/default_content/base-game/songs/milf/metadata.json +++ b/default_content/base-game/songs/milf/metadata.json @@ -1,3 +1,4 @@ { + "songName": "M.I.L.F", "artist": "Kawai Sprite" } \ No newline at end of file diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx index 092c7417..e07f0699 100644 --- a/source/funkin/Paths.hx +++ b/source/funkin/Paths.hx @@ -252,7 +252,7 @@ class Paths inline static public function sound(key:String, ?library:String):Null { - return returnSound('sounds', key, library); + return returnFolderSound('sounds', key, library); } inline static public function soundRandom(key:String, min:Int, max:Int, ?library:String) @@ -262,12 +262,12 @@ class Paths inline static public function music(key:String, ?library:String):Null { - return returnSound('music', key, library); + return returnFolderSound('music', key, library); } inline static public function track(song:String, track:String):Null { - return returnSound('songs', '${formatToSongPath(song)}/$track'); + return returnFolderSound('songs', '${formatToSongPath(song)}/$track'); } inline static public function voices(song:String):Null @@ -528,29 +528,30 @@ class Paths return getPath('$path/$key.$SOUND_EXT'); } - public static function returnSound(path:String, key:String, ?library:String) - { - var gottenPath:String = soundPath(path, key, library); - - if (currentTrackedSounds.exists(gottenPath)) { - if (!localTrackedAssets.contains(gottenPath)) - localTrackedAssets.push(gottenPath); + inline public static function returnFolderSound(path:String, key:String, ?library:String) + return returnSound(soundPath(path, key, library), library); - return currentTrackedSounds.get(gottenPath); + public static function returnSound(path:String, ?library:String) + { + if (currentTrackedSounds.exists(path)) { + if (!localTrackedAssets.contains(path)) + localTrackedAssets.push(path); + + return currentTrackedSounds.get(path); } - var sound = getSound(gottenPath); + var sound = getSound(path); if (sound != null) { - currentTrackedSounds.set(gottenPath, sound); + currentTrackedSounds.set(path, sound); - if (!localTrackedAssets.contains(gottenPath)) - localTrackedAssets.push(gottenPath); + if (!localTrackedAssets.contains(path)) + localTrackedAssets.push(path); return sound; } if (Main.showDebugTraces) - trace('sound $path, $key => $gottenPath returned null'); + trace('sound $path returned null'); return null; } @@ -571,6 +572,9 @@ class Paths return null; } + public static inline function getFolderPath(folder:String = ""):String + return (folder == "") ? getPreloadPath() : mods(folder); + //// public static var currentModDirectory(default, set):String = ''; static function set_currentModDirectory(v:String){ diff --git a/source/funkin/data/Cache.hx b/source/funkin/data/Cache.hx index 4211fb5f..e96b3e02 100644 --- a/source/funkin/data/Cache.hx +++ b/source/funkin/data/Cache.hx @@ -198,11 +198,11 @@ class Cache default: Paths.image(toLoad.path, toLoad.library); case SOUND: - Paths.returnSound("sounds", toLoad.path, toLoad.library); + Paths.returnFolderSound("sounds", toLoad.path, toLoad.library); case MUSIC: - Paths.returnSound("music", toLoad.path, toLoad.library); + Paths.returnFolderSound("music", toLoad.path, toLoad.library); case SONG: - Paths.returnSound("songs", toLoad.path, toLoad.library); + Paths.returnFolderSound("songs", toLoad.path, toLoad.library); } #if traceLoading diff --git a/source/funkin/data/FNFTroll.hx b/source/funkin/data/FNFTroll.hx index 09e46cba..59fe1fa2 100644 --- a/source/funkin/data/FNFTroll.hx +++ b/source/funkin/data/FNFTroll.hx @@ -212,7 +212,7 @@ class FNFTroll extends FNFLegacyBasic { } data.song.metadata ??= {}; - //data.song.metadata.songName = chart.meta.title; + data.song.metadata.songName = chart.meta.title; data.song.metadata.artist = chart.meta.extraData.get("SONG_ARTIST"); data.song.metadata.charter = chart.meta.extraData.get("SONG_CHARTER"); diff --git a/source/funkin/data/Song.hx b/source/funkin/data/Song.hx index 0683da36..b1a2ce02 100644 --- a/source/funkin/data/Song.hx +++ b/source/funkin/data/Song.hx @@ -15,6 +15,7 @@ import funkin.data.Section.SwagSection; import haxe.io.Path; import haxe.Json; +using funkin.CoolerStringTools; using StringTools; typedef SwagSong = { @@ -24,7 +25,6 @@ typedef SwagSong = { //// var song:String; - // var displayName:String; var bpm:Float; var tracks:SongTracks; // currently used @@ -75,40 +75,189 @@ typedef SongTracks = { typedef SongMetadata = { - // ?songName:String, + ?songName:String, ?artist:String, ?charter:String, ?modcharter:String, ?extraInfo:Array, } -@:structInit class Song { - public var songName:String = ''; - public var folder:String = ''; - public var difficulties:Array = []; + public final songId:String; + public final folder:String = ''; + + public var songPath(get, default):String; public var charts(get, null):Array; - function get_charts() - return (charts == null) ? charts = Song.getCharts(this) : charts; + private var metadataCache = new Map(); + + #if PE_MOD_COMPATIBILITY + private final defaultSongPath:String; + private final dataPath:String; + + inline function isUsingDefaultSongPath():Bool { + @:bypassAccessor + return this.songPath == null; + } + #end - public function new(songName:String, ?folder:String = '', ?difficulties:Array) + public function new(songId:String, ?folder:String) { - this.songName = songName; - this.folder = folder != null ? folder : ''; - this.difficulties = difficulties != null ? difficulties : []; + this.songId = songId; + this.folder = folder ?? ''; + #if !PE_MOD_COMPATIBILITY + this.songPath = Paths.getFolderPath(this.folder) + '/songs/$songId'; + #else + var contentFolder = Paths.getFolderPath(this.folder); + this.defaultSongPath = '$contentFolder/songs/$songId'; + this.dataPath = '$contentFolder/data/$songId'; + #end } - public function play(?difficultyName:String = ''){ - var idx = charts.indexOf(difficultyName); - if (idx != -1) - return Song.playSong(this, difficultyName, idx); - - trace('$this: Attempt to play null difficulty: ' + difficultyName); + public function getSongFile(fileName:String) { + var path = '$songPath/$fileName'; + + #if PE_MOD_COMPATIBILITY + if (isUsingDefaultSongPath() && !Paths.exists(path)) { + var pp = '$dataPath/$fileName'; + if (Paths.exists(pp)) path = pp; + } + #end + + return path; + } + + public function play(?chartName:String = ''){ + Song.playSong(this, chartName); } public function toString() - return '$folder:$songName'; + return '$folder:$songId'; + + /** get uncached metadata **/ + private function _getMetadata(chart:String):Null { + var suffix = getDifficultyFileSuffix(chart); + var fileName:String = 'metadata' + suffix + '.json'; + var path:String = getSongFile(fileName); + return Paths.getJson(path); + } + + /** + * Returns metadata for the requested chart. + * If it doesn't exist, metadata for the 'normal' chart is returned instead + * + * @param chartId The song chart for which you want to request metadata + **/ + public function getMetadata(chartId:String = "normal"):SongMetadata { + if (chartId=="") + chartId="normal"; + + if (metadataCache.exists(chartId)) { + //trace('$this: Returning cached metadata for $chartId'); + return metadataCache.get(chartId); + } + + var meta = _getMetadata(chartId); + if (meta != null) { + //trace('$this: Found metadata for $chartId'); + } + else if (chartId != "normal") { + if (Main.showDebugTraces) + trace('$this: Metadata not found for [$chartId]. Using default'); + return getMetadata("normal"); + } + else { + if (Main.showDebugTraces) + trace('$this: No metadata found! Maybe add some?'); + meta = {}; + } + meta.songName ??= songId.replace("-", " ").capitalize(); + + metadataCache.set(chartId, meta); + return meta; + } + + public function getSwagSong(chartId:String):Null { + if (chartId == '') + chartId = 'normal'; + + #if !USING_MOONCHART + var suffix = getDifficultyFileSuffix(chartId); + var path = getSongFile(songId + suffix); + return parseSongJson(path); + #else + + // less strict v-slice format detection + // cause it won't detect it if you place the audio files in the same folder + var chartsFilePath = getSongFile('$songId-chart.json'); + var metadataPath = getSongFile('$songId-metadata.json'); + + if (Paths.exists(chartsFilePath) && Paths.exists(metadataPath)) { + var chart = new moonchart.formats.fnf.FNFVSlice().fromFile(chartsFilePath, metadataPath); + if (chart.diffs.contains(chartId)) { + trace("CONVERTING FROM VSLICE"); + + var converted = new SupportedFormat().fromFormat(chart, chartId); + var chart:JsonSong = cast converted.data.song; + chart.path = chartsFilePath; + chart.song = songId; + chart.tracks = null; + return onLoadJson(chart); + }else{ + trace('VSLICE FILES DO NOT CONTAIN DIFFICULTY CHART: $chartId'); + } + } + + // TODO: scan through the song folder and look for the first thing that has a supported extension (if json then check if it has diffSuffix cus FNF formats!!) + // Or dont since this current method lets you do a dumb thing AKA have 2 diff chart formats in a folder LOL + + var files:Array = []; + var diffSuffix:String = getDifficultyFileSuffix(chartId); + if (diffSuffix != '') files.push(songId + diffSuffix); + files.push(songId); + + for (ext in moonchartExtensions) { + for (input in files) { + var filePath:String = getSongFile('$input.$ext'); + var fileFormat:Null = findFormat([filePath]); + + switch(fileFormat) { + case null: + continue; + + case FNF_LEGACY_PSYCH | FNF_LEGACY | "FNF_TROLL": + return parseSongJson(filePath); + + default: + trace('Converting from format $fileFormat!'); + + var formatInfo:Null = FormatDetector.getFormatData(fileFormat); + var chart:moonchart.formats.BasicFormat<{}, {}>; + chart = cast Type.createInstance(formatInfo.handler, []); + chart = chart.fromFile(filePath); + + if (chart.formatMeta.supportsDiffs && !chart.diffs.contains(chartId)) + continue; + + var converted = new SupportedFormat().fromFormat(chart, chartId); + var chart:JsonSong = cast converted.data.song; + chart.path = filePath; + chart.song = songId; + return onLoadJson(chart); + } + } + } + + return null; + #end + } + + // + function get_charts() + return charts ?? (charts = Song.getCharts(this)); + + function get_songPath() + return songPath #if PE_MOD_COMPATIBILITY ?? defaultSongPath #end; //// @@ -182,11 +331,11 @@ class Song { Paths.currentModDirectory = song.folder; - #if USING_MOONCHART - final songName = Paths.formatToSongPath(song.songName); + final songId:String = song.songId; + final charts:Map = []; + #if USING_MOONCHART var folder:String = ''; - var charts:Map = []; function processFileName(unprocessedName:String) { var fileName:String = unprocessedName.toLowerCase(); @@ -200,12 +349,12 @@ class Song switch (fileFormat) { case FNF_LEGACY_PSYCH | FNF_LEGACY: - if (fileName == '$songName.json') { + if (fileName == '$songId.json') { charts.set("normal", true); return; } - else if (fileName.startsWith('$songName-')) { - final extension_dot = songName.length + 1; + else if (fileName.startsWith('$songId-')) { + final extension_dot = songId.length + 1; charts.set(fileName.substr(extension_dot, fileName.length - extension_dot - 5), true); return; } @@ -221,11 +370,11 @@ class Song }else{ var woExtension:String = Path.withoutExtension(filePath); - if (woExtension == songName){ + if (woExtension == songId){ charts.set("normal", true); return; } - if (woExtension.startsWith('$songName-')){ + if (woExtension.startsWith('$songId-')){ var split = woExtension.split("-"); split.shift(); var diff = split.join("-"); @@ -241,7 +390,7 @@ class Song } if (song.folder == "") { - folder = Paths.getPreloadPath('songs/$songName/'); + folder = Paths.getPreloadPath('songs/$songId/'); Paths.iterateDirectory(folder, processFileName); } #if MODS_ALLOWED @@ -250,7 +399,7 @@ class Song var spoon:Array = []; var crumb:Array = []; - folder = Paths.mods('${song.folder}/songs/$songName/'); + folder = Paths.mods('${song.folder}/songs/$songId/'); Paths.iterateDirectory(folder, (fileName)->{ if (isAMoonchartRecognizedFile(fileName)){ spoon.push(folder+fileName); @@ -260,8 +409,8 @@ class Song var ALL_FILES_DETECTED_FORMAT = findFormat(spoon); if (ALL_FILES_DETECTED_FORMAT == FNF_VSLICE) { - var chartsFilePath:String = folder + songName + '-chart.json'; - var metadataPath:String = folder + songName + '-metadata.json'; + var chartsFilePath:String = folder + songId + '-chart.json'; + var metadataPath:String = folder + songId + '-metadata.json'; var chart = new moonchart.formats.fnf.FNFVSlice().fromFile(chartsFilePath, metadataPath); for (diff in chart.diffs) charts.set(diff, true); @@ -271,88 +420,57 @@ class Song //// #if PE_MOD_COMPATIBILITY - folder = Paths.mods('${song.folder}/data/$songName/'); + folder = Paths.mods('${song.folder}/data/$songId/'); Paths.iterateDirectory(folder, processFileName); #end } #end var allCharts:Array = [for (name in charts.keys()) name]; - var allChartsLower:Array = [for (name in charts.keys()) name.toLowerCase()]; var chartNames:Array = []; - if (song.difficulties.length > 0){ - for(diff in song.difficulties){ - if (allChartsLower.contains(diff)){ - var index = allChartsLower.indexOf(diff); - chartNames.push(diff); - allCharts.splice(index, 1); - allChartsLower.remove(diff); - } - } - } - for (name in allCharts) chartNames.push(name); return chartNames; #else - final songName = Paths.formatToSongPath(song.songName); - final charts = new haxe.ds.StringMap(); function processFileName(unprocessedName:String) { var fileName:String = unprocessedName.toLowerCase(); - if (fileName == '$songName.json'){ + if (fileName == '$songId.json'){ charts.set("normal", true); return; } - else if (!fileName.startsWith('$songName-') || !fileName.endsWith('.json')){ + else if (!fileName.startsWith('$songId-') || !fileName.endsWith('.json')){ return; } - final extension_dot = songName.length + 1; + final extension_dot = songId.length + 1; charts.set(fileName.substr(extension_dot, fileName.length - extension_dot - 5), true); } - - if (song.folder == "") - { - #if PE_MOD_COMPATIBILITY - Paths.iterateDirectory(Paths.getPreloadPath('data/$songName/'), processFileName); - #end - Paths.iterateDirectory(Paths.getPreloadPath('songs/$songName/'), processFileName); - } - #if MODS_ALLOWED - else - { - #if PE_MOD_COMPATIBILITY - Paths.iterateDirectory(Paths.mods('${song.folder}/data/$songName/'), processFileName); - #end - Paths.iterateDirectory(Paths.mods('${song.folder}/songs/$songName/'), processFileName); - } + var contentPath = Paths.getFolderPath(song.folder); + #if PE_MOD_COMPATIBILITY + Paths.iterateDirectory('$contentPath/data/$songId/', processFileName); #end + Paths.iterateDirectory('$contentPath/songs/$songId/', processFileName); return [for (name in charts.keys()) name]; #end } - public static function loadFromJson(jsonInput:String, folder:String, ?isSongJson:Bool = true):Null - { - var path:String = Paths.formatToSongPath(folder) + '/' + Paths.formatToSongPath(jsonInput) + '.json'; - var fullPath = Paths.getPath('songs/$path', false); - - #if PE_MOD_COMPATIBILITY - if (!Paths.exists(fullPath)) - fullPath = Paths.getPath('data/$path', false); - #end + // TODO: GEt rid of this, just save the charts as "-normal" grrrr + public inline static function getDifficultyFileSuffix(diff:String) { + diff = Paths.formatToSongPath(diff); + return (diff=="" || diff=="normal") ? "" : '-$diff'; + } + + private static function _parseSongJson(filePath:String, isChartJson:Bool = true):SwagSong { + var rawJson:Null = Paths.getContent(filePath); + if (rawJson == null) + throw 'song JSON file NOT FOUND: $filePath'; - var rawJson:Null = Paths.getContent(fullPath); - if (rawJson == null){ - trace('song JSON file not found: $path'); - return null; - } - // LOL GOING THROUGH THE BULLSHIT TO CLEAN IDK WHATS STRANGE rawJson = rawJson.trim(); while (!rawJson.endsWith("}")) @@ -360,7 +478,7 @@ class Song var uncastedJson:Dynamic = Json.parse(rawJson); var songJson:JsonSong; - if (uncastedJson.song is String){ + if (isChartJson && uncastedJson.song is String){ // PSYCH 1.0 FUCKING DUMBSHIT FIX IT RETARD // why did shadowmario make such a useless format change oh my god :sob: @@ -374,13 +492,33 @@ class Song note[2] = note[2] > 0 ? note[2] : 0; } } - }else songJson = cast uncastedJson.song; - songJson.path = fullPath; + songJson.path = filePath; + return isChartJson ? onLoadJson(songJson) : onLoadEvents(songJson); + } + + private static function parseSongJson(filePath:String, isChartJson:Bool = true):Null { + try { + return _parseSongJson(filePath, isChartJson); + }catch(e) { + trace('ERROR parsing song JSON: $filePath', e.message); + return null; + } + } + + public static function loadFromJson(jsonInput:String, folder:String, isChartJson:Bool = true):Null + { + var path:String = Paths.formatToSongPath(folder) + '/' + Paths.formatToSongPath(jsonInput) + '.json'; + var fullPath = Paths.getPath('songs/$path', false); + + #if PE_MOD_COMPATIBILITY + if (!Paths.exists(fullPath)) + fullPath = Paths.getPath('data/$path', false); + #end - return isSongJson ? onLoadJson(songJson) : onLoadEvents(songJson); + return parseSongJson(fullPath); } public static function onLoadEvents(songJson:SwagSong) { @@ -589,136 +727,29 @@ class Song return resultArray; } - static public function loadSong(toPlay:Song, ?difficulty:String, ?difficultyIdx:Int = 1) { + static public function loadSong(toPlay:Song, ?difficulty:String) { Paths.currentModDirectory = toPlay.folder; - var songLowercase:String = Paths.formatToSongPath(toPlay.songName); - var diffSuffix:String; - - var rawDifficulty:String = difficulty; - - if (difficulty == null || difficulty == "") { + if (difficulty == "") { + difficulty = "normal"; + } + else if (difficulty == null) { if (toPlay.charts.contains("normal")) difficulty = "normal"; else difficulty = toPlay.charts[0]; } - - if (difficulty == "normal") { - difficulty = 'normal'; - diffSuffix = ''; - }else{ - difficulty = difficulty.trim().toLowerCase(); - diffSuffix = '-$difficulty'; - } - + if (Main.showDebugTraces) trace('loadSong', toPlay, difficulty); - - #if USING_MOONCHART - var SONG:Null = null; - inline function findVSlice():Bool { - // less strict v-slice format detection - var sowy = 'songs/$songLowercase/$songLowercase'; - var basePath:String; - - if (toPlay.folder == "") - basePath = Paths.getPreloadPath(sowy); - else - basePath = Paths.mods(toPlay.folder + '/' + sowy); - - var chartsFilePath = '$basePath-chart.json'; - var metadataPath = '$basePath-metadata.json'; - - var found:Bool = false; - if (Paths.exists(chartsFilePath) && Paths.exists(metadataPath)) { - var chart = new moonchart.formats.fnf.FNFVSlice().fromFile(chartsFilePath, metadataPath); - if (chart.diffs.contains(rawDifficulty)) { - trace("CONVERTING FROM VSLICE"); - - var converted = new SupportedFormat().fromFormat(chart, rawDifficulty); - var chart:JsonSong = cast converted.data.song; - chart.path = chartsFilePath; - chart.song = songLowercase; - chart.tracks = null; - SONG = onLoadJson(chart); - found = true; - }else{ - trace('VSLICE FILES DO NOT CONTAIN DIFFICULTY: $rawDifficulty'); - } - } - - return found; - } - - if (!findVSlice()) { - // TODO: scan through the song folder and look for the first thing that has a supported extension (if json then check if it has diffSuffix cus FNF formats!!) - // Or dont since this current method lets you do a dumb thing AKA have 2 diff chart formats in a folder LOL - - var files:Array = []; - if (diffSuffix != '') files.push(songLowercase + diffSuffix); - files.push(songLowercase); - - for (ext in moonchartExtensions) { - for (input in files) { - var path:String = Paths.formatToSongPath(songLowercase) + '/' + Paths.formatToSongPath(input) + '.' + ext; - var filePath:String = Paths.getPath("songs/" + path); - var fileFormat:Format = findFormat([filePath]); - - #if PE_MOD_COMPATIBILITY - if (fileFormat == null){ - filePath = Paths.getPath("data/" + path); - fileFormat = findFormat([filePath]); - } - #end - - if (fileFormat == null) continue; - var formatInfo:Null = FormatDetector.getFormatData(fileFormat); - - SONG = switch(fileFormat) { - case FNF_LEGACY_PSYCH | FNF_LEGACY | "FNF_TROLL": - Song.loadFromJson(songLowercase + diffSuffix, songLowercase); - - default: - trace('Converting from format $fileFormat!'); - - var chart:moonchart.formats.BasicFormat<{}, {}>; - chart = cast Type.createInstance(formatInfo.handler, []); - chart = chart.fromFile(filePath); - - if (chart.formatMeta.supportsDiffs && !chart.diffs.contains(rawDifficulty)) - continue; - - var converted = new SupportedFormat().fromFormat(chart, rawDifficulty); - var chart:JsonSong = cast converted.data.song; - chart.path = filePath; - chart.song = songLowercase; - onLoadJson(chart); - } - - break; - } - if (SONG != null) - break; - } - } - - if (SONG == null) { - PlayState.SONG = null; - - // Find a better way to show the error to the user - trace("No file format found for the chart!"); - return; - } - #else - var SONG:SwagSong = Song.loadFromJson(songLowercase + diffSuffix, songLowercase); - #end - - PlayState.SONG = SONG; - PlayState.difficulty = difficultyIdx; + PlayState.SONG = toPlay.getSwagSong(difficulty); + PlayState.difficulty = toPlay.charts.indexOf(difficulty); PlayState.difficultyName = difficulty; - PlayState.isStoryMode = false; + PlayState.isStoryMode = false; + + PlayState.songPlaylist = [toPlay]; + PlayState.songPlaylistIdx = 0; } static public function switchToPlayState() @@ -729,9 +760,9 @@ class Song LoadingState.loadAndSwitchState(new PlayState()); } - static public function playSong(song:Song, ?difficulty:String, ?difficultyIdx:Int = 1) + static public function playSong(song:Song, ?difficulty:String) { - loadSong(song, difficulty, difficultyIdx); + loadSong(song, difficulty); switchToPlayState(); } } \ No newline at end of file diff --git a/source/funkin/states/FreeplayState.hx b/source/funkin/states/FreeplayState.hx index 5cde8c83..9551e909 100644 --- a/source/funkin/states/FreeplayState.hx +++ b/source/funkin/states/FreeplayState.hx @@ -17,7 +17,7 @@ class FreeplayState extends MusicBeatState public static var comingFromPlayState:Bool = false; var menu = new AlphabetMenu(); - var songMeta:Array = []; + var songData:Array = []; var bgGrp = new FlxTypedGroup(); var bg:FlxSprite; @@ -55,17 +55,18 @@ class FreeplayState extends MusicBeatState continue; for (songName in week.songs){ - var metadata:Song = {songName: songName, folder: week.directory, difficulties: week.difficulties != null ? week.difficulties : []}; + var song = new Song( + Paths.formatToSongPath(songName), + week.directory + ); - /* - if (metadata.charts.length == 0){ - trace('${week.directory}: $songName doesn\'t have any available charts!'); + if (Main.showDebugTraces && song.charts.length == 0) { + trace('"$song" doesn\'t have any available charts!'); continue; } - */ - menu.addTextOption(songName.replace("-", " ").capitalize()).ID = songMeta.length; - songMeta.push(metadata); + menu.addTextOption(song.getMetadata().songName).ID = songData.length; + songData.push(song); } } @@ -74,7 +75,7 @@ class FreeplayState extends MusicBeatState add(menu); menu.controls = controls; - menu.callbacks.onSelect = (selectedIdx, _) -> onSelectSong(songMeta[selectedIdx]); + menu.callbacks.onSelect = (selectedIdx, _) -> onSelectSong(songData[selectedIdx]); menu.callbacks.onAccept = (_, _) -> onAccept(); //// @@ -129,7 +130,7 @@ class FreeplayState extends MusicBeatState proceed = songLoaded == selectedSong && PlayState.SONG != null; if (!proceed) { - Song.loadSong(selectedSongData, curDiffStr, curDiffIdx); + Song.loadSong(selectedSongData, curDiffStr); proceed = PlayState.SONG != null; } } @@ -154,7 +155,7 @@ class FreeplayState extends MusicBeatState // load song json and play inst if (songLoaded != selectedSong){ songLoaded = selectedSong; - Song.loadSong(selectedSongData, curDiffStr, curDiffIdx); + Song.loadSong(selectedSongData, curDiffStr); if (PlayState.SONG != null){ var instAsset = Paths.track(PlayState.SONG.song, PlayState.SONG.tracks.inst[0]); @@ -194,7 +195,7 @@ class FreeplayState extends MusicBeatState MusicBeatState.switchState(new funkin.states.MainMenuState()); }else if (controls.RESET){ - var songName:String = selectedSongData.songName; + var songName:String = selectedSongData.songId; var _dStrId:String = 'difficultyName_$curDiffStr'; var diffName:String = Paths.getString(_dStrId, curDiffStr); @@ -233,7 +234,7 @@ class FreeplayState extends MusicBeatState function refreshScore() { var data = selectedSongData; - var record = Highscore.getRecord(data.songName, curDiffStr); + var record = Highscore.getRecord(data.songId, curDiffStr); targetRating = Highscore.getRatingRecord(record) * 100; if(ClientPrefs.showWifeScore) diff --git a/source/funkin/states/PlayState.hx b/source/funkin/states/PlayState.hx index 193121b3..50246e46 100644 --- a/source/funkin/states/PlayState.hx +++ b/source/funkin/states/PlayState.hx @@ -115,6 +115,9 @@ class PlayState extends MusicBeatState public static var songPlaylist:Array = []; public static var songPlaylistIdx = 0; + private static var song(get, never):Song; + private static function get_song() return songPlaylist[songPlaylistIdx]; + public static var difficulty:Int = 1; // for psych mod shit public static var difficultyName:String = 'normal'; // should NOT be set to "" when playing normal diff!!!!! @@ -637,10 +640,10 @@ class PlayState extends MusicBeatState Conductor.changeBPM(SONG.bpm); Conductor.songPosition = Conductor.crochet * -5; - songName = Paths.formatToSongPath(SONG.song); - songHighscore = Highscore.getScore(SONG.song, difficultyName); + songName = (song?.songId) ?? Paths.formatToSongPath(SONG.song); + songHighscore = Highscore.getScore(songName, difficultyName); - metadata = SONG.metadata ?? Paths.json('songs/$songName/metadata.json'); + metadata = SONG.metadata ?? (song?.getMetadata(difficultyName)); if (showDebugTraces && metadata == null) trace('No metadata for $songName. Maybe add some?'); @@ -1035,7 +1038,7 @@ class PlayState extends MusicBeatState var stringId:String = 'difficultyName_$difficultyName'; displayedDifficulty = Paths.getString(stringId, difficultyName.replace("-"," ").capitalize()); - displayedSong = SONG.song.replace("-"," ").capitalize(); + displayedSong = metadata?.songName ?? SONG.song.replace("-"," ").capitalize(); #if DISCORD_ALLOWED // Discord RPC texts @@ -1707,7 +1710,13 @@ class PlayState extends MusicBeatState //// for (trackName in songTrackNames) { - var newTrack = new FlxSound().loadEmbedded(Paths.track(PlayState.SONG.song, trackName)); + var sndAsset = { + if (song != null) + Paths.returnSound(song.getSongFile(trackName) + ".ogg"); + else + Paths.track(PlayState.SONG.song, trackName); + } + var newTrack = new FlxSound().loadEmbedded(sndAsset); //newTrack.volume = 0.0; newTrack.pitch = playbackRate; newTrack.filter = sndFilter; diff --git a/source/funkin/states/SongSelectState.hx b/source/funkin/states/SongSelectState.hx index f126fafa..c6ba708b 100644 --- a/source/funkin/states/SongSelectState.hx +++ b/source/funkin/states/SongSelectState.hx @@ -118,7 +118,7 @@ class SongSelectState extends MusicBeatState hPadding + (Math.floor(id/verticalLimit) * width), vPadding + (ySpace*(id%verticalLimit)), width, - songMeta[id].songName, + songMeta[id].songId, textSize ); text.wordWrap = false; @@ -194,7 +194,7 @@ class SongSelectState extends MusicBeatState if (charts.length > 1) MusicBeatState.switchState(new SongChartSelec(songMeta[curSel], charts)); else if (charts.length > 0) { - Song.loadSong(songMeta[curSel], charts[0], 0); + Song.loadSong(songMeta[curSel], charts[0]); if (FlxG.keys.pressed.SHIFT) LoadingState.loadAndSwitchState(new funkin.states.editors.ChartingState()); else @@ -241,7 +241,7 @@ class SongChartSelec extends MusicBeatState override function create() { - add(new FlxText(0, 5, FlxG.width, songMeta.songName).setFormat(null, 20, 0xFFFFFFFF, CENTER)); + add(new FlxText(0, 5, FlxG.width, songMeta.songId).setFormat(null, 20, 0xFFFFFFFF, CENTER)); for (id in 0...alts.length){ var alt = alts[id]; @@ -267,8 +267,8 @@ class SongChartSelec extends MusicBeatState if (controls.BACK) MusicBeatState.switchState(new FreeplayState()); else if (controls.ACCEPT){ - var daDiff = alts[curSel]; - Song.loadSong(songMeta, (daDiff=="normal") ? null : daDiff, curSel); + Song.loadSong(songMeta, alts[curSel]); + if (FlxG.keys.pressed.SHIFT) LoadingState.loadAndSwitchState(new funkin.states.editors.ChartingState()); else