From 038d2582330b0edcbc82cc0be61da3d896a6edab Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 9 Jun 2023 15:28:14 -0400 Subject: [PATCH] Chart editor changes (support for legacy import) --- source/funkin/PauseSubState.hx | 2 +- source/funkin/play/song/Song.hx | 2 +- source/funkin/play/song/SongData.hx | 4 +- source/funkin/play/song/SongMigrator.hx | 63 +++++++++++-------- source/funkin/play/song/SongSerializer.hx | 8 +-- source/funkin/play/song/formats/FNFLegacy.hx | 4 +- .../charting/ChartEditorDialogHandler.hx | 2 +- .../ui/debug/charting/ChartEditorState.hx | 4 +- .../charting/ChartEditorToolboxHandler.hx | 4 +- 9 files changed, 52 insertions(+), 41 deletions(-) diff --git a/source/funkin/PauseSubState.hx b/source/funkin/PauseSubState.hx index 7349052aa..77fdfabf1 100644 --- a/source/funkin/PauseSubState.hx +++ b/source/funkin/PauseSubState.hx @@ -225,7 +225,7 @@ class PauseSubState extends MusicBeatSubState if (PlayStatePlaylist.isStoryMode) openSubState(new funkin.ui.StickerSubState(null, STORY)); else - openSubState(new funkin.ui.StickerSubState()); + openSubState(new funkin.ui.StickerSubState(null, FREEPLAY)); } } diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 7de005cb0..22b5e8f07 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -47,7 +47,7 @@ class Song implements IPlayStateScriptedClass difficultyIds = []; difficulties = new Map(); - _metadata = SongDataParser.parseSongMetadata(songId); + _metadata = SongDataParser.loadSongMetadata(songId); if (_metadata == null || _metadata.length == 0) { throw 'Could not find song data for songId: $songId'; diff --git a/source/funkin/play/song/SongData.hx b/source/funkin/play/song/SongData.hx index 2ae38156a..a6d19454f 100644 --- a/source/funkin/play/song/SongData.hx +++ b/source/funkin/play/song/SongData.hx @@ -377,7 +377,7 @@ abstract SongNoteData(RawSongNoteData) function get_stepTime():Float { // TODO: Account for changes in BPM. - return this.t / Conductor.stepLengthMs; + return this.t / Conductor.stepCrochet; } /** @@ -563,7 +563,7 @@ abstract SongEventData(RawSongEventData) function get_stepTime():Float { // TODO: Account for changes in BPM. - return this.t / Conductor.stepLengthMs; + return this.t / Conductor.stepCrochet; } public var event(get, set):String; diff --git a/source/funkin/play/song/SongMigrator.hx b/source/funkin/play/song/SongMigrator.hx index 05adf2457..81500406d 100644 --- a/source/funkin/play/song/SongMigrator.hx +++ b/source/funkin/play/song/SongMigrator.hx @@ -103,11 +103,28 @@ class SongMigrator * @param songId The ID of the song (only used for error reporting). * @return The migrated song metadata, or null if the migration failed. */ - public static function migrateSongMetadataFromLegacy(jsonData:Dynamic):SongMetadata + public static function migrateSongMetadataFromLegacy(jsonData:Dynamic, difficulty:String = 'normal'):SongMetadata { trace('Migrating song metadata from FNF Legacy.'); var songData:FNFLegacy = cast jsonData; + // Some cleanup + if (Std.isOfType(jsonData.song.notes, Array)) + { + jsonData.song.notes = haxe.ds.Either.Left(jsonData.song.notes); + } + else + { + jsonData.song.notes = haxe.ds.Either.Right(jsonData.song.notes); + } + if (Std.isOfType(jsonData.song.speed, Float)) + { + jsonData.song.speed = haxe.ds.Either.Left(jsonData.song.speed); + } + else + { + jsonData.song.speed = haxe.ds.Either.Right(jsonData.song.speed); + } var songMetadata:SongMetadata = new SongMetadata('Import', 'Kawai Sprite', 'default'); @@ -152,9 +169,20 @@ class SongMigrator songMetadata.playData.difficulties = []; if (songData.song != null && songData.song.notes != null) { - if (songData.song.notes.easy != null) songMetadata.playData.difficulties.push('easy'); - if (songData.song.notes.normal != null) songMetadata.playData.difficulties.push('normal'); - if (songData.song.notes.hard != null) songMetadata.playData.difficulties.push('hard'); + if (Std.isOfType(songData.song.notes, Array)) + { + // One difficulty of notes. + songMetadata.playData.difficulties.push(difficulty); + } + else + { + // Multiple difficulties of notes. + var songNoteDataDynamic:haxe.DynamicAccess = cast songData.song.notes; + for (difficultyKey in songNoteDataDynamic.keys()) + { + songMetadata.playData.difficulties.push(difficultyKey); + } + } } else { @@ -186,7 +214,7 @@ class SongMigrator * @param difficulty The difficulty to migrate. * @return The migrated song chart data, or null if the migration failed. */ - public static function migrateSongChartDataFromLegacy(jsonData:Dynamic):SongChartData + public static function migrateSongChartDataFromLegacy(jsonData:Dynamic, difficulty:String = 'normal'):SongChartData { trace('Migrating song chart data from FNF Legacy.'); @@ -194,27 +222,10 @@ class SongMigrator var songChartData:SongChartData = new SongChartData(1.0, [], []); - if (songData.song.notes.normal != null) - { - var songEventsEmpty:Bool = songChartData.getEvents() == null || songChartData.getEvents().length == 0; - if (songEventsEmpty) songChartData.setEvents(migrateSongEventDataFromLegacy(songData.song.notes.normal)); - songChartData.setNotes(migrateSongNoteDataFromLegacy(songData.song.notes.normal), 'normal'); - songChartData.setScrollSpeed(songData.song.speed.normal, 'normal'); - } - if (songData.song.notes.easy != null) - { - var songEventsEmpty:Bool = songChartData.getEvents() == null || songChartData.getEvents().length == 0; - if (songEventsEmpty) songChartData.setEvents(migrateSongEventDataFromLegacy(songData.song.notes.easy)); - songChartData.setNotes(migrateSongNoteDataFromLegacy(songData.song.notes.easy), 'easy'); - songChartData.setScrollSpeed(songData.song.speed.easy, 'easy'); - } - if (songData.song.notes.hard != null) - { - var songEventsEmpty:Bool = songChartData.getEvents() == null || songChartData.getEvents().length == 0; - if (songEventsEmpty) songChartData.setEvents(migrateSongEventDataFromLegacy(songData.song.notes.hard)); - songChartData.setNotes(migrateSongNoteDataFromLegacy(songData.song.notes.hard), 'hard'); - songChartData.setScrollSpeed(songData.song.speed.hard, 'hard'); - } + var songEventsEmpty:Bool = songChartData.getEvents() == null || songChartData.getEvents().length == 0; + if (songEventsEmpty) songChartData.setEvents(migrateSongEventDataFromLegacy(songData.song.notes)); + songChartData.setNotes(migrateSongNoteDataFromLegacy(songData.song.notes), difficulty); + songChartData.setScrollSpeed(songData.song.speed, difficulty); return songChartData; } diff --git a/source/funkin/play/song/SongSerializer.hx b/source/funkin/play/song/SongSerializer.hx index 968a7a1f5..a08b722da 100644 --- a/source/funkin/play/song/SongSerializer.hx +++ b/source/funkin/play/song/SongSerializer.hx @@ -82,9 +82,9 @@ class SongSerializer * Save a SongChartData object as a JSON file to an automatically generated path. * Works great on HTML5 and desktop. */ - public static function exportSongChartData(data:SongChartData) + public static function exportSongChartData(data:SongChartData, songId:String) { - var path = 'chart.json'; + var path = '${songId}-chart.json'; exportSongChartDataAs(path, data); } @@ -92,9 +92,9 @@ class SongSerializer * Save a SongMetadata object as a JSON file to an automatically generated path. * Works great on HTML5 and desktop. */ - public static function exportSongMetadata(data:SongMetadata) + public static function exportSongMetadata(data:SongMetadata, songId:String) { - var path = 'metadata.json'; + var path = '${songId}-metadata.json'; exportSongMetadataAs(path, data); } diff --git a/source/funkin/play/song/formats/FNFLegacy.hx b/source/funkin/play/song/formats/FNFLegacy.hx index 51dc602f3..a64e461bd 100644 --- a/source/funkin/play/song/formats/FNFLegacy.hx +++ b/source/funkin/play/song/formats/FNFLegacy.hx @@ -10,10 +10,10 @@ typedef LegacySongData = var player1:String; // Boyfriend var player2:String; // Opponent - var speed:LegacyScrollSpeeds; + var speed:Float; var stageDefault:String; var bpm:Float; - var notes:LegacyNoteData; + var notes:Array; var song:String; // Song name }; diff --git a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx index 4044df5d8..ec1b0754d 100644 --- a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx @@ -601,7 +601,7 @@ class ChartEditorDialogHandler { trace('Adding vocal upload for character ${charKey}'); var charMetadata:CharacterData = CharacterDataParser.fetchCharacterData(charKey); - var charName:String = charMetadata.name; + var charName:String = charMetadata != null ? charMetadata.name : charKey; var vocalsEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_UPLOAD_VOCALS_ENTRY_LAYOUT); diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 173e64d24..0769ee800 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -3367,10 +3367,10 @@ class ChartEditorState extends HaxeUIState audioVocalTrackGroup.clear(); } // Add player vocals. - if (currentSongCharacterPlayer != null) audioVocalTrackGroup.addPlayerVocals(new FlxSound().loadEmbedded(Assets.getSound(Paths.voices(songId, + if (currentSongCharacterPlayer != null) audioVocalTrackGroup.addPlayerVoice(new FlxSound().loadEmbedded(Assets.getSound(Paths.voices(songId, '-$currentSongCharacterPlayer')))); // Add opponent vocals. - if (currentSongCharacterOpponent != null) audioVocalTrackGroup.addOpponentVocals(new FlxSound().loadEmbedded(Assets.getSound(Paths.voices(songId, + if (currentSongCharacterOpponent != null) audioVocalTrackGroup.addOpponentVoice(new FlxSound().loadEmbedded(Assets.getSound(Paths.voices(songId, '-$currentSongCharacterOpponent')))); postLoadInstrumental(); diff --git a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx index 9f976df6b..6784b9cfc 100644 --- a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx @@ -374,11 +374,11 @@ class ChartEditorToolboxHandler var difficultyToolboxLoadChart:Button = toolbox.findComponent('difficultyToolboxLoadChart', Button); difficultyToolboxSaveMetadata.onClick = function(event:UIEvent) { - SongSerializer.exportSongMetadata(state.currentSongMetadata); + SongSerializer.exportSongMetadata(state.currentSongMetadata, state); }; difficultyToolboxSaveChart.onClick = function(event:UIEvent) { - SongSerializer.exportSongChartData(state.currentSongChartData); + SongSerializer.exportSongChartData(state.currentSongChartData, state); }; difficultyToolboxSaveAll.onClick = function(event:UIEvent) {