mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2025-04-21 19:31:52 -04:00
Merge 70995ae2e0
into d31ef12363
This commit is contained in:
commit
0097631437
11 changed files with 166 additions and 17 deletions
source/funkin
|
@ -193,7 +193,7 @@ class InitState extends FlxState
|
|||
|
||||
ModuleHandler.buildModuleCallbacks();
|
||||
ModuleHandler.loadModuleCache();
|
||||
ModuleHandler.callOnCreate();
|
||||
ModuleHandler.callOnGameInit();
|
||||
|
||||
funkin.input.Cursor.hide();
|
||||
|
||||
|
|
|
@ -107,6 +107,16 @@ interface IBPMSyncedScriptedClass extends IScriptedClass
|
|||
*/
|
||||
interface IPlayStateScriptedClass extends INoteScriptedClass extends IBPMSyncedScriptedClass
|
||||
{
|
||||
/**
|
||||
* Called after `PlayState` creation, right before the countdown starts.
|
||||
*/
|
||||
public function onPlayStateCreate(event:ScriptEvent):Void;
|
||||
|
||||
/**
|
||||
* Called immediately before `PlayState` cleanup.
|
||||
*/
|
||||
public function onPlayStateClose(event:ScriptEvent):Void;
|
||||
|
||||
/**
|
||||
* Called when the game is paused.
|
||||
* Has properties to set whether the pause easter egg will happen,
|
||||
|
@ -186,3 +196,21 @@ interface IDialogueScriptedClass extends IScriptedClass
|
|||
public function onDialogueSkip(event:DialogueScriptEvent):Void;
|
||||
public function onDialogueEnd(event:DialogueScriptEvent):Void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a set of callbacks available to scripted classes which are global and not tied to a specific state.
|
||||
*/
|
||||
interface IGlobalScriptedClass extends IPlayStateScriptedClass extends IStateChangingScriptedClass
|
||||
{
|
||||
/**
|
||||
* Called when the game is first initialized, before the title screen appears.
|
||||
* This event is only called once.
|
||||
*/
|
||||
public function onGameInit(event:ScriptEvent):Void;
|
||||
|
||||
/**
|
||||
* Called when the game is closed for any reason.
|
||||
* This event is only called once.
|
||||
*/
|
||||
public function onGameClose(event:GameCloseScriptEvent):Void;
|
||||
}
|
||||
|
|
|
@ -511,3 +511,20 @@ class PauseScriptEvent extends ScriptEvent
|
|||
this.gitaroo = gitaroo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An event which is called when the game is closed for any reason.
|
||||
*/
|
||||
class GameCloseScriptEvent extends ScriptEvent
|
||||
{
|
||||
/**
|
||||
* The exit code. Any non-zero value is likely an error.
|
||||
*/
|
||||
public var exitCode(default, null):Int;
|
||||
|
||||
public function new(exitCode:Int):Void
|
||||
{
|
||||
super(GAME_CLOSE, false);
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package funkin.modding.events;
|
||||
|
||||
import funkin.modding.IScriptedClass.IPlayStateScriptedClass;
|
||||
import funkin.modding.IScriptedClass;
|
||||
|
||||
/**
|
||||
|
@ -114,6 +113,12 @@ class ScriptEventDispatcher
|
|||
var t:IPlayStateScriptedClass = cast(target, IPlayStateScriptedClass);
|
||||
switch (event.type)
|
||||
{
|
||||
case PLAYSTATE_CREATE:
|
||||
t.onPlayStateCreate(event);
|
||||
return;
|
||||
case PLAYSTATE_CLOSE:
|
||||
t.onPlayStateClose(event);
|
||||
return;
|
||||
case NOTE_GHOST_MISS:
|
||||
t.onNoteGhostMiss(cast event);
|
||||
return;
|
||||
|
@ -186,6 +191,21 @@ class ScriptEventDispatcher
|
|||
default: // Continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Std.isOfType(target, IGlobalScriptedClass))
|
||||
{
|
||||
var t = cast(target, IGlobalScriptedClass);
|
||||
switch (event.type)
|
||||
{
|
||||
case GAME_INIT:
|
||||
t.onGameInit(event);
|
||||
return;
|
||||
case GAME_CLOSE:
|
||||
t.onGameClose(cast event);
|
||||
return;
|
||||
default: // Continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prevent "NO HELPER error."
|
||||
|
|
|
@ -2,6 +2,22 @@ package funkin.modding.events;
|
|||
|
||||
enum abstract ScriptEventType(String) from String to String
|
||||
{
|
||||
/**
|
||||
* Called when the game is first initialized, before the title screen appears.
|
||||
* This event is only called once.
|
||||
*
|
||||
* This event is not cancelable.
|
||||
*/
|
||||
var GAME_INIT = 'GAME_INIT';
|
||||
|
||||
/**
|
||||
* Called when the game is closed for any reason.
|
||||
* This event is only called once.
|
||||
*
|
||||
* This event is not cancelable.
|
||||
*/
|
||||
var GAME_CLOSE = 'GAME_CLOSE';
|
||||
|
||||
/**
|
||||
* Called when the relevant object is created.
|
||||
* Keep in mind that the constructor may be called before the object is needed,
|
||||
|
@ -35,6 +51,20 @@ enum abstract ScriptEventType(String) from String to String
|
|||
*/
|
||||
var UPDATE = 'UPDATE';
|
||||
|
||||
/**
|
||||
* Called after `PlayState` creation, right before the countdown starts.
|
||||
*
|
||||
* This event is not cancelable.
|
||||
*/
|
||||
var PLAYSTATE_CREATE = 'PLAYSTATE_CREATE';
|
||||
|
||||
/**
|
||||
* Called immediately before `PlayState` cleanup.
|
||||
*
|
||||
* This event is not cancelable.
|
||||
*/
|
||||
var PLAYSTATE_CLOSE = 'PLAYSTATE_CLOSE';
|
||||
|
||||
/**
|
||||
* Called when the player moves to pause the game.
|
||||
*
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package funkin.modding.module;
|
||||
|
||||
import funkin.modding.IScriptedClass.IPlayStateScriptedClass;
|
||||
import funkin.modding.IScriptedClass.IStateChangingScriptedClass;
|
||||
import funkin.modding.IScriptedClass.IGlobalScriptedClass;
|
||||
import funkin.modding.events.ScriptEvent;
|
||||
|
||||
/**
|
||||
* A module is a scripted class which receives all events without requiring a specific context.
|
||||
* You may have the module active at all times, or only when another script enables it.
|
||||
*/
|
||||
class Module implements IPlayStateScriptedClass implements IStateChangingScriptedClass
|
||||
class Module implements IGlobalScriptedClass
|
||||
{
|
||||
/**
|
||||
* Whether the module is currently active.
|
||||
|
@ -60,19 +59,35 @@ class Module implements IPlayStateScriptedClass implements IStateChangingScripte
|
|||
public function onScriptEvent(event:ScriptEvent) {}
|
||||
|
||||
/**
|
||||
* Called when the module is first created.
|
||||
* This happens before the title screen appears!
|
||||
* Called when the game is first initialized, before the title screen appears.
|
||||
* This happens only once, immediately after the module's first `onCreate` event.
|
||||
*/
|
||||
public function onGameInit(event:ScriptEvent) {}
|
||||
|
||||
/**
|
||||
* Called when the game is closed for any reason.
|
||||
* This happens only once, immediately before the module's last `onDestroy` event.
|
||||
*/
|
||||
public function onGameClose(event:GameCloseScriptEvent) {}
|
||||
|
||||
/**
|
||||
* Called when the module is created.
|
||||
* This happens when the game is first initialized or after a mod reload.
|
||||
*/
|
||||
public function onCreate(event:ScriptEvent) {}
|
||||
|
||||
/**
|
||||
* Called when a module is destroyed.
|
||||
* This currently only happens when reloading modules with F5.
|
||||
* This happens when reloading modules with F5 or when the game is closed.
|
||||
*/
|
||||
public function onDestroy(event:ScriptEvent) {}
|
||||
|
||||
public function onUpdate(event:UpdateScriptEvent) {}
|
||||
|
||||
public function onPlayStateCreate(event:ScriptEvent) {}
|
||||
|
||||
public function onPlayStateClose(event:ScriptEvent) {}
|
||||
|
||||
public function onPause(event:PauseScriptEvent) {}
|
||||
|
||||
public function onResume(event:ScriptEvent) {}
|
||||
|
|
|
@ -6,6 +6,7 @@ import funkin.modding.events.ScriptEvent;
|
|||
import funkin.modding.events.ScriptEventDispatcher;
|
||||
import funkin.modding.module.Module;
|
||||
import funkin.modding.module.ScriptedModule;
|
||||
import funkin.util.WindowUtil;
|
||||
|
||||
/**
|
||||
* Utility functions for loading and manipulating active modules.
|
||||
|
@ -46,11 +47,15 @@ class ModuleHandler
|
|||
reorderModuleCache();
|
||||
|
||||
trace("[MODULEHANDLER] Module cache loaded.");
|
||||
|
||||
callEvent(new ScriptEvent(CREATE, false), true);
|
||||
}
|
||||
|
||||
public static function buildModuleCallbacks():Void
|
||||
{
|
||||
FlxG.signals.postStateSwitch.add(onStateSwitchComplete);
|
||||
|
||||
WindowUtil.windowExit.add(callOnGameClose);
|
||||
}
|
||||
|
||||
static function onStateSwitchComplete():Void
|
||||
|
@ -122,9 +127,14 @@ class ModuleHandler
|
|||
var event = new ScriptEvent(DESTROY, false);
|
||||
|
||||
// Note: Ignore stopPropagation()
|
||||
for (key => value in moduleCache)
|
||||
for (i in 0...modulePriorityOrder.length)
|
||||
{
|
||||
ScriptEventDispatcher.callEvent(value, event);
|
||||
var moduleId = modulePriorityOrder[modulePriorityOrder.length - 1 - i];
|
||||
var module:Module = moduleCache.get(moduleId);
|
||||
if (module != null)
|
||||
{
|
||||
ScriptEventDispatcher.callEvent(module, event);
|
||||
}
|
||||
}
|
||||
|
||||
moduleCache.clear();
|
||||
|
@ -132,21 +142,26 @@ class ModuleHandler
|
|||
}
|
||||
}
|
||||
|
||||
public static function callEvent(event:ScriptEvent):Void
|
||||
public static function callEvent(event:ScriptEvent, force:Bool = false):Void
|
||||
{
|
||||
for (moduleId in modulePriorityOrder)
|
||||
{
|
||||
var module:Module = moduleCache.get(moduleId);
|
||||
// The module needs to be active to receive events.
|
||||
if (module != null && module.active)
|
||||
if (module != null && (module.active || force))
|
||||
{
|
||||
ScriptEventDispatcher.callEvent(module, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static inline function callOnCreate():Void
|
||||
public static inline function callOnGameInit():Void
|
||||
{
|
||||
callEvent(new ScriptEvent(CREATE, false));
|
||||
callEvent(new ScriptEvent(GAME_INIT, false));
|
||||
}
|
||||
|
||||
public static inline function callOnGameClose(exitCode:Int):Void
|
||||
{
|
||||
callEvent(new GameCloseScriptEvent(exitCode));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -720,6 +720,9 @@ class PlayState extends MusicBeatSubState
|
|||
|
||||
FlxG.worldBounds.set(0, 0, FlxG.width, FlxG.height);
|
||||
|
||||
// Dispatch the `PlayState` create event.
|
||||
dispatchEvent(new ScriptEvent(PLAYSTATE_CREATE, false));
|
||||
|
||||
// The song is loaded and in the process of starting.
|
||||
// This gets set back to false when the chart actually starts.
|
||||
startingSong = true;
|
||||
|
@ -1185,7 +1188,7 @@ class PlayState extends MusicBeatSubState
|
|||
// Modules should get the first chance to cancel the event.
|
||||
|
||||
// super.dispatchEvent(event) dispatches event to module scripts.
|
||||
super.dispatchEvent(event);
|
||||
if (event.type != DESTROY) super.dispatchEvent(event);
|
||||
|
||||
// Dispatch event to note kind scripts
|
||||
NoteKindManager.callEvent(event);
|
||||
|
@ -3185,11 +3188,18 @@ class PlayState extends MusicBeatSubState
|
|||
super.close();
|
||||
}
|
||||
|
||||
private var cleanupDone:Bool = false;
|
||||
|
||||
/**
|
||||
* Perform necessary cleanup before leaving the PlayState.
|
||||
*/
|
||||
* Perform necessary cleanup before leaving the PlayState.
|
||||
*/
|
||||
function performCleanup():Void
|
||||
{
|
||||
if (cleanupDone) return;
|
||||
|
||||
// Dispatch the `PlayState` close event.
|
||||
dispatchEvent(new ScriptEvent(PLAYSTATE_CLOSE, false));
|
||||
|
||||
// If the camera is being tweened, stop it.
|
||||
cancelAllCameraTweens();
|
||||
|
||||
|
@ -3242,6 +3252,8 @@ class PlayState extends MusicBeatSubState
|
|||
|
||||
// Clear the static reference to this state.
|
||||
instance = null;
|
||||
|
||||
cleanupDone = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -631,6 +631,10 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
|
||||
public function destroy():Void {}
|
||||
|
||||
public function onPlayStateCreate(event:ScriptEvent) {}
|
||||
|
||||
public function onPlayStateClose(event:ScriptEvent) {}
|
||||
|
||||
public function onPause(event:PauseScriptEvent):Void {};
|
||||
|
||||
public function onResume(event:ScriptEvent):Void {};
|
||||
|
|
|
@ -357,6 +357,10 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
return output;
|
||||
}
|
||||
|
||||
public function onPlayStateCreate(event:ScriptEvent) {}
|
||||
|
||||
public function onPlayStateClose(event:ScriptEvent) {}
|
||||
|
||||
public function onPause(event:PauseScriptEvent) {}
|
||||
|
||||
public function onResume(event:ScriptEvent) {}
|
||||
|
|
|
@ -879,6 +879,10 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
|
|||
}
|
||||
}
|
||||
|
||||
public function onPlayStateCreate(event:ScriptEvent) {}
|
||||
|
||||
public function onPlayStateClose(event:ScriptEvent) {}
|
||||
|
||||
public function onPause(event:PauseScriptEvent) {}
|
||||
|
||||
public function onResume(event:ScriptEvent) {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue