From 785c4be88b52dc1b5899013822fc004ba7d9894d Mon Sep 17 00:00:00 2001 From: Kade <26305836+Kade-github@users.noreply.github.com> Date: Fri, 17 Jan 2025 12:37:00 -0800 Subject: [PATCH] [ENHANCEMENT] [MODDING] Several QOL modding changes (#4009) * Custom render distance strumline * Custom note positions * Custom vertices for holds * Song Retry Event Song retry event for pausesubstate.hx Song retry event for playstate.hx Song retry event for stage.hx Song retry event for bopper.hx Song retry event for song.hx Scripted class event Module event * this should be cast * Show notesplash toggle * Formatting and EOF --- source/funkin/modding/IScriptedClass.hx | 2 +- source/funkin/modding/events/ScriptEvent.hx | 22 ++++++ .../modding/events/ScriptEventDispatcher.hx | 2 +- source/funkin/modding/module/Module.hx | 2 +- source/funkin/play/PauseSubState.hx | 1 + source/funkin/play/PlayState.hx | 12 ++- source/funkin/play/notes/Strumline.hx | 78 +++++++++++++------ source/funkin/play/notes/SustainTrail.hx | 66 +++++++++++++++- source/funkin/play/song/Song.hx | 6 +- source/funkin/play/stage/Bopper.hx | 2 +- source/funkin/play/stage/Stage.hx | 2 +- 11 files changed, 161 insertions(+), 34 deletions(-) diff --git a/source/funkin/modding/IScriptedClass.hx b/source/funkin/modding/IScriptedClass.hx index 25e61996ca..11f1d5d66d 100644 --- a/source/funkin/modding/IScriptedClass.hx +++ b/source/funkin/modding/IScriptedClass.hx @@ -143,7 +143,7 @@ interface IPlayStateScriptedClass extends INoteScriptedClass extends IBPMSyncedS /** * Called when the player restarts the song, either via pause menu or restarting after a game over. */ - public function onSongRetry(event:ScriptEvent):Void; + public function onSongRetry(event:SongRetryEvent):Void; /** * Called when the player presses a key when no note is on the strumline. diff --git a/source/funkin/modding/events/ScriptEvent.hx b/source/funkin/modding/events/ScriptEvent.hx index 139da64023..7ece8d2dc8 100644 --- a/source/funkin/modding/events/ScriptEvent.hx +++ b/source/funkin/modding/events/ScriptEvent.hx @@ -414,6 +414,28 @@ class SongLoadScriptEvent extends ScriptEvent } } +/** + * AAn event that is fired when the player retries the song. + */ +class SongRetryEvent extends ScriptEvent +{ + /** + * The new difficulty of the song. + */ + public var difficulty(default, null):String; + + public function new(difficulty:String):Void + { + super(SONG_RETRY, false); + this.difficulty = difficulty; + } + + public override function toString():String + { + return 'SongRetryEvent(difficulty=$difficulty)'; + } +} + /** * An event that is fired when moving out of or into an FlxState. */ diff --git a/source/funkin/modding/events/ScriptEventDispatcher.hx b/source/funkin/modding/events/ScriptEventDispatcher.hx index 2bd9961251..15d4dfaf67 100644 --- a/source/funkin/modding/events/ScriptEventDispatcher.hx +++ b/source/funkin/modding/events/ScriptEventDispatcher.hx @@ -124,7 +124,7 @@ class ScriptEventDispatcher t.onSongEnd(event); return; case SONG_RETRY: - t.onSongRetry(event); + t.onSongRetry(cast event); return; case GAME_OVER: t.onGameOver(event); diff --git a/source/funkin/modding/module/Module.hx b/source/funkin/modding/module/Module.hx index 740e42f36e..57f0cc2dab 100644 --- a/source/funkin/modding/module/Module.hx +++ b/source/funkin/modding/module/Module.hx @@ -121,5 +121,5 @@ class Module implements IPlayStateScriptedClass implements IStateChangingScripte public function onSubStateCloseEnd(event:SubStateScriptEvent) {} - public function onSongRetry(event:ScriptEvent) {} + public function onSongRetry(event:SongRetryEvent) {} } diff --git a/source/funkin/play/PauseSubState.hx b/source/funkin/play/PauseSubState.hx index 9ff70bee57..3c9a670888 100644 --- a/source/funkin/play/PauseSubState.hx +++ b/source/funkin/play/PauseSubState.hx @@ -649,6 +649,7 @@ class PauseSubState extends MusicBeatSubState // So if you switch difficulty on the last song of a week you get a really low overall score. PlayStatePlaylist.campaignScore = 0; PlayStatePlaylist.campaignDifficulty = difficulty; + PlayState.instance.previousDifficulty = PlayState.instance.currentDifficulty; PlayState.instance.currentDifficulty = PlayStatePlaylist.campaignDifficulty; FreeplayState.rememberedDifficulty = difficulty; diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 5df12415ee..fd35690a7b 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -332,6 +332,11 @@ class PlayState extends MusicBeatSubState */ public var disableKeys:Bool = false; + /** + * The previous difficulty the player was playing on. + */ + public var previousDifficulty:String = Constants.DEFAULT_DIFFICULTY; + public var isSubState(get, never):Bool; function get_isSubState():Bool @@ -603,6 +608,7 @@ class PlayState extends MusicBeatSubState // Apply parameters. currentSong = params.targetSong; if (params.targetDifficulty != null) currentDifficulty = params.targetDifficulty; + previousDifficulty = currentDifficulty; if (params.targetVariation != null) currentVariation = params.targetVariation; if (params.targetInstrumental != null) currentInstrumental = params.targetInstrumental; isPracticeMode = params.practiceMode ?? false; @@ -813,7 +819,11 @@ class PlayState extends MusicBeatSubState prevScrollTargets = []; - dispatchEvent(new ScriptEvent(SONG_RETRY)); + var retryEvent = new SongRetryEvent(currentDifficulty); + + previousDifficulty = currentDifficulty; + + dispatchEvent(retryEvent); resetCamera(); diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index e894f9c627..1a1b43ae40 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -36,11 +36,31 @@ class Strumline extends FlxSpriteGroup static var RENDER_DISTANCE_MS(get, never):Float; + /** + * The custom render distance for the strumline. + * This should be in miliseconds only! Not pixels. + */ + public static var CUSTOM_RENDER_DISTANCE_MS:Float = 0.0; + + /** + * Whether to use the custom render distance. + * If false, the render distance will be calculated based on the screen height. + */ + public static var USE_CUSTOM_RENDER_DISTANCE:Bool = false; + static function get_RENDER_DISTANCE_MS():Float { + if (USE_CUSTOM_RENDER_DISTANCE) return CUSTOM_RENDER_DISTANCE_MS; return FlxG.height / Constants.PIXELS_PER_MS; } + /** + * Whether to play note splashes or not + * TODO: Make this a setting! + * IE: Settings.noSplash + */ + public var showNotesplash:Bool = true; + /** * Whether this strumline is controlled by the player's inputs. * False means it's controlled by the opponent or Bot Play. @@ -74,6 +94,11 @@ class Strumline extends FlxSpriteGroup return _conductorInUse = value; } + /** + * Whether the game should auto position notes. + */ + public var customPositionData:Bool = false; + /** * The notes currently being rendered on the strumline. * This group iterates over this every frame to update note positions. @@ -376,7 +401,7 @@ class Strumline extends FlxSpriteGroup var vwoosh:Bool = note.holdNoteSprite == null; // Set the note's position. - note.y = this.y - INITIAL_OFFSET + calculateNoteYPos(note.strumTime, vwoosh); + if (!customPositionData) note.y = this.y - INITIAL_OFFSET + calculateNoteYPos(note.strumTime, vwoosh); // If the note is miss var isOffscreen = Preferences.downscroll ? note.y > FlxG.height : note.y < -note.height; @@ -446,13 +471,16 @@ class Strumline extends FlxSpriteGroup var vwoosh:Bool = false; - if (Preferences.downscroll) + if (!customPositionData) { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; - } - else - { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + yOffset + STRUMLINE_SIZE / 2; + if (Preferences.downscroll) + { + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; + } + else + { + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + yOffset + STRUMLINE_SIZE / 2; + } } // Clean up the cover. @@ -475,13 +503,16 @@ class Strumline extends FlxSpriteGroup holdNote.visible = false; } - if (Preferences.downscroll) + if (!customPositionData) { - holdNote.y = this.y - INITIAL_OFFSET - holdNote.height + STRUMLINE_SIZE / 2; - } - else - { - holdNote.y = this.y - INITIAL_OFFSET + STRUMLINE_SIZE / 2; + if (Preferences.downscroll) + { + holdNote.y = this.y - INITIAL_OFFSET - holdNote.height + STRUMLINE_SIZE / 2; + } + else + { + holdNote.y = this.y - INITIAL_OFFSET + STRUMLINE_SIZE / 2; + } } } else @@ -490,13 +521,16 @@ class Strumline extends FlxSpriteGroup holdNote.visible = true; var vwoosh:Bool = false; - if (Preferences.downscroll) - { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; - } - else + if (!customPositionData) { - holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + STRUMLINE_SIZE / 2; + if (Preferences.downscroll) + { + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; + } + else + { + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + STRUMLINE_SIZE / 2; + } } } } @@ -708,8 +742,7 @@ class Strumline extends FlxSpriteGroup public function playNoteSplash(direction:NoteDirection):Void { - // TODO: Add a setting to disable note splashes. - // if (Settings.noSplash) return; + if (!showNotesplash) return; if (!noteStyle.isNoteSplashEnabled()) return; var splash:NoteSplash = this.constructNoteSplash(); @@ -729,8 +762,7 @@ class Strumline extends FlxSpriteGroup public function playNoteHoldCover(holdNote:SustainTrail):Void { - // TODO: Add a setting to disable note splashes. - // if (Settings.noSplash) return; + if (!showNotesplash) return; if (!noteStyle.isHoldNoteCoverEnabled()) return; var cover:NoteHoldCover = this.constructNoteHoldCover(); diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index a9af468b94..52241ea9c2 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -86,6 +86,11 @@ class SustainTrail extends FlxSprite */ public var bottomClip:Float = 0.9; + /** + * Whether the note will recieve custom vertex data + */ + public var customVertexData:Bool = false; + public var isPixel:Bool; public var noteStyleOffsets:Array; @@ -110,11 +115,68 @@ class SustainTrail extends FlxSprite setupHoldNoteGraphic(noteStyle); noteStyleOffsets = noteStyle.getHoldNoteOffsets(); - indices = new DrawData(12, true, TRIANGLE_VERTEX_INDICES); + setIndices(TRIANGLE_VERTEX_INDICES); this.active = true; // This NEEDS to be true for the note to be drawn! } + /** + * Sets the indices for the triangles. + * @param indices The indices to set. + */ + public function setIndices(indices:Array):Void + { + if (this.indices.length == indices.length) + { + for (i in 0...indices.length) + { + this.indices[i] = indices[i]; + } + } + else + { + this.indices = new DrawData(indices.length, false, indices); + } + } + + /** + * Sets the vertices for the triangles. + * @param vertices The vertices to set. + */ + public function setVertices(vertices:Array):Void + { + if (this.vertices.length == vertices.length) + { + for (i in 0...vertices.length) + { + this.vertices[i] = vertices[i]; + } + } + else + { + this.vertices = new DrawData(vertices.length, false, vertices); + } + } + + /** + * Sets the UV data for the triangles. + * @param uvtData The UV data to set. + */ + public function setUVTData(uvtData:Array):Void + { + if (this.uvtData.length == uvtData.length) + { + for (i in 0...uvtData.length) + { + this.uvtData[i] = uvtData[i]; + } + } + else + { + this.uvtData = new DrawData(uvtData.length, false, uvtData); + } + } + /** * Creates hold note graphic and applies correct zooming * @param noteStyle The note style @@ -214,7 +276,7 @@ class SustainTrail extends FlxSprite */ public function updateClipping(songTime:Float = 0):Void { - if (graphic == null) + if (graphic == null || customVertexData) { return; } diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 20d2f75a4c..12dbd5a52f 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -643,11 +643,11 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry