From 059e1c0e13c9560edbe3454e6cf7ae9be8b3886a Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 5 Mar 2024 21:48:04 -0500 Subject: [PATCH] Implement onNoteIncoming script event. --- assets | 2 +- source/funkin/modding/IScriptedClass.hx | 28 ++++++++++--------- .../modding/events/ScriptEventDispatcher.hx | 16 +++++++++-- .../funkin/modding/events/ScriptEventType.hx | 7 +++++ source/funkin/modding/module/Module.hx | 4 ++- source/funkin/play/PlayState.hx | 13 +++++++-- source/funkin/play/character/BaseCharacter.hx | 2 +- source/funkin/play/notes/Strumline.hx | 7 +++++ source/funkin/play/song/Song.hx | 4 ++- source/funkin/play/stage/Bopper.hx | 4 ++- source/funkin/play/stage/Stage.hx | 4 ++- .../ui/debug/charting/ChartEditorState.hx | 2 +- .../ui/haxeui/components/CharacterPlayer.hx | 8 +++++- 13 files changed, 76 insertions(+), 25 deletions(-) diff --git a/assets b/assets index 69ebdb6a7..518349369 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 69ebdb6a7aa57b6762ce509243679ab959615120 +Subproject commit 518349369ea3237504e8100c901313185bb5b80f diff --git a/source/funkin/modding/IScriptedClass.hx b/source/funkin/modding/IScriptedClass.hx index b009aea41..5f2ff2b9e 100644 --- a/source/funkin/modding/IScriptedClass.hx +++ b/source/funkin/modding/IScriptedClass.hx @@ -56,7 +56,20 @@ interface IStateStageProp extends IScriptedClass */ interface INoteScriptedClass extends IScriptedClass { - public function onNoteHit(event:NoteScriptEvent):Void; + /** + * Called when a note enters the field of view and approaches the strumline. + */ + public function onNoteIncoming(event:NoteScriptEvent):Void; + + /** + * Called when EITHER player hits a note. + * Query the note attached to the event to determine if it was hit by the player or CPU. + */ + public function onNoteHit(event:HitNoteScriptEvent):Void; + + /** + * Called when EITHER player (usually the player) misses a note. + */ public function onNoteMiss(event:NoteScriptEvent):Void; } @@ -73,7 +86,7 @@ interface INoteScriptedClass extends IScriptedClass /** * Defines a set of callbacks available to scripted classes that involve the lifecycle of the Play State. */ -interface IPlayStateScriptedClass extends IScriptedClass +interface IPlayStateScriptedClass extends INoteScriptedClass { /** * Called when the game is paused. @@ -113,17 +126,6 @@ interface IPlayStateScriptedClass extends IScriptedClass */ public function onSongRetry(event:ScriptEvent):Void; - /** - * Called when EITHER player hits a note. - * Query the note attached to the event to determine if it was hit by the player or CPU. - */ - public function onNoteHit(event:NoteScriptEvent):Void; - - /** - * Called when EITHER player (usually the player) misses a note. - */ - public function onNoteMiss(event:NoteScriptEvent):Void; - /** * Called when the player presses a key when no note is on the strumline. */ diff --git a/source/funkin/modding/events/ScriptEventDispatcher.hx b/source/funkin/modding/events/ScriptEventDispatcher.hx index f5d797ea4..fd58d0fad 100644 --- a/source/funkin/modding/events/ScriptEventDispatcher.hx +++ b/source/funkin/modding/events/ScriptEventDispatcher.hx @@ -71,17 +71,29 @@ class ScriptEventDispatcher } } - if (Std.isOfType(target, IPlayStateScriptedClass)) + if (Std.isOfType(target, INoteScriptedClass)) { - var t:IPlayStateScriptedClass = cast(target, IPlayStateScriptedClass); + var t:INoteScriptedClass = cast(target, INoteScriptedClass); switch (event.type) { + case NOTE_INCOMING: + t.onNoteIncoming(cast event); + return; case NOTE_HIT: t.onNoteHit(cast event); return; case NOTE_MISS: t.onNoteMiss(cast event); return; + default: // Continue; + } + } + + if (Std.isOfType(target, IPlayStateScriptedClass)) + { + var t:IPlayStateScriptedClass = cast(target, IPlayStateScriptedClass); + switch (event.type) + { case NOTE_GHOST_MISS: t.onNoteGhostMiss(cast event); return; diff --git a/source/funkin/modding/events/ScriptEventType.hx b/source/funkin/modding/events/ScriptEventType.hx index e06b5ad24..eeeb8ef29 100644 --- a/source/funkin/modding/events/ScriptEventType.hx +++ b/source/funkin/modding/events/ScriptEventType.hx @@ -63,6 +63,13 @@ enum abstract ScriptEventType(String) from String to String */ var SONG_STEP_HIT = 'STEP_HIT'; + /** + * Called when a note comes on screen and starts approaching the strumline. + * + * This event is not cancelable. + */ + var NOTE_INCOMING = 'NOTE_INCOMING'; + /** * Called when a character hits a note. * Important information such as judgement/timing, note data, player/opponent, etc. are all provided. diff --git a/source/funkin/modding/module/Module.hx b/source/funkin/modding/module/Module.hx index f50c9936a..be9b7146b 100644 --- a/source/funkin/modding/module/Module.hx +++ b/source/funkin/modding/module/Module.hx @@ -83,7 +83,9 @@ class Module implements IPlayStateScriptedClass implements IStateChangingScripte public function onGameOver(event:ScriptEvent) {} - public function onNoteHit(event:NoteScriptEvent) {} + public function onNoteIncoming(event:NoteScriptEvent) {} + + public function onNoteHit(event:HitNoteScriptEvent) {} public function onNoteMiss(event:NoteScriptEvent) {} diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index e7ad326d2..5564c46c2 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1614,8 +1614,10 @@ class PlayState extends MusicBeatSubState var noteStyle:NoteStyle = NoteStyleRegistry.instance.fetchEntry(noteStyleId); if (noteStyle == null) noteStyle = NoteStyleRegistry.instance.fetchDefault(); - playerStrumline = new Strumline(noteStyle, true); + playerStrumline = new Strumline(noteStyle, !isBotPlayMode); + playerStrumline.onNoteIncoming.add(onStrumlineNoteIncoming); opponentStrumline = new Strumline(noteStyle, false); + opponentStrumline.onNoteIncoming.add(onStrumlineNoteIncoming); add(playerStrumline); add(opponentStrumline); @@ -1751,6 +1753,13 @@ class PlayState extends MusicBeatSubState opponentStrumline.applyNoteData(opponentNoteData); } + function onStrumlineNoteIncoming(noteSprite:NoteSprite):Void + { + var event:NoteScriptEvent = new NoteScriptEvent(NOTE_INCOMING, noteSprite, 0, false); + + dispatchEvent(event); + } + /** * Prepares to start the countdown. * Ends any running cutscenes, creates the strumlines, and starts the countdown. @@ -1942,7 +1951,7 @@ class PlayState extends MusicBeatSubState // Call an event to allow canceling the note hit. // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new NoteScriptEvent(NOTE_HIT, note, 0, true); + var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index cf5311bdc..d39f19b76 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -485,7 +485,7 @@ class BaseCharacter extends Bopper * Every time a note is hit, check if the note is from the same strumline. * If it is, then play the sing animation. */ - public override function onNoteHit(event:NoteScriptEvent) + public override function onNoteHit(event:HitNoteScriptEvent) { super.onNoteHit(event); diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 190aa3ee0..1ba5dcfc5 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -1,5 +1,6 @@ package funkin.play.notes; +import flixel.util.FlxSignal.FlxTypedSignal; import flixel.FlxG; import funkin.play.notes.notestyle.NoteStyle; import flixel.group.FlxSpriteGroup; @@ -49,6 +50,8 @@ class Strumline extends FlxSpriteGroup public var holdNotes:FlxTypedSpriteGroup; + public var onNoteIncoming:FlxTypedSignalVoid>; + var strumlineNotes:FlxTypedSpriteGroup; var noteSplashes:FlxTypedSpriteGroup; var noteHoldCovers:FlxTypedSpriteGroup; @@ -106,6 +109,8 @@ class Strumline extends FlxSpriteGroup this.refresh(); + this.onNoteIncoming = new FlxTypedSignalVoid>(); + for (i in 0...KEY_COUNT) { var child:StrumlineNote = new StrumlineNote(noteStyle, isPlayer, DIRECTIONS[i]); @@ -311,6 +316,8 @@ class Strumline extends FlxSpriteGroup } nextNoteIndex = noteIndex + 1; // Increment the nextNoteIndex rather than splicing the array, because splicing is slow. + + onNoteIncoming.dispatch(noteSprite); } // Update rendering of notes. diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 61f83d1ed..3997692c2 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -364,7 +364,9 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry