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