From 290c568cb5be0456741ed1c3acf7791389beeb24 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 Nov 2023 16:11:53 -0500 Subject: [PATCH 1/8] Disable notification actions while playtest is open. --- .../handlers/ChartEditorNotificationHandler.hx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorNotificationHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorNotificationHandler.hx index 796e70381..a81b704b7 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorNotificationHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorNotificationHandler.hx @@ -21,7 +21,7 @@ class ChartEditorNotificationHandler */ public static function success(state:ChartEditorState, title:String, body:String):Notification { - return sendNotification(title, body, NotificationType.Success); + return sendNotification(state, title, body, NotificationType.Success); } /** @@ -30,7 +30,7 @@ class ChartEditorNotificationHandler */ public static function warning(state:ChartEditorState, title:String, body:String):Notification { - return sendNotification(title, body, NotificationType.Warning); + return sendNotification(state, title, body, NotificationType.Warning); } /** @@ -48,7 +48,7 @@ class ChartEditorNotificationHandler */ public static function error(state:ChartEditorState, title:String, body:String):Notification { - return sendNotification(title, body, NotificationType.Error); + return sendNotification(state, title, body, NotificationType.Error); } /** @@ -66,7 +66,7 @@ class ChartEditorNotificationHandler */ public static function info(state:ChartEditorState, title:String, body:String):Notification { - return sendNotification(title, body, NotificationType.Info); + return sendNotification(state, title, body, NotificationType.Info); } /** @@ -79,7 +79,7 @@ class ChartEditorNotificationHandler */ public static function infoWithActions(state:ChartEditorState, title:String, body:String, actions:Array):Notification { - return sendNotification(title, body, NotificationType.Info, actions); + return sendNotification(state, title, body, NotificationType.Info, actions); } /** @@ -101,7 +101,7 @@ class ChartEditorNotificationHandler NotificationManager.instance.removeNotification(notif); } - static function sendNotification(title:String, body:String, ?type:NotificationType, ?actions:Array):Notification + static function sendNotification(state:ChartEditorState, title:String, body:String, ?type:NotificationType, ?actions:Array):Notification { #if !mac var actionNames:Array = actions == null ? [] : actions.map(action -> action.text); @@ -127,6 +127,8 @@ class ChartEditorNotificationHandler if (action != null && action.callback != null) { button.onClick = function(_) { + // Don't allow actions to be clicked while the playtest is open. + if (state.subState != null) return; action.callback(); }; } From ed10d2c5d017dd5eaec2c4cd3bbbf0a4688f36a2 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 28 Nov 2023 20:36:59 -0500 Subject: [PATCH 2/8] Multiple chart editor bug fixes +tweaks --- assets | 2 +- source/funkin/data/song/SongDataUtils.hx | 33 +++- source/funkin/play/PlayState.hx | 21 ++ .../ui/debug/charting/ChartEditorState.hx | 22 ++- .../commands/ChangeStartingBPMCommand.hx | 54 +++++ .../charting/commands/PasteItemsCommand.hx | 6 +- .../handlers/ChartEditorDialogHandler.hx | 186 +++++++++--------- .../handlers/ChartEditorToolboxHandler.hx | 15 +- 8 files changed, 230 insertions(+), 109 deletions(-) create mode 100644 source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx diff --git a/assets b/assets index c6aef3e3e..a88cfa4c2 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c6aef3e3e6abc573c75dc5dbc90059ccdb6da83c +Subproject commit a88cfa4c2eb3d4b8fc0bb0f7770d6a8359755bb4 diff --git a/source/funkin/data/song/SongDataUtils.hx b/source/funkin/data/song/SongDataUtils.hx index 9a9f758b1..4ae4b1426 100644 --- a/source/funkin/data/song/SongDataUtils.hx +++ b/source/funkin/data/song/SongDataUtils.hx @@ -32,10 +32,7 @@ class SongDataUtils return new SongNoteData(time, data, length, kind); }; - trace(notes); - trace(notes[0]); var result = [for (i in 0...notes.length) offsetNote(notes[i])]; - trace(result); return result; } @@ -54,6 +51,36 @@ class SongDataUtils }); } + /** + * Given an array of SongNoteData objects, return a new array of SongNoteData objects + * which excludes any notes whose timestamps are outside of the given range. + * @param notes The notes to modify. + * @param startTime The start of the range in milliseconds. + * @param endTime The end of the range in milliseconds. + * @return The filtered array of notes. + */ + public static function clampSongNoteData(notes:Array, startTime:Float, endTime:Float):Array + { + return notes.filter(function(note:SongNoteData):Bool { + return note.time >= startTime && note.time <= endTime; + }); + } + + /** + * Given an array of SongEventData objects, return a new array of SongEventData objects + * which excludes any events whose timestamps are outside of the given range. + * @param events The events to modify. + * @param startTime The start of the range in milliseconds. + * @param endTime The end of the range in milliseconds. + * @return The filtered array of events. + */ + public static function clampSongEventData(events:Array, startTime:Float, endTime:Float):Array + { + return events.filter(function(event:SongEventData):Bool { + return event.time >= startTime && event.time <= endTime; + }); + } + /** * Return a new array without a certain subset of notes from an array of SongNoteData objects. * Does not mutate the original array. diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index c9512aa93..e17aee6f2 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -468,6 +468,8 @@ class PlayState extends MusicBeatSubState var generatedMusic:Bool = false; var perfectMode:Bool = false; + static final BACKGROUND_COLOR:FlxColor = FlxColor.MAGENTA; + /** * Instantiate a new PlayState. * @param params The parameters used to initialize the PlayState. @@ -631,6 +633,24 @@ class PlayState extends MusicBeatSubState initialized = true; } + public override function draw():Void + { + // if (FlxG.renderBlit) + // { + // camGame.fill(BACKGROUND_COLOR); + // } + // else if (FlxG.renderTile) + // { + // FlxG.log.warn("PlayState background not displayed properly on tile renderer!"); + // } + // else + // { + // FlxG.log.warn("PlayState background not displayed properly, unknown renderer!"); + // } + + super.draw(); + } + function assertChartExists():Bool { // Returns null if the song failed to load or doesn't have the selected difficulty. @@ -1258,6 +1278,7 @@ class PlayState extends MusicBeatSubState function initCameras():Void { camGame = new SwagCamera(); + camGame.bgColor = BACKGROUND_COLOR; // Show a pink background behind the stage. camHUD = new FlxCamera(); camHUD.bgColor.alpha = 0; // Show the game scene behind the camera. camCutscene = new FlxCamera(); diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 983840b75..6840fa091 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -2137,8 +2137,6 @@ class ChartEditorState extends HaxeUIState // Disable the menu item if we're not on a desktop platform. var menubarItemGoToBackupsFolder = findComponent('menubarItemGoToBackupsFolder', MenuItem); if (menubarItemGoToBackupsFolder != null) menubarItemGoToBackupsFolder.disabled = true; - - menubarItemGoToBackupsFolder.disabled = true; #end addUIClickListener('menubarItemUserGuide', _ -> this.openUserGuideDialog()); @@ -2291,9 +2289,11 @@ class ChartEditorState extends HaxeUIState */ function openBackupsFolder():Void { + #if sys // TODO: Is there a way to open a folder and highlight a file in it? var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]); WindowUtil.openFolder(absoluteBackupsPath); + #end } /** @@ -4263,7 +4263,16 @@ class ChartEditorState extends HaxeUIState var startTimestamp:Float = 0; if (playtestStartTime) startTimestamp = scrollPositionInMs + playheadPositionInMs; - var targetSong:Song = Song.buildRaw(currentSongId, songMetadata.values(), availableVariations, songChartData, false); + var targetSong:Song; + try + { + targetSong = Song.buildRaw(currentSongId, songMetadata.values(), availableVariations, songChartData, false); + } + catch (e) + { + this.error("Could Not Playtest", 'Got an error trying to playtest the song.\n${e}'); + return; + } // TODO: Rework asset system so we can remove this. switch (currentSongStage) @@ -4308,6 +4317,8 @@ class ChartEditorState extends HaxeUIState if (audioInstTrack != null) FlxG.sound.music = audioInstTrack; if (audioVocalTrackGroup != null) targetState.vocals = audioVocalTrackGroup; + this.persistentUpdate = false; + this.persistentDraw = false; openSubState(targetState); } @@ -4521,6 +4532,8 @@ class ChartEditorState extends HaxeUIState var prevDifficulty = availableDifficulties[availableDifficulties.length - 1]; selectedDifficulty = prevDifficulty; + Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + refreshDifficultyTreeSelection(); refreshMetadataToolbox(); } @@ -4639,6 +4652,9 @@ class ChartEditorState extends HaxeUIState @:nullSafety(Off) function resetConductorAfterTest(_:FlxSubState = null):Void { + this.persistentUpdate = true; + this.persistentDraw = true; + moveSongToScrollPosition(); var instVolumeSlider:Null = findComponent('menubarItemVolumeInstrumental', Slider); diff --git a/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx b/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx new file mode 100644 index 000000000..f5f978aa2 --- /dev/null +++ b/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx @@ -0,0 +1,54 @@ +package funkin.ui.debug.charting.commands; + +/** + * A command which changes the starting BPM of the song. + */ +@:nullSafety +@:access(funkin.ui.debug.charting.ChartEditorState) +class ChangeStartingBPMCommand implements ChartEditorCommand +{ + var targetBPM:Float; + + var previousBPM:Float = 100; + + public function new(targetBPM:Float) + { + this.targetBPM = targetBPM; + } + + public function execute(state:ChartEditorState):Void + { + var timeChanges:Array = state.currentSongMetadata.timeChanges; + if (timeChanges == null || timeChanges.length == 0) + { + previousBPM = 100; + timeChanges = [new SongTimeChange(0, event.value)]; + } + else + { + previousBPM = timeChanges[0].bpm; + timeChanges[0].bpm = event.value; + } + + state.currentSongMetadata.timeChanges = timeChanges; + + Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + } + + public function undo(state:ChartEditorState):Void + { + var timeChanges:Array = state.currentSongMetadata.timeChanges; + if (timeChanges == null || timeChanges.length == 0) + { + timeChanges = [new SongTimeChange(0, previousBPM)]; + } + else + { + timeChanges[0].bpm = previousBPM; + } + + state.currentSongMetadata.timeChanges = timeChanges; + + Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + } +} diff --git a/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx b/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx index 1857b44db..75382da41 100644 --- a/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx +++ b/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx @@ -32,10 +32,14 @@ class PasteItemsCommand implements ChartEditorCommand return; } - trace(currentClipboard.notes); + var stepEndOfSong:Float = Conductor.getTimeInSteps(state.songLengthInMs); + var stepCutoff:Float = stepEndOfSong - 1.0; + var msCutoff:Float = Conductor.getStepTimeInMs(stepCutoff); addedNotes = SongDataUtils.offsetSongNoteData(currentClipboard.notes, Std.int(targetTimestamp)); + addedNotes = SongDataUtils.clampSongNoteData(addedNotes, 0.0, msCutoff); addedEvents = SongDataUtils.offsetSongEventData(currentClipboard.events, Std.int(targetTimestamp)); + addedEvents = SongDataUtils.clampSongEventData(addedEvents, 0.0, msCutoff); state.currentSongChartNoteData = state.currentSongChartNoteData.concat(addedNotes); state.currentSongChartEventData = state.currentSongChartEventData.concat(addedEvents); diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx index 23895be68..d84063117 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx @@ -87,7 +87,7 @@ class ChartEditorDialogHandler if (dialog == null) throw 'Could not locate Welcome dialog'; state.isHaxeUIDialogOpen = true; - dialog.onDialogClosed = function(_event) { + dialog.onDialogClosed = function(event) { state.isHaxeUIDialogOpen = false; // Called when the Welcome dialog is closed while it is closable. state.stopWelcomeMusic(); @@ -109,7 +109,7 @@ class ChartEditorDialogHandler var fileName:String = fileNamePattern.match(chartPath) ? fileNamePattern.matched(1) : chartPath; linkRecentChart.text = fileName; linkRecentChart.tooltip = chartPath; - linkRecentChart.onClick = function(_event) { + linkRecentChart.onClick = function(_) { dialog.hideDialog(DialogButton.CANCEL); state.stopWelcomeMusic(); @@ -155,7 +155,7 @@ class ChartEditorDialogHandler // Create New Song "Easy/Normal/Hard" var linkCreateBasic:Null = dialog.findComponent('splashCreateFromSongBasicOnly', Link); if (linkCreateBasic == null) throw 'Could not locate splashCreateFromSongBasicOnly link in Welcome dialog'; - linkCreateBasic.onClick = function(_event) { + linkCreateBasic.onClick = function(_) { // Hide the welcome dialog dialog.hideDialog(DialogButton.CANCEL); state.stopWelcomeMusic(); @@ -169,7 +169,7 @@ class ChartEditorDialogHandler // Create New Song "Erect/Nightmare" var linkCreateErect:Null = dialog.findComponent('splashCreateFromSongErectOnly', Link); if (linkCreateErect == null) throw 'Could not locate splashCreateFromSongErectOnly link in Welcome dialog'; - linkCreateErect.onClick = function(_event) { + linkCreateErect.onClick = function(_) { // Hide the welcome dialog dialog.hideDialog(DialogButton.CANCEL); @@ -182,7 +182,7 @@ class ChartEditorDialogHandler // Create New Song "Easy/Normal/Hard/Erect/Nightmare" var linkCreateErect:Null = dialog.findComponent('splashCreateFromSongBasicErect', Link); if (linkCreateErect == null) throw 'Could not locate splashCreateFromSongBasicErect link in Welcome dialog'; - linkCreateErect.onClick = function(_event) { + linkCreateErect.onClick = function(_) { // Hide the welcome dialog dialog.hideDialog(DialogButton.CANCEL); @@ -194,7 +194,7 @@ class ChartEditorDialogHandler var linkImportChartLegacy:Null = dialog.findComponent('splashImportChartLegacy', Link); if (linkImportChartLegacy == null) throw 'Could not locate splashImportChartLegacy link in Welcome dialog'; - linkImportChartLegacy.onClick = function(_event) { + linkImportChartLegacy.onClick = function(_) { // Hide the welcome dialog dialog.hideDialog(DialogButton.CANCEL); state.stopWelcomeMusic(); @@ -205,7 +205,7 @@ class ChartEditorDialogHandler var buttonBrowse:Null