diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index eca0c466..b0a9980e 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -9,6 +9,7 @@ import flixel.FlxState; import flixel.FlxSubState; import funkin.backend.scripting.events.*; import funkin.backend.scripting.Script; +import funkin.backend.scripting.ScriptPack; import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.system.Conductor; import funkin.options.PlayerSettings; @@ -89,7 +90,7 @@ class MusicBeatState extends FlxState implements IBeatReceiver /** * Current injected script attached to the state. To add one, create a file at path "data/states/stateName" (ex: data/states/FreeplayState) */ - public var stateScript:Script; + public var stateScripts:ScriptPack; public var scriptsAllowed:Bool = true; @@ -113,14 +114,21 @@ class MusicBeatState extends FlxState implements IBeatReceiver function loadScript() { if (scriptsAllowed) { - if (stateScript == null || stateScript is DummyScript) { - var className = Type.getClassName(Type.getClass(this)); + var className = Type.getClassName(Type.getClass(this)); + if (stateScripts == null) + (stateScripts = new ScriptPack(className)).setParent(this); + if (stateScripts.scripts.length == 0) { var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1); - stateScript = Script.create(Paths.script('data/states/${scriptName}')); - stateScript.setParent(this); - stateScript.load(); - } else - stateScript.reload(); + for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { + var path = Paths.script('data/states/${scriptName}/LIB_$i'); + var script = Script.create(path); + if (script is DummyScript) continue; + script.fileName = '$i:$scriptName'; + stateScripts.add(script); + script.load(); + } + } + else stateScripts.reload(); } } @@ -161,13 +169,11 @@ class MusicBeatState extends FlxState implements IBeatReceiver } public function call(name:String, ?args:Array, ?defaultVal:Dynamic):Dynamic { // calls the function on the assigned script - if (stateScript == null) return defaultVal; - return stateScript.call(name, args); + return stateScripts.call(name, args); } public function event(name:String, event:T):T { - if (stateScript == null) return event; - stateScript.call(name, [event]); + stateScripts.call(name, [event]); return event; } @@ -176,8 +182,6 @@ class MusicBeatState extends FlxState implements IBeatReceiver // TODO: DEBUG MODE!! if (FlxG.keys.justPressed.F5) { loadScript(); - if (stateScript != null && !(stateScript is DummyScript)) - Logs.trace('State script successfully reloaded', WARNING, GREEN); } call("update", [elapsed]); @@ -234,8 +238,7 @@ class MusicBeatState extends FlxState implements IBeatReceiver super.destroy(); graphicCache.destroy(); call("onDestroy"); - if (stateScript != null) - stateScript.destroy(); + stateScripts = FlxDestroyUtil.destroy(stateScripts); } public override function draw() { diff --git a/source/funkin/backend/MusicBeatSubstate.hx b/source/funkin/backend/MusicBeatSubstate.hx index d1d96f43..b7987f7d 100644 --- a/source/funkin/backend/MusicBeatSubstate.hx +++ b/source/funkin/backend/MusicBeatSubstate.hx @@ -3,6 +3,7 @@ package funkin.backend; import flixel.FlxState; import funkin.backend.scripting.events.*; import funkin.backend.scripting.Script; +import funkin.backend.scripting.ScriptPack; import funkin.backend.scripting.DummyScript; import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.system.Conductor.BPMChangeEvent; @@ -63,7 +64,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver /** * Current injected script attached to the state. To add one, create a file at path "data/states/stateName" (ex: "data/states/PauseMenuSubstate.hx") */ - public var stateScript:Script; + public var stateScripts:ScriptPack; public var scriptsAllowed:Bool = true; @@ -100,14 +101,21 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver function loadScript() { if (scriptsAllowed) { - if (stateScript == null || stateScript is DummyScript) { - var className = Type.getClassName(Type.getClass(this)); + var className = Type.getClassName(Type.getClass(this)); + if (stateScripts == null) + (stateScripts = new ScriptPack(className)).setParent(this); + if (stateScripts.scripts.length == 0) { var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1); - stateScript = Script.create(Paths.script('data/states/${scriptName}')); - stateScript.setParent(this); - stateScript.load(); - } else - stateScript.reload(); + for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { + var path = Paths.script('data/states/${scriptName}/LIB_$i'); + var script = Script.create(path); + if (script is DummyScript) continue; + script.fileName = '$i:$scriptName'; + stateScripts.add(script); + script.load(); + } + } + else stateScripts.reload(); } } @@ -151,13 +159,11 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver } public function call(name:String, ?args:Array, ?defaultVal:Dynamic):Dynamic { // calls the function on the assigned script - if (stateScript == null) return defaultVal; - return stateScript.call(name, args); + return stateScripts.call(name, args); } public function event(name:String, event:T):T { - if (stateScript == null) return event; - stateScript.call(name, [event]); + stateScripts.call(name, [event]); return event; } @@ -166,8 +172,6 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver // TODO: DEBUG MODE!! if (FlxG.keys.justPressed.F5) { loadScript(); - if (stateScript != null && !(stateScript is DummyScript)) - Logs.trace('State script successfully reloaded', WARNING, GREEN); } call("update", [elapsed]); super.update(elapsed); @@ -222,8 +226,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver public override function destroy() { super.destroy(); call("onDestroy"); - if(stateScript != null) - stateScript.destroy(); + stateScripts = FlxDestroyUtil.destroy(stateScripts); } public override function switchTo(nextState:FlxState) { diff --git a/source/funkin/backend/assets/ModsFolder.hx b/source/funkin/backend/assets/ModsFolder.hx index fc37ed52..a88377ad 100644 --- a/source/funkin/backend/assets/ModsFolder.hx +++ b/source/funkin/backend/assets/ModsFolder.hx @@ -89,6 +89,22 @@ class ModsFolder { #end } + public static function getLoadedMods():Array { + var libs = []; + for (i in Paths.assetsTree.libraries) { + var l = i; + if (l is openfl.utils.AssetLibrary) { + var al = cast(l, openfl.utils.AssetLibrary); + @:privateAccess + if (al.__proxy != null) l = al.__proxy; + } + var libString:String; + if (l is ScriptedAssetLibrary || l is IModsAssetLibrary) libString = cast(l, IModsAssetLibrary).modName; + else continue; + libs.push(libString); + } + return libs; + } public static function prepareLibrary(libName:String, force:Bool = false) { var assets:AssetManifest = new AssetManifest(); assets.name = libName; diff --git a/source/funkin/backend/assets/ScriptedAssetLibrary.hx b/source/funkin/backend/assets/ScriptedAssetLibrary.hx index 0b72a426..a5087be3 100644 --- a/source/funkin/backend/assets/ScriptedAssetLibrary.hx +++ b/source/funkin/backend/assets/ScriptedAssetLibrary.hx @@ -23,7 +23,7 @@ class ScriptedAssetLibrary extends ModsFolderLibrary { public function new(scriptName:String, args:Array = null, folderPath:String="./assets/", libName:String="assets", ?modName:String) { super(folderPath, libName, modName); - + if(modName == null) modName = scriptName; this.scriptName = scriptName; script = Script.create(Paths.script("data/library/" + scriptName)); script.setParent(this); diff --git a/source/funkin/backend/scripting/GlobalScript.hx b/source/funkin/backend/scripting/GlobalScript.hx index d6d10000..dbca645c 100644 --- a/source/funkin/backend/scripting/GlobalScript.hx +++ b/source/funkin/backend/scripting/GlobalScript.hx @@ -9,7 +9,7 @@ import funkin.backend.assets.ModsFolder; * Class for THE Global Script, aka script that runs in the background at all times. */ class GlobalScript { - public static var script:Script; + public static var scripts:ScriptPack; public static function init() { #if MOD_SUPPORT @@ -43,17 +43,13 @@ class GlobalScript { FlxG.signals.postUpdate.add(function() { call("postUpdate", [FlxG.elapsed]); if (FlxG.keys.justPressed.F5) { - if (script != null && !(script is DummyScript)) { + if (scripts.scripts.length > 0) { Logs.trace('Reloading global script...', WARNING, YELLOW); - script.reload(); + scripts.reload(); Logs.trace('Global script successfully reloaded.', WARNING, GREEN); } else { Logs.trace('Loading global script...', WARNING, YELLOW); onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end); - if (script is DummyScript) - Logs.trace('Global script not found. Are you sure "data/global.hx" exists?', ERROR, RED); - else - Logs.trace('Global script successfully loaded.', WARNING, GREEN); } } if (FlxG.keys.justPressed.F2) @@ -83,23 +79,25 @@ class GlobalScript { } public static function event(name:String, event:T):T { - if (script == null) return event; - script.call(name, [event]); + if (scripts != null) scripts.call(name, [event]); return event; } public static function call(name:String, ?args:Array) { - if (script == null) return; - script.call(name, args); + if (scripts != null) scripts.call(name, args); } public static function onModSwitch(newMod:String) { call("onDestroy"); - if (script != null) { - script.destroy(); - script = null; + scripts = FlxDestroyUtil.destroy(scripts); + scripts = new ScriptPack("GlobalScript"); + for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { + var path = Paths.script('data/global/LIB_$i'); + var script = Script.create(path); + if (script is DummyScript) continue; + script.fileName = '$i:global.hx'; + scripts.add(script); + script.load(); } - script = Script.create(Paths.script('data/global')); - script.load(); } public static function beatHit(curBeat:Int) {