diff --git a/.vscode/settings.json b/.vscode/settings.json index 8455fde932..ec86904ea6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -95,16 +95,31 @@ "target": "windows", "args": ["-debug", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug", + "target": "hl", + "args": ["-debug"] + }, { "label": "Windows / Debug (FlxAnimate Test)", "target": "windows", "args": ["-debug", "-DANIMATE", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (FlxAnimate Test)", + "target": "hl", + "args": ["-debug", "-DANIMATE"] + }, { "label": "Windows / Debug (Straight to Freeplay)", "target": "windows", "args": ["-debug", "-DFREEPLAY", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (Straight to Freeplay)", + "target": "hl", + "args": ["-debug", "-DFREEPLAY"] + }, { "label": "Windows / Debug (Straight to Play - Bopeebo Normal)", "target": "windows", @@ -114,31 +129,61 @@ "-DFORCE_DEBUG_VERSION" ] }, + { + "label": "HashLink / Debug (Straight to Play - Bopeebo Normal)", + "target": "hl", + "args": ["-debug", "-DSONG=bopeebo -DDIFFICULTY=normal"] + }, { "label": "Windows / Debug (Conversation Test)", "target": "windows", "args": ["-debug", "-DDIALOGUE", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (Conversation Test)", + "target": "hl", + "args": ["-debug", "-DDIALOGUE"] + }, { "label": "Windows / Debug (Straight to Chart Editor)", "target": "windows", "args": ["-debug", "-DCHARTING", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (Straight to Chart Editor)", + "target": "hl", + "args": ["-debug", "-DCHARTING"] + }, { "label": "Windows / Debug (Straight to Animation Editor)", "target": "windows", "args": ["-debug", "-DANIMDEBUG", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (Straight to Animation Editor)", + "target": "hl", + "args": ["-debug", "-DANIMDEBUG"] + }, { "label": "Windows / Debug (Latency Test)", "target": "windows", "args": ["-debug", "-DLATENCY", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (Latency Test)", + "target": "hl", + "args": ["-debug", "-DLATENCY"] + }, { "label": "Windows / Debug (Waveform Test)", "target": "windows", "args": ["-debug", "-DWAVEFORM", "-DFORCE_DEBUG_VERSION"] }, + { + "label": "HashLink / Debug (Waveform Test)", + "target": "hl", + "args": ["-debug", "-DWAVEFORM"] + }, { "label": "HTML5 / Debug", "target": "html5", diff --git a/Project.xml b/Project.xml index 0a8d31b866..c58153575a 100644 --- a/Project.xml +++ b/Project.xml @@ -113,7 +113,6 @@ - diff --git a/docs/COMPILING.md b/docs/COMPILING.md index 7f9c0cdb85..6d5b5b3651 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -7,7 +7,8 @@ - If you accidentally cloned without the `assets` submodule (aka didn't follow the step above), you can run `git submodule update --init --recursive` to get the assets in a foolproof way. 2. Install `hmm` (run `haxelib --global install hmm` and then `haxelib --global run hmm setup`) 3. Install all haxelibs of the current branch by running `hmm install` -4. Platform setup +4. Setup lime: `haxelib run lime setup` +5. Platform setup - For Windows, download the [Visual Studio Build Tools](https://aka.ms/vs/17/release/vs_BuildTools.exe) - When prompted, select "Individual Components" and make sure to download the following: - MSVC v143 VS 2022 C++ x64/x86 build tools @@ -15,5 +16,5 @@ - Mac: [`lime setup mac` Documentation](https://lime.openfl.org/docs/advanced-setup/macos/) - Linux: [`lime setup linux` Documentation](https://lime.openfl.org/docs/advanced-setup/linux/) - HTML5: Compiles without any extra setup -5. If you are targeting for native, you likely need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -6. `lime test PLATFORM` ! +6. If you are targeting for native, you likely need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +7. `lime test PLATFORM` ! diff --git a/hmm.json b/hmm.json index e1acf6c876..26cb0d0b44 100644 --- a/hmm.json +++ b/hmm.json @@ -64,11 +64,6 @@ "ref": "e9f880522e27134b29df4067f82df7d7e5237b70", "url": "https://github.com/haxeui/haxeui-flixel" }, - { - "name": "hmm", - "type": "haxelib", - "version": "3.1.0" - }, { "name": "hscript", "type": "haxelib", @@ -151,7 +146,7 @@ "name": "polymod", "type": "git", "dir": null, - "ref": "0b53e478bc375ec51b760b650201ac7a965d2ef4", + "ref": "d5a3b8995f64d20b95f844454e8c3b38c3d3a9fa", "url": "https://github.com/larsiusprime/polymod" }, { diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 399f524985..ac1b3903b7 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -50,11 +50,13 @@ class InitState extends FlxState */ public override function create():Void { + // Setup a bunch of important Flixel stuff. setupShit(); - // loadSaveData(); // Moved to Main.hx // Load player options from save data. + // Flixel has already loaded the save data, so we can just use it. Preferences.init(); + // Load controls from save data. PlayerSettings.init(); @@ -198,8 +200,13 @@ class InitState extends FlxState // // FLIXEL PLUGINS // + // Plugins provide a useful interface for globally active Flixel objects, + // that receive update events regardless of the current state. + // TODO: Move Module behavior to a Flixel plugin. funkin.util.plugins.EvacuateDebugPlugin.initialize(); funkin.util.plugins.ReloadAssetsDebugPlugin.initialize(); + funkin.util.plugins.ScreenshotPlugin.initialize(); + funkin.util.plugins.VolumePlugin.initialize(); funkin.util.plugins.WatchPlugin.initialize(); // diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index 6b0911eded..039a4c2852 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -20,7 +20,10 @@ class Preferences static function set_naughtyness(value:Bool):Bool { - return Save.get().options.naughtyness = value; + var save = Save.get(); + save.options.naughtyness = value; + save.flush(); + return value; } /** @@ -36,7 +39,10 @@ class Preferences static function set_downscroll(value:Bool):Bool { - return Save.get().options.downscroll = value; + var save = Save.get(); + save.options.downscroll = value; + save.flush(); + return value; } /** @@ -52,7 +58,10 @@ class Preferences static function set_flashingLights(value:Bool):Bool { - return Save.get().options.flashingLights = value; + var save = Save.get(); + save.options.flashingLights = value; + save.flush(); + return value; } /** @@ -68,7 +77,10 @@ class Preferences static function set_zoomCamera(value:Bool):Bool { - return Save.get().options.zoomCamera = value; + var save = Save.get(); + save.options.zoomCamera = value; + save.flush(); + return value; } /** @@ -89,7 +101,10 @@ class Preferences toggleDebugDisplay(value); } - return Save.get().options.debugDisplay = value; + var save = Save.get(); + save.options.debugDisplay = value; + save.flush(); + return value; } /** @@ -107,7 +122,10 @@ class Preferences { if (value != Save.get().options.autoPause) FlxG.autoPause = value; - return Save.get().options.autoPause = value; + var save = Save.get(); + save.options.autoPause = value; + save.flush(); + return value; } public static function init():Void diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 8a07f9fb1a..4deba7088f 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; @@ -1067,13 +1073,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; @@ -1088,11 +1094,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 01ea2da32f..7f3b01eb41 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/input/Controls.hx b/source/funkin/input/Controls.hx index 201c222a3d..c4760cf5fb 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -63,12 +63,10 @@ class Controls extends FlxActionSet var _debug_menu = new FlxActionDigital(Action.DEBUG_MENU); var _debug_chart = new FlxActionDigital(Action.DEBUG_CHART); var _debug_stage = new FlxActionDigital(Action.DEBUG_STAGE); + var _screenshot = new FlxActionDigital(Action.SCREENSHOT); var _volume_up = new FlxActionDigital(Action.VOLUME_UP); var _volume_down = new FlxActionDigital(Action.VOLUME_DOWN); var _volume_mute = new FlxActionDigital(Action.VOLUME_MUTE); - #if CAN_CHEAT - var _cheat = new FlxActionDigital(Action.CHEAT); - #end var byName:Map = new Map(); @@ -235,6 +233,11 @@ class Controls extends FlxActionSet inline function get_DEBUG_STAGE() return _debug_stage.check(); + public var SCREENSHOT(get, never):Bool; + + inline function get_SCREENSHOT() + return _screenshot.check(); + public var VOLUME_UP(get, never):Bool; inline function get_VOLUME_UP() @@ -255,13 +258,6 @@ class Controls extends FlxActionSet inline function get_RESET() return _reset.check(); - #if CAN_CHEAT - public var CHEAT(get, never):Bool; - - inline function get_CHEAT() - return _cheat.check(); - #end - public function new(name, scheme:KeyboardScheme = null) { super(name); @@ -295,13 +291,14 @@ class Controls extends FlxActionSet add(_pause); add(_cutscene_advance); add(_cutscene_skip); + add(_debug_menu); + add(_debug_chart); + add(_debug_stage); + add(_screenshot); add(_volume_up); add(_volume_down); add(_volume_mute); add(_reset); - #if CAN_CHEAT - add(_cheat); - #end for (action in digitalActions) byName[action.name] = action; @@ -391,12 +388,10 @@ class Controls extends FlxActionSet case DEBUG_MENU: _debug_menu; case DEBUG_CHART: _debug_chart; case DEBUG_STAGE: _debug_stage; + case SCREENSHOT: _screenshot; case VOLUME_UP: _volume_up; case VOLUME_DOWN: _volume_down; case VOLUME_MUTE: _volume_mute; - #if CAN_CHEAT - case CHEAT: _cheat; - #end } } @@ -464,6 +459,8 @@ class Controls extends FlxActionSet func(_debug_chart, JUST_PRESSED); case DEBUG_STAGE: func(_debug_stage, JUST_PRESSED); + case SCREENSHOT: + func(_screenshot, JUST_PRESSED); case VOLUME_UP: func(_volume_up, JUST_PRESSED); case VOLUME_DOWN: @@ -472,10 +469,6 @@ class Controls extends FlxActionSet func(_volume_mute, JUST_PRESSED); case RESET: func(_reset, JUST_PRESSED); - #if CAN_CHEAT - case CHEAT: - func(_cheat, JUST_PRESSED); - #end } } @@ -666,6 +659,8 @@ class Controls extends FlxActionSet bindKeys(Control.DEBUG_MENU, getDefaultKeybinds(scheme, Control.DEBUG_MENU)); bindKeys(Control.DEBUG_CHART, getDefaultKeybinds(scheme, Control.DEBUG_CHART)); bindKeys(Control.DEBUG_STAGE, getDefaultKeybinds(scheme, Control.DEBUG_STAGE)); + bindKeys(Control.RESET, getDefaultKeybinds(scheme, Control.RESET)); + bindKeys(Control.SCREENSHOT, getDefaultKeybinds(scheme, Control.SCREENSHOT)); bindKeys(Control.VOLUME_UP, getDefaultKeybinds(scheme, Control.VOLUME_UP)); bindKeys(Control.VOLUME_DOWN, getDefaultKeybinds(scheme, Control.VOLUME_DOWN)); bindKeys(Control.VOLUME_MUTE, getDefaultKeybinds(scheme, Control.VOLUME_MUTE)); @@ -693,6 +688,7 @@ class Controls extends FlxActionSet case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; case Control.DEBUG_STAGE: return []; + case Control.SCREENSHOT: return [F3]; // TODO: Change this back to PrintScreen case Control.VOLUME_UP: return [PLUS, NUMPADPLUS]; case Control.VOLUME_DOWN: return [MINUS, NUMPADMINUS]; case Control.VOLUME_MUTE: return [ZERO, NUMPADZERO]; @@ -716,6 +712,7 @@ class Controls extends FlxActionSet case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; case Control.DEBUG_STAGE: return []; + case Control.SCREENSHOT: return [PRINTSCREEN]; case Control.VOLUME_UP: return [PLUS]; case Control.VOLUME_DOWN: return [MINUS]; case Control.VOLUME_MUTE: return [ZERO]; @@ -739,6 +736,7 @@ class Controls extends FlxActionSet case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; case Control.DEBUG_STAGE: return []; + case Control.SCREENSHOT: return [PRINTSCREEN]; case Control.VOLUME_UP: return [NUMPADPLUS]; case Control.VOLUME_DOWN: return [NUMPADMINUS]; case Control.VOLUME_MUTE: return [NUMPADZERO]; @@ -845,6 +843,7 @@ class Controls extends FlxActionSet Control.NOTE_LEFT => getDefaultGamepadBinds(Control.NOTE_LEFT), Control.NOTE_RIGHT => getDefaultGamepadBinds(Control.NOTE_RIGHT), Control.PAUSE => getDefaultGamepadBinds(Control.PAUSE), + // Control.SCREENSHOT => [], // Control.VOLUME_UP => [RIGHT_SHOULDER], // Control.VOLUME_DOWN => [LEFT_SHOULDER], // Control.VOLUME_MUTE => [RIGHT_TRIGGER], @@ -852,8 +851,7 @@ class Controls extends FlxActionSet Control.CUTSCENE_SKIP => getDefaultGamepadBinds(Control.CUTSCENE_SKIP), // Control.DEBUG_MENU // Control.DEBUG_CHART - Control.RESET => getDefaultGamepadBinds(Control.RESET), - #if CAN_CHEAT, Control.CHEAT => getDefaultGamepadBinds(Control.CHEAT) #end + Control.RESET => getDefaultGamepadBinds(Control.RESET) ]); } @@ -870,6 +868,7 @@ class Controls extends FlxActionSet case Control.NOTE_LEFT: return [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT]; case Control.NOTE_RIGHT: return [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT]; case Control.PAUSE: return [START]; + case Control.SCREENSHOT: return []; case Control.VOLUME_UP: return []; case Control.VOLUME_DOWN: return []; case Control.VOLUME_MUTE: return []; @@ -878,7 +877,6 @@ class Controls extends FlxActionSet case Control.DEBUG_MENU: return []; case Control.DEBUG_CHART: return []; case Control.RESET: return [RIGHT_SHOULDER]; - #if CAN_CHEAT, Control.CHEAT: return [X]; #end default: // Fallthrough. } @@ -1236,6 +1234,8 @@ enum Control // CUTSCENE CUTSCENE_ADVANCE; CUTSCENE_SKIP; + // SCREENSHOT + SCREENSHOT; // VOLUME VOLUME_UP; VOLUME_DOWN; @@ -1244,9 +1244,6 @@ enum Control DEBUG_MENU; DEBUG_CHART; DEBUG_STAGE; - #if CAN_CHEAT - CHEAT; - #end } enum @@ -1289,13 +1286,12 @@ abstract Action(String) to String from String var VOLUME_UP = "volume_up"; var VOLUME_DOWN = "volume_down"; var VOLUME_MUTE = "volume_mute"; + // SCREENSHOT + var SCREENSHOT = "screenshot"; // DEBUG var DEBUG_MENU = "debug_menu"; var DEBUG_CHART = "debug_chart"; var DEBUG_STAGE = "debug_stage"; - #if CAN_CHEAT - var CHEAT = "cheat"; - #end } enum Device diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 4b93496481..e7b12fa16f 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -354,6 +354,11 @@ class PlayState extends MusicBeatSubState */ var startingSong:Bool = false; + /** + * False if `FlxG.sound.music` + */ + var musicPausedBySubState:Bool = false; + /** * False until `create()` has completed. */ @@ -697,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; @@ -716,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'); @@ -1043,6 +1052,7 @@ class PlayState extends MusicBeatSubState // Pause the music. if (FlxG.sound.music != null) { + musicPausedBySubState = FlxG.sound.music.playing; FlxG.sound.music.pause(); if (vocals != null) vocals.pause(); } @@ -1050,7 +1060,6 @@ class PlayState extends MusicBeatSubState // Pause the countdown. Countdown.pauseCountdown(); } - else {} super.openSubState(subState); } @@ -1070,7 +1079,10 @@ class PlayState extends MusicBeatSubState if (event.eventCanceled) return; // Resume - FlxG.sound.music.play(FlxG.sound.music.time); + if (musicPausedBySubState) + { + FlxG.sound.music.play(FlxG.sound.music.time); + } if (FlxG.sound.music != null && !startingSong && !isInCutscene) resyncVocals(); diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 6a4dd048ce..5bbded231b 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -113,6 +113,9 @@ abstract Save(RawSaveData) }; } + /** + * NOTE: Modifications will not be saved without calling `Save.flush()`! + */ public var options(get, never):SaveDataOptions; function get_options():SaveDataOptions @@ -120,6 +123,9 @@ abstract Save(RawSaveData) return this.options; } + /** + * NOTE: Modifications will not be saved without calling `Save.flush()`! + */ public var modOptions(get, never):Map; function get_modOptions():Map diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index 884fc50610..98197a0e78 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -58,19 +58,6 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler Conductor.stepHit.remove(this.stepHit); } - function handleControls():Void - { - var isHaxeUIFocused:Bool = haxe.ui.focus.FocusManager.instance?.focus != null; - - if (!isHaxeUIFocused) - { - // Rebindable volume keys. - if (controls.VOLUME_MUTE) FlxG.sound.toggleMuted(); - else if (controls.VOLUME_UP) FlxG.sound.changeVolume(0.1); - else if (controls.VOLUME_DOWN) FlxG.sound.changeVolume(-0.1); - } - } - function handleFunctionControls():Void { // Emergency exit button. @@ -84,8 +71,6 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler { super.update(elapsed); - handleControls(); - dispatchEvent(new UpdateScriptEvent(elapsed)); } diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index 9a6f1a3235..2c89703575 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -53,11 +53,6 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler { super.update(elapsed); - // Rebindable volume keys. - if (controls.VOLUME_MUTE) FlxG.sound.toggleMuted(); - else if (controls.VOLUME_UP) FlxG.sound.changeVolume(0.1); - else if (controls.VOLUME_DOWN) FlxG.sound.changeVolume(-0.1); - // Emergency exit button. if (FlxG.keys.justPressed.F4) FlxG.switchState(() -> new MainMenuState()); diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 861e99f6b0..375fb8f5c5 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -9,6 +9,7 @@ import funkin.ui.debug.charting.ChartEditorState; import funkin.ui.MusicBeatSubState; import funkin.util.logging.CrashHandler; import flixel.addons.transition.FlxTransitionableState; +import funkin.util.FileUtil; class DebugMenuSubState extends MusicBeatSubState { @@ -110,16 +111,7 @@ class DebugMenuSubState extends MusicBeatSubState #if sys function openLogFolder() { - #if windows - Sys.command('explorer', [CrashHandler.LOG_FOLDER]); - #elseif mac - // mac could be fuckie with where the log folder is relative to the game file... - // if this comment is still here... it means it has NOT been verified on mac yet! - Sys.command('open', [CrashHandler.LOG_FOLDER]); - #end - - // TODO: implement linux - // some shit with xdg-open :thinking: emoji... + FileUtil.openFolder(CrashHandler.LOG_FOLDER); } #end diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 6c64f952b2..48a6e70c9d 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 d6c5beeac6..88f73cfed3 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 35a00e5623..5cc89e1370 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 9e22ba833e..f32cc2bfbf 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