From ca69e7b850332e0aa4a35574566867cca649cdbf Mon Sep 17 00:00:00 2001 From: lemz Date: Sun, 2 Jun 2024 02:44:16 +0200 Subject: [PATCH] custom note styles in chart editor --- .../ui/debug/charting/ChartEditorState.hx | 2 + .../components/ChartEditorNoteSprite.hx | 106 ++++++++++-------- .../toolboxes/ChartEditorNoteDataToolbox.hx | 5 + 3 files changed, 64 insertions(+), 49 deletions(-) diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index f72cca77f..0117d8a51 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -1663,6 +1663,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState return currentSongMetadata.playData.characters.instrumental = value; } + var currentCustomNoteKindStyle:Null; + /** * HAXEUI COMPONENTS */ diff --git a/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx b/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx index 98f5a47aa..c97aee1f8 100644 --- a/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx +++ b/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx @@ -7,7 +7,11 @@ import flixel.graphics.frames.FlxAtlasFrames; import flixel.graphics.frames.FlxFrame; import flixel.graphics.frames.FlxTileFrames; import flixel.math.FlxPoint; +import funkin.data.animation.AnimationData; import funkin.data.song.SongData.SongNoteData; +import funkin.data.notestyle.NoteStyleRegistry; +import funkin.play.notes.notestyle.NoteStyle; +import funkin.play.notes.NoteDirection; /** * A sprite that can be used to display a note in a chart. @@ -68,68 +72,62 @@ class ChartEditorNoteSprite extends FlxSprite if (noteFrameCollection == null) { - initFrameCollection(); + buildEmptyFrameCollection(); + + addNoteStyleFrames(fetchNoteStyle('funkin')); + addNoteStyleFrames(fetchNoteStyle('pixel')); } if (noteFrameCollection == null) throw 'ERROR: Could not initialize note sprite animations.'; this.frames = noteFrameCollection; - // Initialize all the animations, not just the one we're going to use immediately, - // so that later we can reuse the sprite without having to initialize more animations during scrolling. - this.animation.addByPrefix('tapLeftFunkin', 'purple instance'); - this.animation.addByPrefix('tapDownFunkin', 'blue instance'); - this.animation.addByPrefix('tapUpFunkin', 'green instance'); - this.animation.addByPrefix('tapRightFunkin', 'red instance'); - - this.animation.addByPrefix('holdLeftFunkin', 'LeftHoldPiece'); - this.animation.addByPrefix('holdDownFunkin', 'DownHoldPiece'); - this.animation.addByPrefix('holdUpFunkin', 'UpHoldPiece'); - this.animation.addByPrefix('holdRightFunkin', 'RightHoldPiece'); - - this.animation.addByPrefix('holdEndLeftFunkin', 'LeftHoldEnd'); - this.animation.addByPrefix('holdEndDownFunkin', 'DownHoldEnd'); - this.animation.addByPrefix('holdEndUpFunkin', 'UpHoldEnd'); - this.animation.addByPrefix('holdEndRightFunkin', 'RightHoldEnd'); - - this.animation.addByPrefix('tapLeftPixel', 'pixel4'); - this.animation.addByPrefix('tapDownPixel', 'pixel5'); - this.animation.addByPrefix('tapUpPixel', 'pixel6'); - this.animation.addByPrefix('tapRightPixel', 'pixel7'); + addNoteStyleAnimations(fetchNoteStyle('funkin')); + addNoteStyleAnimations(fetchNoteStyle('pixel')); } static var noteFrameCollection:Null = null; - /** - * We load all the note frames once, then reuse them. - */ - static function initFrameCollection():Void + function fetchNoteStyle(noteStyleId:String):NoteStyle { - buildEmptyFrameCollection(); - if (noteFrameCollection == null) return; + return NoteStyleRegistry.instance.fetchEntry(noteStyleId) ?? NoteStyleRegistry.instance.fetchDefault(); + } - // TODO: Automatically iterate over the list of note skins. + @:access(funkin.play.notes.notestyle.NoteStyle) + @:nullSafety(Off) + static function addNoteStyleFrames(noteStyle:NoteStyle):Void + { + var prefix:String = noteStyle.id.toTitleCase(); - // Normal notes - var frameCollectionNormal:FlxAtlasFrames = Paths.getSparrowAtlas('NOTE_assets'); - - for (frame in frameCollectionNormal.frames) + var frameCollection:FlxAtlasFrames = Paths.getSparrowAtlas(noteStyle.getNoteAssetPath(), noteStyle.getNoteAssetLibrary()); + for (frame in frameCollection.frames) { - noteFrameCollection.pushFrame(frame); + // cloning the frame because else + // we will fuck up the frame data used in game + var clonedFrame:FlxFrame = frame.copyTo(); + clonedFrame.name = '$prefix${clonedFrame.name}'; + noteFrameCollection.pushFrame(clonedFrame); } + } - // Pixel notes - var graphicPixel = FlxG.bitmap.add(Paths.image('weeb/pixelUI/arrows-pixels', 'week6'), false, null); - if (graphicPixel == null) trace('ERROR: Could not load graphic: ' + Paths.image('weeb/pixelUI/arrows-pixels', 'week6')); - var frameCollectionPixel = FlxTileFrames.fromGraphic(graphicPixel, new FlxPoint(17, 17)); - for (i in 0...frameCollectionPixel.frames.length) - { - var frame:Null = frameCollectionPixel.frames[i]; - if (frame == null) continue; + @:access(funkin.play.notes.notestyle.NoteStyle) + @:nullSafety(Off) + function addNoteStyleAnimations(noteStyle:NoteStyle):Void + { + var prefix:String = noteStyle.id.toTitleCase(); + var suffix:String = noteStyle.id.toTitleCase(); - frame.name = 'pixel' + i; - noteFrameCollection.pushFrame(frame); - } + var leftData:AnimationData = noteStyle.fetchNoteAnimationData(NoteDirection.LEFT); + this.animation.addByPrefix('tapLeft$suffix', '$prefix${leftData.prefix}', leftData.frameRate, leftData.looped, leftData.flipX, leftData.flipY); + + var downData:AnimationData = noteStyle.fetchNoteAnimationData(NoteDirection.DOWN); + this.animation.addByPrefix('tapDown$suffix', '$prefix${downData.prefix}', downData.frameRate, downData.looped, downData.flipX, downData.flipY); + + var upData:AnimationData = noteStyle.fetchNoteAnimationData(NoteDirection.UP); + this.animation.addByPrefix('tapUp$suffix', '$prefix${upData.prefix}', upData.frameRate, upData.looped, upData.flipX, upData.flipY); + + var rightData:AnimationData = noteStyle.fetchNoteAnimationData(NoteDirection.RIGHT); + this.animation.addByPrefix('tapRight$suffix', '$prefix${rightData.prefix}', rightData.frameRate, rightData.looped, rightData.flipX, rightData.flipY); } @:nullSafety(Off) @@ -187,10 +185,20 @@ class ChartEditorNoteSprite extends FlxSprite function get_noteStyle():String { - // Fall back to Funkin' if it's not a valid note style. - return if (NOTE_STYLES.contains(this.parentState.currentSongNoteStyle)) this.parentState.currentSongNoteStyle else 'funkin'; + if (this.parentState.currentCustomNoteKindStyle != null) + { + return this.parentState.currentCustomNoteKindStyle; + } + + if (NOTE_STYLES.contains(this.parentState.currentSongNoteStyle)) + { + return this.parentState.currentSongNoteStyle; + } + + return 'funkin'; } + @:nullSafety(Off) public function playNoteAnimation():Void { if (this.noteData == null) return; @@ -213,8 +221,8 @@ class ChartEditorNoteSprite extends FlxSprite } this.updateHitbox(); - // TODO: Make this an attribute of the note skin. - this.antialiasing = (this.parentState.currentSongNoteStyle != 'Pixel'); + var bruhStyle:NoteStyle = fetchNoteStyle(this.noteStyle); + this.antialiasing = !bruhStyle._data?.assets?.note?.isPixel ?? true; } /** diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorNoteDataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorNoteDataToolbox.hx index d4fc69fc1..952513f0e 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorNoteDataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorNoteDataToolbox.hx @@ -4,6 +4,8 @@ import haxe.ui.components.DropDown; import haxe.ui.components.TextField; import haxe.ui.events.UIEvent; import funkin.ui.debug.charting.util.ChartEditorDropdowns; +import funkin.play.notes.notestyle.NoteStyle; +import funkin.play.notes.notekind.NoteKindManager; /** * The toolbox which allows modifying information like Note Kind. @@ -73,6 +75,9 @@ class ChartEditorNoteDataToolbox extends ChartEditorBaseToolbox var customKind:Null = event?.target?.text; chartEditorState.noteKindToPlace = customKind; + var noteStyle:Null = NoteKindManager.getNoteStyle(customKind); + chartEditorState.currentCustomNoteKindStyle = noteStyle?.id; + if (chartEditorState.currentEventSelection.length > 0) { // Edit the note data of any selected notes.