global scripts
This commit is contained in:
@@ -160,4 +160,7 @@
|
||||
|
||||
<!-- Comment this out to disable mods folder !-->
|
||||
<haxedef name="MOD_SUPPORT" unless="web"/>
|
||||
|
||||
<!-- Comment this out to disable global scripts !-->
|
||||
<haxedef name="GLOBAL_SCRIPT" />
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1016
|
||||
1032
|
||||
@@ -1,9 +1,11 @@
|
||||
package funkin.mods;
|
||||
|
||||
import flixel.util.FlxSignal.FlxTypedSignal;
|
||||
import openfl.utils.Assets;
|
||||
import openfl.utils.AssetManifest;
|
||||
import openfl.utils.AssetLibrary;
|
||||
import flixel.graphics.FlxGraphic;
|
||||
import flixel.util.FlxSignal.FlxTypedSignal;
|
||||
|
||||
#if MOD_SUPPORT
|
||||
import sys.FileSystem;
|
||||
@@ -16,13 +18,11 @@ import haxe.io.Path;
|
||||
using StringTools;
|
||||
|
||||
class ModsFolder {
|
||||
#if MOD_SUPPORT
|
||||
/**
|
||||
* Last time the folder was modified.
|
||||
* INTERNAL - Only use when editing source mods!!
|
||||
*/
|
||||
public static var lastFolderEditTime:Date = null;
|
||||
#end
|
||||
|
||||
@:dox(hide) public static var onModSwitch:FlxTypedSignal<String->Void> = new FlxTypedSignal<String->Void>();
|
||||
|
||||
/**
|
||||
* Current mod folder. Will affect `Paths`.
|
||||
*/
|
||||
@@ -49,6 +49,8 @@ class ModsFolder {
|
||||
* @param force Whenever the mod should be reloaded if it has already been loaded
|
||||
*/
|
||||
public static function loadMod(mod:String, force:Bool = false) {
|
||||
if (mod == null) return null; // may be loading base game
|
||||
|
||||
if (FileSystem.exists('${modsPath}$mod.zip')) {
|
||||
var e = loadLibraryFromZip('mods/$mod'.toLowerCase(), '${modsPath}$mod.zip', force);
|
||||
loadedMods.push(mod);
|
||||
@@ -60,6 +62,23 @@ class ModsFolder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches mod - unloads all the other mods, then load this one.
|
||||
* @param libName
|
||||
*/
|
||||
public static function switchMod(mod:String) {
|
||||
for(m in loadedMods)
|
||||
unloadMod(m);
|
||||
|
||||
loadMod(ModsFolder.currentModFolder = mod);
|
||||
onModSwitch.dispatch(ModsFolder.currentModFolder);
|
||||
FlxG.resetState();
|
||||
}
|
||||
|
||||
public static function unloadMod(mod:String) {
|
||||
Assets.unloadLibrary('mods/$mod');
|
||||
}
|
||||
|
||||
public static function prepareLibrary(libName:String, force:Bool = false) {
|
||||
if (Assets.hasLibrary(libName)) {
|
||||
if (force)
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package funkin.scripting;
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxState;
|
||||
import funkin.mods.ModsFolder;
|
||||
#if GLOBAL_SCRIPT
|
||||
/**
|
||||
* Class for THE Global Script, aka script that runs in the background at all times.
|
||||
*/
|
||||
class GlobalScript {
|
||||
public static var script:Script;
|
||||
|
||||
public static function init() {
|
||||
#if MOD_SUPPORT
|
||||
ModsFolder.onModSwitch.add(onModSwitch);
|
||||
#end
|
||||
FlxG.signals.focusGained.add(function() {
|
||||
call("focusGained");
|
||||
});
|
||||
FlxG.signals.focusLost.add(function() {
|
||||
call("focusLost");
|
||||
});
|
||||
FlxG.signals.gameResized.add(function(w:Int, h:Int) {
|
||||
call("gameResized", [w, h]);
|
||||
});
|
||||
FlxG.signals.postDraw.add(function() {
|
||||
call("postDraw");
|
||||
});
|
||||
FlxG.signals.postGameReset.add(function() {
|
||||
call("postGameReset");
|
||||
});
|
||||
FlxG.signals.postGameStart.add(function() {
|
||||
});
|
||||
FlxG.signals.postStateSwitch.add(function() {
|
||||
call("postStateSwitch");
|
||||
});
|
||||
FlxG.signals.postUpdate.add(function() {
|
||||
call("postUpdate", [FlxG.elapsed]);
|
||||
call("updatePost", [FlxG.elapsed]);
|
||||
if (FlxG.keys.justPressed.F5) {
|
||||
if (script != null && !(script is DummyScript)) {
|
||||
Logs.trace('Reloading global script...', WARNING, YELLOW);
|
||||
script.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);
|
||||
}
|
||||
}
|
||||
});
|
||||
FlxG.signals.preDraw.add(function() {
|
||||
call("preDraw");
|
||||
});
|
||||
FlxG.signals.preGameReset.add(function() {
|
||||
call("preGameReset");
|
||||
});
|
||||
FlxG.signals.preGameStart.add(function() {
|
||||
call("preGameStart");
|
||||
});
|
||||
FlxG.signals.preStateCreate.add(function(state:FlxState) {
|
||||
call("preStateCreate", [state]);
|
||||
});
|
||||
FlxG.signals.preStateSwitch.add(function() {
|
||||
call("preStateSwitch", []);
|
||||
});
|
||||
FlxG.signals.preUpdate.add(function() {
|
||||
call("preUpdate", [FlxG.elapsed]);
|
||||
call("update", [FlxG.elapsed]);
|
||||
});
|
||||
|
||||
onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end);
|
||||
}
|
||||
|
||||
public static function call(name:String, ?args:Array<Dynamic>) {
|
||||
if (script == null) return;
|
||||
script.call(name, args);
|
||||
}
|
||||
public static function onModSwitch(newMod:String) {
|
||||
trace(newMod);
|
||||
if (script != null) {
|
||||
script.destroy();
|
||||
script = null;
|
||||
}
|
||||
script = Script.create(Paths.script('data/global'));
|
||||
script.load();
|
||||
}
|
||||
|
||||
public static function beatHit(curBeat:Int) {
|
||||
call("beatHit", [curBeat]);
|
||||
}
|
||||
|
||||
public static function stepHit(curStep:Int) {
|
||||
call("stepHit", [curStep]);
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -9,10 +9,6 @@ import funkin.windows.WindowsAPI.ConsoleColor;
|
||||
class Logs {
|
||||
private static var __showing:Bool = false;
|
||||
public static function init() {
|
||||
__showInConsole([
|
||||
logText("Hello, World! ", CYAN),
|
||||
logText("I am..."),
|
||||
logText("COLORED!!", RED)]);
|
||||
|
||||
Log.trace = function(v : Dynamic, ?infos : Null<haxe.PosInfos>) {
|
||||
__showInConsole(prepareColoredTrace([
|
||||
|
||||
@@ -106,13 +106,15 @@ class Main extends Sprite
|
||||
|
||||
|
||||
public function loadGameSettings() {
|
||||
|
||||
Logs.init();
|
||||
|
||||
// TODO: Mod switching
|
||||
ModsFolder.init();
|
||||
ModsFolder.loadMod("introMod");
|
||||
ModsFolder.currentModFolder = "introMod";
|
||||
|
||||
Logs.init();
|
||||
ModsFolder.switchMod("introMod");
|
||||
|
||||
#if GLOBAL_SCRIPT
|
||||
funkin.scripting.GlobalScript.init();
|
||||
#end
|
||||
|
||||
#if sys
|
||||
if (Sys.args().contains("-livereload")) {
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package scripting;
|
||||
|
||||
import flixel.FlxState;
|
||||
/**
|
||||
* A global script is a special kind of script that runs on everywhere on your mod: menus, game, etc...
|
||||
*
|
||||
* To create one, go to data and create a script named "global", then press F5 in game.
|
||||
*
|
||||
* All flixel signals are automatically binded, as shown below.
|
||||
*/
|
||||
interface GlobalScript {
|
||||
/**
|
||||
* Called whenever the game gains focus.
|
||||
*/
|
||||
public function focusGained():Void;
|
||||
/**
|
||||
* Called whenever the game loses focus.
|
||||
*/
|
||||
public function focusLost():Void;
|
||||
/**
|
||||
* Called whenever the game loses focus.
|
||||
* @param width Width of the game
|
||||
* @param height Height of the game
|
||||
*/
|
||||
public function gameResized(width:Int, height:Int):Void;
|
||||
|
||||
/**
|
||||
* Called after the screen has been drawn.
|
||||
*/
|
||||
public function postDraw():Void;
|
||||
|
||||
/**
|
||||
* Called after the game has been reset.
|
||||
*/
|
||||
public function postGameReset():Void;
|
||||
|
||||
/**
|
||||
* Called after the game has been started.
|
||||
*/
|
||||
public function postGameStart():Void;
|
||||
|
||||
/**
|
||||
* Called after the state has been switched.
|
||||
*/
|
||||
public function postStateSwitch():Void;
|
||||
|
||||
/**
|
||||
* Called after the game has been updated.
|
||||
*
|
||||
* Aliases: `postUpdate`
|
||||
*
|
||||
* @param elapsed Time elapsed since last frame
|
||||
*/
|
||||
public function updatePost(elapsed:Float):Void;
|
||||
|
||||
/**
|
||||
* Called before the game draws on screen.
|
||||
*/
|
||||
public function preDraw():Void;
|
||||
|
||||
/**
|
||||
* Called before the game resets.
|
||||
*/
|
||||
public function preGameReset():Void;
|
||||
|
||||
/**
|
||||
* Called before the game starts.
|
||||
*/
|
||||
public function preGameStart():Void;
|
||||
|
||||
/**
|
||||
* Called before the state creates.
|
||||
*/
|
||||
public function preStateCreate(state:FlxState):Void;
|
||||
|
||||
/**
|
||||
* Called before the state switches.
|
||||
*/
|
||||
public function preStateSwitch():Void;
|
||||
|
||||
/**
|
||||
* Called before the game updates.
|
||||
*
|
||||
* Aliases: `preUpdate`
|
||||
*/
|
||||
public function update(elapsed:Float):Void;
|
||||
}
|
||||
Reference in New Issue
Block a user