2022-03-11 06:30:01 +00:00
|
|
|
package funkin.modding.events;
|
|
|
|
|
|
|
|
import funkin.modding.IScriptedClass.IPlayStateScriptedClass;
|
2022-04-18 23:36:09 +00:00
|
|
|
import funkin.modding.IScriptedClass;
|
2022-03-11 06:30:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Utility functions to assist with handling scripted classes.
|
|
|
|
*/
|
|
|
|
class ScriptEventDispatcher
|
|
|
|
{
|
2024-03-16 04:55:57 +00:00
|
|
|
/**
|
|
|
|
* Invoke the given event hook on the given scripted class.
|
|
|
|
* @param target The target class to call script hooks on.
|
|
|
|
* @param event The event, which determines the script hook to call and provides parameters for it.
|
|
|
|
*/
|
|
|
|
public static function callEvent(target:Null<IScriptedClass>, event:ScriptEvent):Void
|
2023-01-23 03:25:45 +00:00
|
|
|
{
|
|
|
|
if (target == null || event == null) return;
|
2022-03-13 18:36:03 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
target.onScriptEvent(event);
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
// If one target says to stop propagation, stop.
|
|
|
|
if (!event.shouldPropagate)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
// IScriptedClass
|
|
|
|
switch (event.type)
|
|
|
|
{
|
2023-10-26 09:46:22 +00:00
|
|
|
case CREATE:
|
2023-01-23 03:25:45 +00:00
|
|
|
target.onCreate(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case DESTROY:
|
2023-01-23 03:25:45 +00:00
|
|
|
target.onDestroy(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case UPDATE:
|
2023-01-23 03:25:45 +00:00
|
|
|
target.onUpdate(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
default: // Continue;
|
2023-01-23 03:25:45 +00:00
|
|
|
}
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-05-26 21:10:08 +00:00
|
|
|
if (Std.isOfType(target, IStateStageProp))
|
|
|
|
{
|
|
|
|
var t:IStateStageProp = cast(target, IStateStageProp);
|
|
|
|
switch (event.type)
|
|
|
|
{
|
2023-10-26 09:46:22 +00:00
|
|
|
case ADDED:
|
2023-05-26 21:10:08 +00:00
|
|
|
t.onAdd(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
default: // Continue;
|
2023-05-26 21:10:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-16 21:37:56 +00:00
|
|
|
if (Std.isOfType(target, IDialogueScriptedClass))
|
|
|
|
{
|
|
|
|
var t:IDialogueScriptedClass = cast(target, IDialogueScriptedClass);
|
|
|
|
switch (event.type)
|
|
|
|
{
|
2023-10-26 09:46:22 +00:00
|
|
|
case DIALOGUE_START:
|
2023-06-16 21:37:56 +00:00
|
|
|
t.onDialogueStart(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case DIALOGUE_LINE:
|
2023-06-16 21:37:56 +00:00
|
|
|
t.onDialogueLine(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case DIALOGUE_COMPLETE_LINE:
|
2023-06-16 21:37:56 +00:00
|
|
|
t.onDialogueCompleteLine(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case DIALOGUE_SKIP:
|
2023-06-16 21:37:56 +00:00
|
|
|
t.onDialogueSkip(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case DIALOGUE_END:
|
2023-06-16 21:37:56 +00:00
|
|
|
t.onDialogueEnd(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
default: // Continue;
|
2023-06-16 21:37:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-06 02:48:04 +00:00
|
|
|
if (Std.isOfType(target, INoteScriptedClass))
|
2023-01-23 03:25:45 +00:00
|
|
|
{
|
2024-03-06 02:48:04 +00:00
|
|
|
var t:INoteScriptedClass = cast(target, INoteScriptedClass);
|
2023-01-23 03:25:45 +00:00
|
|
|
switch (event.type)
|
|
|
|
{
|
2024-03-06 02:48:04 +00:00
|
|
|
case NOTE_INCOMING:
|
|
|
|
t.onNoteIncoming(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case NOTE_HIT:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onNoteHit(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case NOTE_MISS:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onNoteMiss(cast event);
|
|
|
|
return;
|
2024-03-06 02:48:04 +00:00
|
|
|
default: // Continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Std.isOfType(target, IPlayStateScriptedClass))
|
|
|
|
{
|
|
|
|
var t:IPlayStateScriptedClass = cast(target, IPlayStateScriptedClass);
|
|
|
|
switch (event.type)
|
|
|
|
{
|
2023-10-26 09:46:22 +00:00
|
|
|
case NOTE_GHOST_MISS:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onNoteGhostMiss(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_BEAT_HIT:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onBeatHit(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_STEP_HIT:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onStepHit(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_START:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onSongStart(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_END:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onSongEnd(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_RETRY:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onSongRetry(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case GAME_OVER:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onGameOver(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case PAUSE:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onPause(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case RESUME:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onResume(event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_EVENT:
|
2023-04-20 17:48:15 +00:00
|
|
|
t.onSongEvent(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case COUNTDOWN_START:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onCountdownStart(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case COUNTDOWN_STEP:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onCountdownStep(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case COUNTDOWN_END:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onCountdownEnd(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SONG_LOADED:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onSongLoaded(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
default: // Continue;
|
2023-01-23 03:25:45 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
if (Std.isOfType(target, IStateChangingScriptedClass))
|
|
|
|
{
|
|
|
|
var t = cast(target, IStateChangingScriptedClass);
|
|
|
|
switch (event.type)
|
|
|
|
{
|
2023-10-26 09:46:22 +00:00
|
|
|
case STATE_CHANGE_BEGIN:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onStateChangeBegin(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case STATE_CHANGE_END:
|
2023-01-23 03:25:45 +00:00
|
|
|
t.onStateChangeEnd(cast event);
|
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SUBSTATE_OPEN_BEGIN:
|
2023-06-09 19:44:29 +00:00
|
|
|
t.onSubStateOpenBegin(cast event);
|
2023-01-23 03:25:45 +00:00
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SUBSTATE_OPEN_END:
|
2023-06-09 19:44:29 +00:00
|
|
|
t.onSubStateOpenEnd(cast event);
|
2023-01-23 03:25:45 +00:00
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SUBSTATE_CLOSE_BEGIN:
|
2023-06-09 19:44:29 +00:00
|
|
|
t.onSubStateCloseBegin(cast event);
|
2023-01-23 03:25:45 +00:00
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
case SUBSTATE_CLOSE_END:
|
2023-06-09 19:44:29 +00:00
|
|
|
t.onSubStateCloseEnd(cast event);
|
2023-01-23 03:25:45 +00:00
|
|
|
return;
|
2023-10-26 09:46:22 +00:00
|
|
|
default: // Continue;
|
2023-01-23 03:25:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Prevent "NO HELPER error."
|
|
|
|
return;
|
|
|
|
}
|
2022-04-18 23:36:09 +00:00
|
|
|
|
2023-04-20 17:48:15 +00:00
|
|
|
// If you get a crash on this line, that means ERIC FUCKED UP!
|
2023-06-16 21:37:56 +00:00
|
|
|
// throw 'No function called for event type: ${event.type}';
|
2023-01-23 03:25:45 +00:00
|
|
|
}
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
public static function callEventOnAllTargets(targets:Iterator<IScriptedClass>, event:ScriptEvent):Void
|
|
|
|
{
|
|
|
|
if (targets == null || event == null) return;
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
if (Std.isOfType(targets, Array))
|
|
|
|
{
|
|
|
|
var t = cast(targets, Array<Dynamic>);
|
|
|
|
if (t.length == 0) return;
|
|
|
|
}
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
for (target in targets)
|
|
|
|
{
|
|
|
|
var t:IScriptedClass = cast target;
|
|
|
|
if (t == null) continue;
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
callEvent(t, event);
|
2022-03-11 06:30:01 +00:00
|
|
|
|
2023-01-23 03:25:45 +00:00
|
|
|
// If one target says to stop propagation, stop.
|
|
|
|
if (!event.shouldPropagate)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-03-11 06:30:01 +00:00
|
|
|
}
|