diff --git a/.gitmodules b/.gitmodules index 8968471e3..17c3cc026 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,6 +2,9 @@ path = assets url = https://github.com/FunkinCrew/Funkin-history-rewrite-assets branch = master + update = merge [submodule "art"] path = art url = https://github.com/FunkinCrew/Funkin-history-rewrite-art + branch = master + update = merge diff --git a/assets b/assets index d491f5d87..8b89a7e73 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d491f5d87a0deba0b5642beeb801c8e130754038 +Subproject commit 8b89a7e734d7203b3782fbbcdf7e028c03d13df2 diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx index 918e7c725..0ba5d5175 100644 --- a/source/funkin/FreeplayState.hx +++ b/source/funkin/FreeplayState.hx @@ -84,6 +84,7 @@ class FreeplayState extends MusicBeatSubState var dj:DJBoyfriend; + var letterSort:LetterSort; var typing:FlxInputText; var exitMovers:Map<Array<FlxSprite>, MoveData> = new Map(); @@ -413,7 +414,7 @@ class FreeplayState extends MusicBeatSubState txtCompletion.visible = false; add(txtCompletion); - var letterSort:LetterSort = new LetterSort(400, 75); + letterSort = new LetterSort(400, 75); add(letterSort); letterSort.visible = false; @@ -953,6 +954,7 @@ class FreeplayState extends MusicBeatSubState trace("RANDOM SELECTED"); busy = true; + letterSort.inputEnabled = false; var availableSongCapsules:Array<SongMenuItem> = grpCapsules.members.filter(function(cap:SongMenuItem) { // Dead capsules are ones which were removed from the list when changing filters. @@ -963,6 +965,15 @@ class FreeplayState extends MusicBeatSubState return cap.songData.songName; })}'); + if (availableSongCapsules.length == 0) + { + trace("No songs available!"); + busy = false; + letterSort.inputEnabled = true; + FlxG.sound.play(Paths.sound('cancelMenu')); + return; + } + var targetSong:SongMenuItem = FlxG.random.getObject(availableSongCapsules); // Seeing if I can do an animation... @@ -976,6 +987,7 @@ class FreeplayState extends MusicBeatSubState function capsuleOnConfirmDefault(cap:SongMenuItem):Void { busy = true; + letterSort.inputEnabled = false; PlayStatePlaylist.isStoryMode = false; diff --git a/source/funkin/freeplayStuff/LetterSort.hx b/source/funkin/freeplayStuff/LetterSort.hx index e6d923c90..edf1221d2 100644 --- a/source/funkin/freeplayStuff/LetterSort.hx +++ b/source/funkin/freeplayStuff/LetterSort.hx @@ -23,6 +23,8 @@ class LetterSort extends FlxTypedSpriteGroup<FlxSprite> var rightArrow:FlxSprite; var grpSeperators:Array<FlxSprite> = []; + public var inputEnabled:Bool = true; + public function new(x, y) { super(x, y); @@ -72,8 +74,11 @@ class LetterSort extends FlxTypedSpriteGroup<FlxSprite> { super.update(elapsed); - if (FlxG.keys.justPressed.E) changeSelection(1); - if (FlxG.keys.justPressed.Q) changeSelection(-1); + if (inputEnabled) + { + if (FlxG.keys.justPressed.E) changeSelection(1); + if (FlxG.keys.justPressed.Q) changeSelection(-1); + } } public function changeSelection(diff:Int = 0) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 8761b3ec1..ecbe0087b 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -700,6 +700,8 @@ class PlayState extends MusicBeatSubState if (!overrideMusic) { + // Stop the vocals if they already exist. + if (vocals != null) vocals.stop(); vocals = currentChart.buildVocals(); if (vocals.members.length == 0) @@ -1554,6 +1556,8 @@ class PlayState extends MusicBeatSubState if (!overrideMusic) { + // Stop the vocals if they already exist. + if (vocals != null) vocals.stop(); vocals = currentChart.buildVocals(); if (vocals.members.length == 0) diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 8255a8c7d..05db47a69 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -35,6 +35,15 @@ import funkin.play.HealthIcon; import funkin.play.notes.NoteSprite; import funkin.play.PlayState; import funkin.play.song.Song; +import funkin.data.song.SongData.SongChartData; +import funkin.data.song.SongRegistry; +import funkin.data.song.SongData.SongEventData; +import funkin.data.song.SongData.SongMetadata; +import funkin.data.song.SongData.SongNoteData; +import funkin.data.song.SongData.SongCharacterData; +import funkin.data.song.SongDataUtils; +import funkin.ui.debug.charting.commands.ChartEditorCommand; +import funkin.ui.debug.charting.handlers.ChartEditorShortcutHandler; import funkin.play.stage.StageData; import funkin.ui.debug.charting.commands.AddEventsCommand; import funkin.ui.debug.charting.commands.AddNotesCommand; @@ -1403,6 +1412,7 @@ class ChartEditorState extends HaxeUIState buildSelectionBox(); buildAdditionalUI(); + ChartEditorShortcutHandler.applyPlatformShortcutText(this); // Setup the onClick listeners for the UI after it's been created. setupUIListeners(); diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorShortcutHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorShortcutHandler.hx new file mode 100644 index 000000000..016a181d3 --- /dev/null +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorShortcutHandler.hx @@ -0,0 +1,61 @@ +package funkin.ui.debug.charting.handlers; + +import funkin.util.PlatformUtil; + +@:access(funkin.ui.debug.charting.ChartEditorState) +class ChartEditorShortcutHandler +{ + public static function applyPlatformShortcutText(state:ChartEditorState):Void + { + state.setComponentShortcutText('menubarItemNewChart', ctrlOrCmd('N')); + state.setComponentShortcutText('menubarItemOpenChart', ctrlOrCmd('O')); + state.setComponentShortcutText('menubarItemSaveChartAs', ctrlOrCmd(shift('S'))); + state.setComponentShortcutText('menubarItemExit', ctrlOrCmd('Q')); + + state.setComponentShortcutText('menubarItemUndo', ctrlOrCmd('Z')); + state.setComponentShortcutText('menubarItemRedo', ctrlOrCmd('Y')); + state.setComponentShortcutText('menubarItemCut', ctrlOrCmd('X')); + state.setComponentShortcutText('menubarItemCopy', ctrlOrCmd('C')); + state.setComponentShortcutText('menubarItemPaste', ctrlOrCmd('V')); + + state.setComponentShortcutText('menubarItemSelectAll', ctrlOrCmd('A')); + state.setComponentShortcutText('menubarItemSelectInverse', ctrlOrCmd('I')); + state.setComponentShortcutText('menubarItemSelectNone', ctrlOrCmd('D')); + state.setComponentShortcutText('menubarItemSelectBeforeCursor', shift('Home')); + state.setComponentShortcutText('menubarItemSelectAfterCursor', shift('End')); + + state.setComponentShortcutText('menubarItemDifficultyDown', ctrlOrCmd('←')); + state.setComponentShortcutText('menubarItemDifficultyUp', ctrlOrCmd('→')); + + state.setComponentShortcutText('menubarItemPlaytestFull', 'Enter'); + state.setComponentShortcutText('menubarItemPlaytestMinimal', shift('Enter')); + } + + /** + * Display `Ctrl` on Windows and `⌘` (Command) on macOS. + * @param input + */ + static inline function ctrlOrCmd(input:String) + { + return (PlatformUtil.isMacOS()) ? '⌘+${input}' : 'Ctrl+${input}'; + } + + /** + * Display `Ctrl` on Windows and `^` (Control) on macOS. + * @param input + */ + static inline function ctrl(input:String) + { + return (PlatformUtil.isMacOS()) ? '^+${input}' : 'Ctrl+${input}'; + } + + static inline function alt(input:String) + { + return (PlatformUtil.isMacOS()) ? '⌥+${input}' : 'Alt+${input}'; + } + + static inline function shift(input:String) + { + return (PlatformUtil.isMacOS()) ? '⇧+${input}' : 'Shift+${input}'; + } +} diff --git a/source/funkin/ui/haxeui/HaxeUIState.hx b/source/funkin/ui/haxeui/HaxeUIState.hx index 78b93c431..36540c45e 100644 --- a/source/funkin/ui/haxeui/HaxeUIState.hx +++ b/source/funkin/ui/haxeui/HaxeUIState.hx @@ -2,6 +2,7 @@ package funkin.ui.haxeui; import haxe.ui.components.CheckBox; import haxe.ui.containers.menus.MenuCheckBox; +import haxe.ui.containers.menus.MenuItem; import haxe.ui.core.Component; import haxe.ui.core.Screen; import haxe.ui.events.MouseEvent; @@ -139,6 +140,20 @@ class HaxeUIState extends MusicBeatState } } + function setComponentShortcutText(key:String, text:String):Void + { + var target:MenuItem = findComponent(key, MenuItem); + if (target == null) + { + // Gracefully handle the case where the item can't be located. + trace('WARN: Could not locate menu item: $key'); + } + else + { + target.shortcutText = text; + } + } + /** * Add an onChange listener to a HaxeUI input component such as a slider or text field. */ diff --git a/source/funkin/util/PlatformUtil.hx b/source/funkin/util/PlatformUtil.hx new file mode 100644 index 000000000..b709eb475 --- /dev/null +++ b/source/funkin/util/PlatformUtil.hx @@ -0,0 +1,23 @@ +package funkin.util; + +class PlatformUtil +{ + /** + * Returns true if the current platform is MacOS. + * + * NOTE: Only use this for choosing modifier keys for shortcut hints. + * @return Whether the current platform is MacOS, or HTML5 running on MacOS. + */ + public static function isMacOS():Bool + { + #if mac + return true; + #elseif html5 + return js.Browser.window.navigator.platform.startsWith("Mac") + || js.Browser.window.navigator.platform.startsWith("iPad") + || js.Browser.window.navigator.platform.startsWith("iPhone"); + #else + return false; + #end + } +}