attempt undo (#193)

This commit is contained in:
CharlesCatYT
2023-07-20 20:50:37 -07:00
committed by GitHub
parent 4db9cf7cee
commit 8a2ac9e1d4
6 changed files with 154 additions and 184 deletions
+38 -53
View File
@@ -9,7 +9,6 @@ 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;
@@ -90,7 +89,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 scripts:ScriptPack;
public var stateScript:Script;
public var scriptsAllowed:Bool = true;
@@ -112,50 +111,25 @@ class MusicBeatState extends FlxState implements IBeatReceiver
this.scriptName = scriptName;
}
public function addScript(file:String)
scripts.add(Script.create(Paths.script(file, null, true)));
function loadScript() {
if (scriptsAllowed) {
if (scripts == null) {
if (stateScript == null || stateScript is DummyScript) {
var className = Type.getClassName(Type.getClass(this));
var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1);
var scriptPaths = [];
(scripts = new ScriptPack(scriptName)).setParent(this);
scriptPaths = Paths.getScriptPaths('assets/data/states/$scriptName');
for (i in Paths.getScriptPaths('assets/data/states', '/$scriptName.'))
scriptPaths.push(i);
if (scriptPaths.length > 0)
for (i in scriptPaths) {
var old = Assets.forceAssetLibrary;
Assets.forceAssetLibrary = i.library;
addScript(i.file);
Assets.forceAssetLibrary = old;
}
if (Type.getClass(this) != PlayState) scripts.load();
}
else
scripts.reload();
stateScript = Script.create(Paths.script('data/states/${scriptName}'));
stateScript.setParent(this);
stateScript.load();
} else
stateScript.reload();
}
}
public function call(name:String, ?args:Array<Dynamic>, ?defaultVal:Dynamic):Dynamic {
// calls the function on the assigned script
if (scripts == null) return defaultVal;
return scripts.call(name, args);
}
public function event<T:CancellableEvent>(name:String, event:T):T {
if (scripts == null) return event;
scripts.event(name, event);
return event;
}
public override function tryUpdate(elapsed:Float):Void
{
if (persistentUpdate || subState == null) {
scripts.call("preUpdate", [elapsed]);
call("preUpdate", [elapsed]);
update(elapsed);
scripts.call("postUpdate", [elapsed]);
call("postUpdate", [elapsed]);
}
if (_requestSubStateReset)
@@ -170,31 +144,42 @@ class MusicBeatState extends FlxState implements IBeatReceiver
}
override function create()
{
if (Type.getClass(this) != PlayState) loadScript();
loadScript();
Framerate.offset.y = 0;
super.create();
scripts.call("create");
call("create");
}
public override function createPost() {
super.createPost();
persistentUpdate = true;
scripts.call("postCreate");
call("postCreate");
if (!skipTransIn)
openSubState(new MusicBeatTransition(null));
skipTransIn = false;
skipTransOut = false;
}
public function call(name:String, ?args:Array<Dynamic>, ?defaultVal:Dynamic):Dynamic {
// calls the function on the assigned script
if (stateScript == null) return defaultVal;
return stateScript.call(name, args);
}
public function event<T:CancellableEvent>(name:String, event:T):T {
if (stateScript == null) return event;
stateScript.call(name, [event]);
return event;
}
override function update(elapsed:Float)
{
// TODO: DEBUG MODE!!
if (FlxG.keys.justPressed.F5) {
loadScript();
if (scripts != null)
if (stateScript != null && !(stateScript is DummyScript))
Logs.trace('State script successfully reloaded', WARNING, GREEN);
}
scripts.call("update", [elapsed]);
call("update", [elapsed]);
super.update(elapsed);
}
@@ -202,19 +187,19 @@ class MusicBeatState extends FlxState implements IBeatReceiver
@:dox(hide) public function stepHit(curStep:Int):Void
{
for(e in members) if (e != null && e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep);
scripts.call("stepHit", [curStep]);
call("stepHit", [curStep]);
}
@:dox(hide) public function beatHit(curBeat:Int):Void
{
for(e in members) if (e != null && e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat);
scripts.call("beatHit", [curBeat]);
call("beatHit", [curBeat]);
}
@:dox(hide) public function measureHit(curMeasure:Int):Void
{
for(e in members) if (e != null && e is IBeatReceiver) cast(e, IBeatReceiver).measureHit(curMeasure);
scripts.call("measureHit", [curMeasure]);
call("measureHit", [curMeasure]);
}
/**
@@ -235,34 +220,34 @@ class MusicBeatState extends FlxState implements IBeatReceiver
* SCRIPTING STUFF
*/
public override function openSubState(subState:FlxSubState) {
var e = scripts.event("onOpenSubState", EventManager.get(StateEvent).recycle(subState));
var e = event("onOpenSubState", EventManager.get(StateEvent).recycle(subState));
if (!e.cancelled)
super.openSubState(subState);
}
public override function onResize(w:Int, h:Int) {
super.onResize(w, h);
scripts.event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
}
public override function destroy() {
super.destroy();
graphicCache.destroy();
scripts.call("onDestroy");
scripts.call("destroy");
scripts = FlxDestroyUtil.destroy(scripts);
call("onDestroy");
if (stateScript != null)
stateScript.destroy();
}
public override function draw() {
graphicCache.draw();
var e = scripts.event("draw", EventManager.get(DrawEvent).recycle());
var e = event("draw", EventManager.get(DrawEvent).recycle());
if (!e.cancelled)
super.draw();
scripts.event("postDraw", e);
event("postDraw", e);
}
public override function switchTo(nextState:FlxState) {
var e = scripts.event("onStateSwitch", EventManager.get(StateEvent).recycle(nextState));
var e = event("onStateSwitch", EventManager.get(StateEvent).recycle(nextState));
if (e.cancelled)
return false;
@@ -277,12 +262,12 @@ class MusicBeatState extends FlxState implements IBeatReceiver
public override function onFocus() {
super.onFocus();
scripts.call("onFocus");
call("onFocus");
}
public override function onFocusLost() {
super.onFocusLost();
scripts.call("onFocusLost");
call("onFocusLost");
}
public override function resetSubState() {
+40 -55
View File
@@ -3,7 +3,6 @@ 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;
@@ -64,7 +63,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 scripts:ScriptPack;
public var stateScript:Script;
public var scriptsAllowed:Bool = true;
@@ -98,49 +97,26 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
this.scriptsAllowed = #if SOFTCODED_STATES scriptsAllowed #else false #end;
this.scriptName = scriptName;
}
public function addScript(file:String)
scripts.add(Script.create(Paths.script(file, null, true)));
function loadScript() {
if (scriptsAllowed) {
if (scripts == null) {
(scripts = new ScriptPack(scriptName)).setParent(this);
if (stateScript == null || stateScript is DummyScript) {
var className = Type.getClassName(Type.getClass(this));
var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1);
var scriptPaths = [];
scriptPaths = Paths.getScriptPaths('assets/data/states/$scriptName');
for (i in Paths.getScriptPaths('assets/data/states', '/$scriptName.'))
scriptPaths.push(i);
if (scriptPaths.length > 0)
for (i in scriptPaths) {
var old = Assets.forceAssetLibrary;
Assets.forceAssetLibrary = i.library;
addScript(i.file);
Assets.forceAssetLibrary = old;
}
scripts.load();
}
else
scripts.reload();
stateScript = Script.create(Paths.script('data/states/${scriptName}'));
stateScript.setParent(this);
stateScript.load();
} else
stateScript.reload();
}
}
public function call(name:String, ?args:Array<Dynamic>, ?defaultVal:Dynamic):Dynamic {
// calls the function on the assigned script
if (scripts == null) return defaultVal;
return scripts.call(name, args);
}
public function event<T:CancellableEvent>(name:String, event:T):T {
if (scripts == null) return event;
scripts.call(name, [event]);
return event;
}
public override function tryUpdate(elapsed:Float):Void
{
if (persistentUpdate || subState == null) {
scripts.call("preUpdate", [elapsed]);
call("preUpdate", [elapsed]);
update(elapsed);
scripts.call("postUpdate", [elapsed]);
call("postUpdate", [elapsed]);
}
if (_requestSubStateReset)
@@ -155,26 +131,34 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
}
override function close() {
if (scripts != null) {
var event = scripts.event("onClose", new CancellableEvent());
if (!event.cancelled) {
super.close();
scripts.call("onClosePost");
}
} else
var event = event("onClose", new CancellableEvent());
if (!event.cancelled) {
super.close();
call("onClosePost");
}
}
override function create()
{
loadScript();
super.create();
scripts.call("create");
call("create");
}
public override function createPost() {
super.createPost();
scripts.call("postCreate");
call("postCreate");
}
public function call(name:String, ?args:Array<Dynamic>, ?defaultVal:Dynamic):Dynamic {
// calls the function on the assigned script
if (stateScript == null) return defaultVal;
return stateScript.call(name, args);
}
public function event<T:CancellableEvent>(name:String, event:T):T {
if (stateScript == null) return event;
stateScript.call(name, [event]);
return event;
}
override function update(elapsed:Float)
@@ -182,28 +166,29 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
// TODO: DEBUG MODE!!
if (FlxG.keys.justPressed.F5) {
loadScript();
Logs.trace('State script successfully reloaded', WARNING, GREEN);
if (stateScript != null && !(stateScript is DummyScript))
Logs.trace('State script successfully reloaded', WARNING, GREEN);
}
scripts.call("update", [elapsed]);
call("update", [elapsed]);
super.update(elapsed);
}
@:dox(hide) public function stepHit(curStep:Int):Void
{
for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep);
scripts.call("stepHit", [curStep]);
call("stepHit", [curStep]);
}
@:dox(hide) public function beatHit(curBeat:Int):Void
{
for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat);
scripts.call("beatHit", [curBeat]);
call("beatHit", [curBeat]);
}
@:dox(hide) public function measureHit(curMeasure:Int):Void
{
for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).measureHit(curMeasure);
scripts.call("measureHit", [curMeasure]);
call("measureHit", [curMeasure]);
}
/**
@@ -224,25 +209,25 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
* SCRIPTING STUFF
*/
public override function openSubState(subState:FlxSubState) {
var e = scripts.event("onOpenSubState", EventManager.get(StateEvent).recycle(subState));
var e = event("onOpenSubState", EventManager.get(StateEvent).recycle(subState));
if (!e.cancelled)
super.openSubState(subState);
}
public override function onResize(w:Int, h:Int) {
super.onResize(w, h);
scripts.event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
}
public override function destroy() {
super.destroy();
scripts.call("onDestroy");
scripts.call("destroy");
scripts = FlxDestroyUtil.destroy(scripts);
call("onDestroy");
if(stateScript != null)
stateScript.destroy();
}
public override function switchTo(nextState:FlxState) {
var e = scripts.event("onStateSwitch", EventManager.get(StateEvent).recycle(nextState));
var e = event("onStateSwitch", EventManager.get(StateEvent).recycle(nextState));
if (e.cancelled)
return false;
return super.switchTo(nextState);
@@ -250,12 +235,12 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
public override function onFocus() {
super.onFocus();
scripts.call("onFocus");
call("onFocus");
}
public override function onFocusLost() {
super.onFocusLost();
scripts.call("onFocusLost");
call("onFocusLost");
}
public var parent:FlxState;
+2 -27
View File
@@ -98,35 +98,10 @@ class Paths
}
return getPath('images/$key.png', library);
}
static public function getScriptPaths(key:String, excep:String = ""):Array<ScriptPathInfo> {
var scriptsPaths:Array<ScriptPathInfo> = [];
var reallib = assetsTree.libraries.copy();
key = key.replace("//", "/");
if (!key.endsWith("/")) key += "/";
for (library in reallib) {
if (!library.exists(key, null)) continue;
var path = library.getPath(key);
if(path == null) continue;
for (i in sys.FileSystem.readDirectory(path)) {
var file = Path.withoutDirectory(i);
if (Script.scriptExtensions.contains(Path.extension(file))) {
var filepath = '${key}$file'.replace("//", "/");
if (filepath.contains(excep) || excep == "")
scriptsPaths.push(new ScriptPathInfo(filepath, library));
}
}
}
return scriptsPaths;
}
inline static public function script(key:String, ?library:String, isAssetsPath:Bool = false) {
var scriptPath = isAssetsPath ? key : getPath(key, library);
if (!Script.scriptExtensions.contains(Path.extension(scriptPath))) {
if (!OpenFlAssets.exists(scriptPath)) {
var p:String;
for(ex in Script.scriptExtensions) {
p = '$scriptPath.$ex';
+40 -31
View File
@@ -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 scripts:ScriptPack;
public static var script:Script;
public static function init() {
#if MOD_SUPPORT
@@ -20,83 +20,92 @@ class GlobalScript {
Conductor.onStepHit.add(stepHit);
FlxG.signals.focusGained.add(function() {
scripts.call("focusGained");
call("focusGained");
});
FlxG.signals.focusLost.add(function() {
scripts.call("focusLost");
call("focusLost");
});
FlxG.signals.gameResized.add(function(w:Int, h:Int) {
scripts.call("gameResized", [w, h]);
call("gameResized", [w, h]);
});
FlxG.signals.postDraw.add(function() {
scripts.call("postDraw");
call("postDraw");
});
FlxG.signals.postGameReset.add(function() {
scripts.call("postGameReset");
call("postGameReset");
});
FlxG.signals.postGameStart.add(function() {
scripts.call("postGameStart");
call("postGameStart");
});
FlxG.signals.postStateSwitch.add(function() {
scripts.call("postStateSwitch");
call("postStateSwitch");
});
FlxG.signals.postUpdate.add(function() {
scripts.call("postUpdate", [FlxG.elapsed]);
call("postUpdate", [FlxG.elapsed]);
if (FlxG.keys.justPressed.F5) {
if (scripts != null) {
if (script != null && !(script is DummyScript)) {
Logs.trace('Reloading global script...', WARNING, YELLOW);
scripts.reload();
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() {
scripts.call("preDraw");
call("preDraw");
});
FlxG.signals.preGameReset.add(function() {
scripts.call("preGameReset");
call("preGameReset");
});
FlxG.signals.preGameStart.add(function() {
scripts.call("preGameStart");
call("preGameStart");
});
FlxG.signals.preStateCreate.add(function(state:FlxState) {
scripts.call("preStateCreate", [state]);
call("preStateCreate", [state]);
});
FlxG.signals.preStateSwitch.add(function() {
scripts.call("preStateSwitch", []);
call("preStateSwitch", []);
});
FlxG.signals.preUpdate.add(function() {
scripts.call("preUpdate", [FlxG.elapsed]);
scripts.call("update", [FlxG.elapsed]);
call("preUpdate", [FlxG.elapsed]);
call("update", [FlxG.elapsed]);
});
onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end);
}
public static function event<T:CancellableEvent>(name:String, event:T):T {
if (script == null) return event;
script.call(name, [event]);
return event;
}
public static function call(name:String, ?args:Array<Dynamic>) {
if (script == null) return;
script.call(name, args);
}
public static function onModSwitch(newMod:String) {
if (scripts != null) scripts.call("onDestroy");
scripts = FlxDestroyUtil.destroy(scripts);
scripts = new ScriptPack("global");
var scriptPaths = Paths.getScriptPaths("assets/data", "/global.");
for (i in Paths.getScriptPaths("assets/data/global")) scriptPaths.push(i);
var old = Assets.forceAssetLibrary;
for (i in scriptPaths) {
Assets.forceAssetLibrary = i.library;
scripts.add(Script.create(Paths.script(i.file, null, true)));
call("onDestroy");
if (script != null) {
script.destroy();
script = null;
}
Assets.forceAssetLibrary = old;
scripts.load();
script = Script.create(Paths.script('data/global'));
script.load();
}
public static function beatHit(curBeat:Int) {
scripts.call("beatHit", [curBeat]);
call("beatHit", [curBeat]);
}
public static function stepHit(curStep:Int) {
scripts.call("stepHit", [curStep]);
call("stepHit", [curStep]);
}
}
#end
+1 -1
View File
@@ -96,7 +96,7 @@ class DiscordUtil {
data.largeImageText = DiscordUtil.data.logoText;
#if GLOBAL_SCRIPT
var event = funkin.backend.scripting.GlobalScript.scripts.event("onDiscordPresenceUpdate", EventManager.get(DiscordPresenceUpdateEvent).recycle(data));
var event = funkin.backend.scripting.GlobalScript.event("onDiscordPresenceUpdate", EventManager.get(DiscordPresenceUpdateEvent).recycle(data));
if (event.cancelled) return;
#end
+33 -17
View File
@@ -79,6 +79,11 @@ class PlayState extends MusicBeatState
*/
public static var coopMode:Bool = false;
/**
* Script Pack of all the scripts being ran.
*/
public var scripts:ScriptPack;
/**
* Array of all the players in the stage.
*/
@@ -505,7 +510,7 @@ class PlayState extends MusicBeatState
if (FlxG.sound.music != null) FlxG.sound.music.stop();
PauseSubState.script = "";
loadScript();
(scripts = new ScriptPack("PlayState")).setParent(this);
camGame = camera;
FlxG.cameras.add(camHUD = new HudCamera(), false);
@@ -555,29 +560,19 @@ class PlayState extends MusicBeatState
// case "":
// ADD YOUR HARDCODED SCRIPTS HERE!
default:
for(content in [Paths.getScriptPaths('assets/songs/${SONG.meta.name.toLowerCase()}/scripts'), Paths.getScriptPaths('assets/data/charts/')])
for(file in content) {
var old = Assets.forceAssetLibrary;
Assets.forceAssetLibrary = file.library;
addScript(file.file);
Assets.forceAssetLibrary = old;
}
for(content in [Paths.getFolderContent('songs/${SONG.meta.name.toLowerCase()}/scripts', true, fromMods ? MODS : BOTH), Paths.getFolderContent('data/charts/', true, fromMods ? MODS : BOTH)])
for(file in content) addScript(file);
var songEvents:Array<String> = [];
for (event in SONG.events)
if (!songEvents.contains(event.name)) songEvents.push(event.name);
for (file in Paths.getScriptPaths('assets/data/events/')) {
var old = Assets.forceAssetLibrary;
Assets.forceAssetLibrary = file.library;
var fileName:String = Path.withoutExtension(Path.withoutDirectory(file.file));
if (EventsData.eventsList.contains(fileName) && songEvents.contains(fileName)) addScript(file.file);
Assets.forceAssetLibrary = old;
for (file in Paths.getFolderContent('data/events/', true, fromMods ? MODS : BOTH)) {
var fileName:String = Path.withoutExtension(Path.withoutDirectory(file));
if (EventsData.eventsList.contains(fileName) && songEvents.contains(fileName)) addScript(file);
}
}
}
add(comboGroup);
#end
@@ -649,6 +644,7 @@ class PlayState extends MusicBeatState
add(splashHandler);
scripts.load();
scripts.call("create");
#end
// CAMERA & HUD INITIALISATION
@@ -725,6 +721,7 @@ class PlayState extends MusicBeatState
#end
startingSong = true;
super.create();
for(s in introSprites)
@@ -743,6 +740,8 @@ class PlayState extends MusicBeatState
updateDiscordPresence();
__updateNote_event = EventManager.get(NoteUpdateEvent);
scripts.call("postCreate");
}
/**
@@ -895,9 +894,11 @@ class PlayState extends MusicBeatState
}
public override function destroy() {
scripts.call("destroy");
for(g in __cachedGraphics)
g.useCount--;
super.destroy();
scripts = FlxDestroyUtil.destroy(scripts);
@:privateAccess {
FlxG.sound.destroySound(inst);
FlxG.sound.destroySound(vocals);
@@ -1071,9 +1072,11 @@ class PlayState extends MusicBeatState
@:dox(hide)
override public function update(elapsed:Float)
{
scripts.call("update", [elapsed]);
if (inCutscene) {
super.update(elapsed);
scripts.call("postUpdate", [elapsed]);
return;
}
@@ -1191,6 +1194,13 @@ class PlayState extends MusicBeatState
scripts.call("postUpdate", [elapsed]);
}
override function draw() {
var e = scripts.event("draw", EventManager.get(DrawEvent).recycle());
if (!e.cancelled)
super.draw();
scripts.event("postDraw", e);
}
public function executeEvent(event:ChartEvent) {
if (event == null) return;
if (event.params == null) return;
@@ -1614,6 +1624,12 @@ class PlayState extends MusicBeatState
scripts.call("beatHit", [curBeat]);
}
public function addScript(file:String) {
var ext = Path.extension(file).toLowerCase();
if (Script.scriptExtensions.contains(ext))
scripts.add(Script.create(file));
}
// GETTERS & SETTERS
#if REGION
private inline function get_player():StrumLine