diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 73ecbce14..bba5f899f 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -898,20 +898,26 @@ class SongNoteDataRaw implements ICloneable /** * The kind of the note. * This can allow the note to include information used for custom behavior. - * Defaults to blank or `Constants.DEFAULT_DIFFICULTY`. + * Defaults to `null` for no kind. */ @:alias("k") - @:default("normal") @:optional - public var kind(get, default):String = ''; + @:isVar + public var kind(get, set):Null = null; - function get_kind():String + function get_kind():Null { - if (this.kind == null || this.kind == '') return 'normal'; + if (this.kind == null || this.kind == '') return null; return this.kind; } + function set_kind(value:Null):Null + { + if (value == '') value = null; + return this.kind = value; + } + public function new(time:Float, data:Int, length:Float = 0, kind:String = '') { this.time = time; @@ -1061,13 +1067,13 @@ abstract SongNoteData(SongNoteDataRaw) from SongNoteDataRaw to SongNoteDataRaw if (this == null) return other == null; if (other == null) return false; - if (this.kind == '') + if (this.kind == null || this.kind == '') { - if (other.kind != '' && other.kind != 'normal') return false; + if (other.kind != '' && this.kind != null) return false; } else { - if (other.kind == '' || other.kind != this.kind) return false; + if (other.kind == '' || this.kind == null) return false; } return this.time == other.time && this.data == other.data && this.length == other.length; @@ -1082,11 +1088,11 @@ abstract SongNoteData(SongNoteDataRaw) from SongNoteDataRaw to SongNoteDataRaw if (this.kind == '') { - if (other.kind != '' && other.kind != 'normal') return true; + if (other.kind != '') return true; } else { - if (other.kind == '' || other.kind != this.kind) return true; + if (other.kind == '') return true; } return this.time != other.time || this.data != other.data || this.length != other.length; diff --git a/source/funkin/data/song/SongDataUtils.hx b/source/funkin/data/song/SongDataUtils.hx index 01ea2da32..7f3b01eb4 100644 --- a/source/funkin/data/song/SongDataUtils.hx +++ b/source/funkin/data/song/SongDataUtils.hx @@ -210,14 +210,13 @@ class SongDataUtils */ public static function writeItemsToClipboard(data:SongClipboardItems):Void { - var writer = new json2object.JsonWriter(); + var ignoreNullOptionals = true; + var writer = new json2object.JsonWriter(ignoreNullOptionals); var dataString:String = writer.write(data, ' '); ClipboardUtil.setClipboard(dataString); trace('Wrote ' + data.notes.length + ' notes and ' + data.events.length + ' events to clipboard.'); - - trace(dataString); } /** diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 66e8e0dcc..b1d075de4 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -702,7 +702,7 @@ class PlayState extends MusicBeatSubState function assertChartExists():Bool { // Returns null if the song failed to load or doesn't have the selected difficulty. - if (currentSong == null || currentChart == null) + if (currentSong == null || currentChart == null || currentChart.notes == null) { // We have encountered a critical error. Prevent Flixel from trying to run any gameplay logic. criticalFailure = true; @@ -721,6 +721,10 @@ class PlayState extends MusicBeatSubState { message = 'The was a critical error retrieving data for this song on "$currentDifficulty" difficulty with variation "$currentVariation". Click OK to return to the main menu.'; } + else if (currentChart.notes == null) + { + message = 'The was a critical error retrieving note data for this song on "$currentDifficulty" difficulty with variation "$currentVariation". Click OK to return to the main menu.'; + } // Display a popup. This blocks the application until the user clicks OK. lime.app.Application.current.window.alert(message, 'Error loading PlayState'); diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 6c64f952b..48a6e70c9 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -162,8 +162,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState public static final CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT:String = Paths.ui('chart-editor/toolbox/opponent-preview'); public static final CHART_EDITOR_TOOLBOX_METADATA_LAYOUT:String = Paths.ui('chart-editor/toolbox/metadata'); public static final CHART_EDITOR_TOOLBOX_OFFSETS_LAYOUT:String = Paths.ui('chart-editor/toolbox/offsets'); - public static final CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT:String = Paths.ui('chart-editor/toolbox/notedata'); - public static final CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT:String = Paths.ui('chart-editor/toolbox/eventdata'); + public static final CHART_EDITOR_TOOLBOX_NOTE_DATA_LAYOUT:String = Paths.ui('chart-editor/toolbox/note-data'); + public static final CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT:String = Paths.ui('chart-editor/toolbox/event-data'); public static final CHART_EDITOR_TOOLBOX_FREEPLAY_LAYOUT:String = Paths.ui('chart-editor/toolbox/freeplay'); public static final CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT:String = Paths.ui('chart-editor/toolbox/playtest-properties'); @@ -538,9 +538,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Tools Status /** - * The note kind to use for notes being placed in the chart. Defaults to `''`. + * The note kind to use for notes being placed in the chart. Defaults to `null`. */ - var noteKindToPlace:String = ''; + var noteKindToPlace:Null = null; /** * The event type to use for events being placed in the chart. Defaults to `''`. @@ -2458,11 +2458,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState */ override public function draw():Void { - if (selectionBoxStartPos != null) - { - trace('selectionBoxSprite: ${selectionBoxSprite.visible} ${selectionBoxSprite.exists} ${this.members.contains(selectionBoxSprite)}'); - } - super.draw(); } @@ -2968,7 +2963,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState menubarItemToggleToolboxDifficulty.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT, event.value); menubarItemToggleToolboxMetadata.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT, event.value); menubarItemToggleToolboxOffsets.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_OFFSETS_LAYOUT, event.value); - menubarItemToggleToolboxNotes.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT, event.value); + menubarItemToggleToolboxNoteData.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_NOTE_DATA_LAYOUT, event.value); menubarItemToggleToolboxEventData.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT, event.value); menubarItemToggleToolboxFreeplay.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_FREEPLAY_LAYOUT, event.value); menubarItemToggleToolboxPlaytestProperties.onChange = event -> this.setToolboxState(CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT, event.value); @@ -5286,6 +5281,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { FlxG.watch.addQuick('musicTime', audioInstTrack?.time ?? 0.0); + FlxG.watch.addQuick('noteKindToPlace', noteKindToPlace); + FlxG.watch.addQuick('eventKindToPlace', eventKindToPlace); + FlxG.watch.addQuick('scrollPosInPixels', scrollPositionInPixels); FlxG.watch.addQuick('playheadPosInPixels', playheadPositionInPixels); diff --git a/source/funkin/ui/debug/charting/commands/SelectItemsCommand.hx b/source/funkin/ui/debug/charting/commands/SelectItemsCommand.hx index d6c5beeac..88f73cfed 100644 --- a/source/funkin/ui/debug/charting/commands/SelectItemsCommand.hx +++ b/source/funkin/ui/debug/charting/commands/SelectItemsCommand.hx @@ -59,6 +59,17 @@ class SelectItemsCommand implements ChartEditorCommand state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT); } + // If we just selected one or more notes (and no events), then we should make the note data toolbox display the note data for the selected note. + if (this.events.length == 0 && this.notes.length >= 1) + { + var noteSelected = this.notes[0]; + + state.noteKindToPlace = noteSelected.kind; + + // This code is here to parse note data that's not built as a struct for some reason. + state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_NOTE_DATA_LAYOUT); + } + state.noteDisplayDirty = true; state.notePreviewDirty = true; } diff --git a/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx b/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx index 35a00e562..5cc89e137 100644 --- a/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx +++ b/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx @@ -56,6 +56,16 @@ class SetItemSelectionCommand implements ChartEditorCommand state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT); } + // IF we just selected one or more notes (and no events), then we should make the note data toolbox display the note data for the selected note. + if (this.events.length == 0 && this.notes.length >= 1) + { + var noteSelected = this.notes[0]; + + state.noteKindToPlace = noteSelected.kind; + + state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_NOTE_DATA_LAYOUT); + } + state.noteDisplayDirty = true; } diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorToolboxHandler.hx index 9e22ba833..f32cc2bfb 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorToolboxHandler.hx @@ -38,6 +38,7 @@ import funkin.ui.debug.charting.toolboxes.ChartEditorMetadataToolbox; import funkin.ui.debug.charting.toolboxes.ChartEditorOffsetsToolbox; import funkin.ui.debug.charting.toolboxes.ChartEditorFreeplayToolbox; import funkin.ui.debug.charting.toolboxes.ChartEditorEventDataToolbox; +import funkin.ui.debug.charting.toolboxes.ChartEditorNoteDataToolbox; import funkin.ui.debug.charting.toolboxes.ChartEditorDifficultyToolbox; import haxe.ui.containers.Frame; import haxe.ui.containers.Grid; @@ -79,17 +80,16 @@ class ChartEditorToolboxHandler switch (id) { - case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT: - onShowToolboxNoteData(state, toolbox); + case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTE_DATA_LAYOUT: + cast(toolbox, ChartEditorBaseToolbox).refresh(); case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT: - // TODO: Fix this. + // TODO: Make these better. cast(toolbox, ChartEditorBaseToolbox).refresh(); case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT: onShowToolboxPlaytestProperties(state, toolbox); case ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT: cast(toolbox, ChartEditorBaseToolbox).refresh(); case ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT: - // TODO: Fix this. cast(toolbox, ChartEditorBaseToolbox).refresh(); case ChartEditorState.CHART_EDITOR_TOOLBOX_OFFSETS_LAYOUT: cast(toolbox, ChartEditorBaseToolbox).refresh(); @@ -124,10 +124,6 @@ class ChartEditorToolboxHandler switch (id) { - case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT: - onHideToolboxNoteData(state, toolbox); - case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT: - onHideToolboxEventData(state, toolbox); case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYTEST_PROPERTIES_LAYOUT: onHideToolboxPlaytestProperties(state, toolbox); case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT: @@ -196,7 +192,7 @@ class ChartEditorToolboxHandler var toolbox:Null = null; switch (id) { - case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT: + case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTE_DATA_LAYOUT: toolbox = buildToolboxNoteDataLayout(state); case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT: toolbox = buildToolboxEventDataLayout(state); @@ -262,58 +258,13 @@ class ChartEditorToolboxHandler static function buildToolboxNoteDataLayout(state:ChartEditorState):Null { - var toolbox:CollapsibleDialog = cast RuntimeComponentBuilder.fromAsset(ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT); + var toolbox:ChartEditorBaseToolbox = ChartEditorNoteDataToolbox.build(state); if (toolbox == null) return null; - // Starting position. - toolbox.x = 75; - toolbox.y = 100; - - toolbox.onDialogClosed = function(event:DialogEvent) { - state.menubarItemToggleToolboxNotes.selected = false; - } - - var toolboxNotesNoteKind:Null = toolbox.findComponent('toolboxNotesNoteKind', DropDown); - if (toolboxNotesNoteKind == null) throw 'ChartEditorToolboxHandler.buildToolboxNoteDataLayout() - Could not find toolboxNotesNoteKind component.'; - var toolboxNotesCustomKindLabel:Null