ModSubState
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
1360
|
||||
1374
|
||||
@@ -265,8 +265,10 @@ class PlayState extends MusicBeatState
|
||||
} else {
|
||||
var gfVersion = SONG.gf;
|
||||
if (gfVersion == null) gfVersion = "gf";
|
||||
gf = new Character(400, 130, gfVersion);
|
||||
gf.scrollFactor.set(0.95, 0.95);
|
||||
if (gfVersion != "none") {
|
||||
gf = new Character(400, 130, gfVersion);
|
||||
gf.scrollFactor.set(0.95, 0.95);
|
||||
}
|
||||
}
|
||||
|
||||
var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y);
|
||||
@@ -454,13 +456,10 @@ class PlayState extends MusicBeatState
|
||||
|
||||
startTimer = new FlxTimer().start(Conductor.crochet / 1000, function(tmr:FlxTimer)
|
||||
{
|
||||
dad.dance();
|
||||
gf.dance();
|
||||
boyfriend.dance();
|
||||
|
||||
countdown(swagCounter);
|
||||
|
||||
swagCounter += 1;
|
||||
for(char in [dad, gf, boyfriend])
|
||||
if (char != null)
|
||||
char.dance();
|
||||
countdown(swagCounter++);
|
||||
}, introLength);
|
||||
}
|
||||
|
||||
@@ -1223,7 +1222,7 @@ class PlayState extends MusicBeatState
|
||||
if (event.cancelled) return;
|
||||
|
||||
health += event.healthGain;
|
||||
if (combo > 5 && gf.animOffsets.exists('sad'))
|
||||
if (gf != null && combo > 5 && gf.animOffsets.exists('sad'))
|
||||
{
|
||||
gf.playAnim('sad');
|
||||
}
|
||||
@@ -1441,7 +1440,7 @@ class PlayState extends MusicBeatState
|
||||
iconP1.updateHitbox();
|
||||
iconP2.updateHitbox();
|
||||
|
||||
if (curBeat % gfSpeed == 0)
|
||||
if (gf != null && curBeat % gfSpeed == 0)
|
||||
{
|
||||
gf.dance();
|
||||
}
|
||||
|
||||
@@ -102,12 +102,12 @@ class Stage extends FlxBasic implements IBeatReceiver {
|
||||
state.add(spr);
|
||||
spr;
|
||||
case "boyfriend" | "bf":
|
||||
if (PlayState.instance == null) continue;
|
||||
if (PlayState.instance == null || PlayState.instance.boyfriend == null) continue;
|
||||
doCharNodeShit(PlayState.instance.boyfriend, node);
|
||||
PlayState.instance.add(PlayState.instance.boyfriend);
|
||||
PlayState.instance.boyfriend;
|
||||
case "girlfriend" | "gf":
|
||||
if (PlayState.instance == null) continue;
|
||||
if (PlayState.instance == null || PlayState.instance.gf == null) continue;
|
||||
doCharNodeShit(PlayState.instance.gf, node);
|
||||
PlayState.instance.add(PlayState.instance.gf);
|
||||
PlayState.instance.gf;
|
||||
|
||||
@@ -227,6 +227,7 @@ class MainMenuState extends MusicBeatState
|
||||
}
|
||||
|
||||
spr.updateHitbox();
|
||||
spr.centerOffsets();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ using StringTools;
|
||||
|
||||
interface ModsAssetLibrary {
|
||||
public var prefix:String;
|
||||
public var libName:String;
|
||||
|
||||
#if MOD_SUPPORT
|
||||
public var _parsedAsset:String;
|
||||
|
||||
@@ -116,7 +116,6 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
|
||||
public override function exists(asset:String, type:String):Bool {
|
||||
if(!__parseAsset(asset)) return false;
|
||||
trace('$folderPath: $_parsedAsset: ${FileSystem.exists(getAssetPath())}');
|
||||
return FileSystem.exists(getAssetPath());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ class HScript extends Script {
|
||||
var code:String = Assets.getText(path);
|
||||
var parser = new hscript.Parser();
|
||||
parser.allowJSON = parser.allowMetadata = parser.allowTypes = true;
|
||||
parser.preprocesorValues = Script.getDefaultPreprocessors();
|
||||
interp.errorHandler = _errorHandler;
|
||||
interp.staticVariables = Script.staticVariables;
|
||||
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package funkin.scripting;
|
||||
|
||||
class ModSubState extends MusicBeatSubstate {
|
||||
public function new(scriptName:String) {
|
||||
super(true, scriptName);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package funkin.scripting;
|
||||
|
||||
import lime.app.Application;
|
||||
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
|
||||
import flixel.FlxBasic;
|
||||
import haxe.io.Path;
|
||||
@@ -55,6 +56,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
name: "Codename Engine"
|
||||
},
|
||||
"ModState" => funkin.scripting.ModState,
|
||||
"ModSubState" => funkin.scripting.ModSubState,
|
||||
"PlayState" => funkin.game.PlayState,
|
||||
"GameOverSubstate" => funkin.game.GameOverSubstate,
|
||||
"Note" => funkin.game.Note,
|
||||
@@ -77,6 +79,25 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
"Alphabet" => funkin.ui.Alphabet,
|
||||
];
|
||||
}
|
||||
public static function getDefaultPreprocessors():Map<String, Dynamic> {
|
||||
return [
|
||||
"CODENAME_ENGINE" => true,
|
||||
"CODENAME_VER" => Application.current.meta.get('version'),
|
||||
"CODENAME_BUILD" => funkin.macros.BuildCounterMacro.getBuildNumber(),
|
||||
"desktop" => #if desktop true #else false #end,
|
||||
"windows" => #if windows true #else false #end,
|
||||
"linux" => #if linux true #else false #end,
|
||||
"macos" => #if macos true #else false #end,
|
||||
"android" => #if android true #else false #end,
|
||||
"web" => #if web true #else false #end,
|
||||
"debug" => #if debug true #else false #end,
|
||||
"MOD_SUPPORT" => #if MOD_SUPPORT true #else false #end,
|
||||
"GLOBAL_SCRIPT" => #if GLOBAL_SCRIPT true #else false #end,
|
||||
"SOFTCODED_STATES" => #if SOFTCODED_STATES true #else false #end,
|
||||
"USE_SOURCE_ASSETS" => #if USE_SOURCE_ASSETS true #else false #end,
|
||||
"USE_ADAPTED_ASSETS" => #if USE_ADAPTED_ASSETS true #else false #end,
|
||||
];
|
||||
}
|
||||
/**
|
||||
* All available script extensions
|
||||
*/
|
||||
|
||||
@@ -169,8 +169,8 @@ class Conductor
|
||||
if (FlxG.state is IBeatReceiver) {
|
||||
var state = FlxG.state;
|
||||
while(state != null) {
|
||||
if (FlxG.state is IBeatReceiver) {
|
||||
var st = cast(FlxG.state, IBeatReceiver);
|
||||
if (state is IBeatReceiver && (state.subState == null || state.subState.persistentUpdate)) {
|
||||
var st = cast(state, IBeatReceiver);
|
||||
st.stepHit(curStep);
|
||||
if (updateBeat)
|
||||
st.beatHit(curBeat);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package funkin.system;
|
||||
|
||||
import funkin.mods.ModsAssetLibrary;
|
||||
import lime.ui.KeyCode;
|
||||
import openfl.ui.Keyboard;
|
||||
import openfl.events.KeyboardEvent;
|
||||
@@ -71,14 +72,32 @@ class FramerateField extends TextField {
|
||||
text.push('CODENAME ENGINE ALPHA - BUILD ${funkin.macros.BuildCounterMacro.getBuildNumber()}');
|
||||
#end
|
||||
if (debugMode) {
|
||||
text.push('======');
|
||||
text.push('=== CONDUCTOR INFO ===');
|
||||
text.push('Current Song Position: ${Conductor.songPosition} (${Conductor.curBeat} beats - ${Conductor.curStep} steps)');
|
||||
text.push('Current BPM: ${Conductor.bpm}');
|
||||
text.push('======');
|
||||
text.push('=== SYSTEM INFO ===');
|
||||
text.push('System: ${lime.system.System.platformLabel} ${lime.system.System.platformVersion}');
|
||||
text.push('Objs in state: ${FlxG.state.members.length}');
|
||||
text.push('Nb cameras: ${FlxG.cameras.list.length}');
|
||||
text.push('Current state: ${Type.getClassName(Type.getClass(FlxG.state))}');
|
||||
text.push('=== ASSET LIBRARIES TREE ===');
|
||||
if (Paths.assetsTree == null)
|
||||
text.push('Not initialized yet');
|
||||
else {
|
||||
for(e in Paths.assetsTree.libraries) {
|
||||
var l = e;
|
||||
if (l is openfl.utils.AssetLibrary) {
|
||||
var al = cast(l, openfl.utils.AssetLibrary);
|
||||
@:privateAccess
|
||||
if (al.__proxy != null) l = al.__proxy;
|
||||
}
|
||||
|
||||
if (l is ModsAssetLibrary)
|
||||
text.push('${Type.getClassName(Type.getClass(l))} - ${cast(l, ModsAssetLibrary).libName} (${cast(l, ModsAssetLibrary).prefix})');
|
||||
else
|
||||
text.push(Std.string(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.text = text.join("\n");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package funkin.system;
|
||||
|
||||
import flixel.FlxState;
|
||||
import funkin.scripting.events.*;
|
||||
import funkin.scripting.Script;
|
||||
import funkin.scripting.DummyScript;
|
||||
import funkin.interfaces.IBeatReceiver;
|
||||
import funkin.system.Conductor.BPMChangeEvent;
|
||||
import funkin.system.Conductor;
|
||||
@@ -10,11 +14,6 @@ import flixel.math.FlxMath;
|
||||
|
||||
class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
{
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
private var lastBeat:Float = 0;
|
||||
private var lastStep:Float = 0;
|
||||
|
||||
@@ -51,6 +50,16 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
inline function get_songPos():Float
|
||||
return Conductor.songPosition;
|
||||
|
||||
|
||||
/**
|
||||
* 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 scriptsAllowed:Bool = true;
|
||||
|
||||
public var scriptName:String = null;
|
||||
|
||||
/**
|
||||
* Game Controls.
|
||||
*/
|
||||
@@ -59,23 +68,102 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
inline function get_controls():Controls
|
||||
return PlayerSettings.player1.controls;
|
||||
|
||||
|
||||
public function new(scriptsAllowed:Bool = true, ?scriptName:String) {
|
||||
super();
|
||||
this.scriptsAllowed = #if SOFTCODED_STATES scriptsAllowed #else false #end;
|
||||
this.scriptName = scriptName;
|
||||
loadScript();
|
||||
}
|
||||
|
||||
function loadScript() {
|
||||
if (scriptsAllowed) {
|
||||
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);
|
||||
|
||||
stateScript = Script.create(Paths.script('data/states/${scriptName}'));
|
||||
stateScript.setParent(this);
|
||||
stateScript.load();
|
||||
} else
|
||||
stateScript.reload();
|
||||
}
|
||||
}
|
||||
|
||||
public override function tryUpdate(elapsed:Float):Void
|
||||
{
|
||||
if (persistentUpdate || subState == null) {
|
||||
call("preUpdate", [elapsed]);
|
||||
update(elapsed);
|
||||
call("postUpdate", [elapsed]);
|
||||
}
|
||||
|
||||
if (_requestSubStateReset)
|
||||
{
|
||||
_requestSubStateReset = false;
|
||||
resetSubState();
|
||||
}
|
||||
if (subState != null)
|
||||
{
|
||||
subState.tryUpdate(elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
override function close() {
|
||||
var event = event("onClose", new CancellableEvent());
|
||||
if (!event.cancelled) {
|
||||
super.close();
|
||||
call("onClosePost");
|
||||
}
|
||||
}
|
||||
|
||||
override function create()
|
||||
{
|
||||
super.create();
|
||||
call("create");
|
||||
}
|
||||
|
||||
public override function createPost() {
|
||||
super.createPost();
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
@:dox(hide) public function stepHit(curStep:Int):Void
|
||||
{
|
||||
//do literally nothing neither dumbass
|
||||
for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep);
|
||||
call("stepHit", [curStep]);
|
||||
}
|
||||
|
||||
@:dox(hide) public function beatHit(curBeat:Int):Void
|
||||
{
|
||||
//do literally nothing dumbass
|
||||
for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat);
|
||||
call("beatHit", [curBeat]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Shortcut to `FlxMath.lerp` or `CoolUtil.lerp`, depending on `fpsSensitive`
|
||||
* @param v1 Value 1
|
||||
* @param v2 Value 2
|
||||
@@ -88,4 +176,41 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
|
||||
else
|
||||
return CoolUtil.fpsLerp(v1, v2, ratio);
|
||||
}
|
||||
|
||||
/**
|
||||
* SCRIPTING STUFF
|
||||
*/
|
||||
public override function openSubState(subState:FlxSubState) {
|
||||
var e = event("onOpenSubState", new StateEvent(subState));
|
||||
if (!e.cancelled)
|
||||
super.openSubState(subState);
|
||||
}
|
||||
|
||||
public override function onResize(w:Int, h:Int) {
|
||||
super.onResize(w, h);
|
||||
event("onResize", new ResizeEvent(w, h));
|
||||
}
|
||||
|
||||
public override function destroy() {
|
||||
super.destroy();
|
||||
call("onDestroy");
|
||||
stateScript.destroy();
|
||||
}
|
||||
|
||||
public override function switchTo(nextState:FlxState) {
|
||||
var e = event("onStateSwitch", new StateEvent(nextState));
|
||||
if (e.cancelled)
|
||||
return false;
|
||||
return super.switchTo(nextState);
|
||||
}
|
||||
|
||||
public override function onFocus() {
|
||||
super.onFocus();
|
||||
call("onFocus");
|
||||
}
|
||||
|
||||
public override function onFocusLost() {
|
||||
super.onFocusLost();
|
||||
call("onFocusLost");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user