Files
FNF-i486-Engine/source/psychlua/FunkinLua.hx

3851 lines
112 KiB
Haxe

package psychlua;
import Controls;
import DialogueBoxPsych;
import Shaders;
import Type.ValueType;
import flixel.FlxBasic;
import flixel.addons.effects.FlxTrail;
import flixel.input.keyboard.FlxKey;
import flixel.system.FlxAssets.FlxShader;
import openfl.Lib;
import openfl.display.BitmapData;
import openfl.display.BlendMode;
import utils.*;
#if (SHADERS_ALLOWED)
import flixel.addons.display.FlxRuntimeShader;
import shaders.ErrorHandledShader;
import openfl.filters.BitmapFilter;
import openfl.filters.ShaderFilter;
#end
#if desktop
import DiscordClient;
#end
class FunkinLua
{
public static var Function_Stop:Dynamic = "##PSYCHLUA_FUNCTIONSTOP";
public static var Function_Continue:Dynamic = "##PSYCHLUA_FUNCTIONCONTINUE";
public static var Function_StopLua:Dynamic = "##PSYCHLUA_FUNCTIONSTOPLUA";
#if (MODS_ALLOWED && SHADERS_ALLOWED)
private static var storedFilters:Map<String, ShaderFilter> = []; // for a few shader functions
#end
// public var errorHandler:String->Void;
#if LUA_ALLOWED
public var lua:State = null;
#end
public var camTarget:FlxCamera;
public var scriptName:String = '';
public var closed:Bool = false;
#if hscript
public var hscript:HScript = null;
#end
public var callbacks:Map<String, Dynamic> = [];
public static var customFunctions:Map<String, Dynamic> = [];
public static var registeredFunctions:Map<String, Dynamic> = [];
public function new(scriptName:String, ?scriptCode:String)
{
#if LUA_ALLOWED
lua = LuaL.newstate();
LuaL.openlibs(lua);
// trace('Lua version: ' + Lua.version());
// trace("LuaJIT version: " + Lua.versionJIT());
// LuaL.dostring(lua, CLENSE);
this.scriptName = scriptName;
final game:PlayState = PlayState.instance;
game.luaArray.push(this);
try
{
var result:Int = scriptCode != null ? LuaL.dostring(lua, scriptCode) : LuaL.dofile(lua, scriptName);
var resultStr:String = Lua.tostring(lua, result);
if (resultStr != null && result != 0)
{
trace('Error on lua script! ' + resultStr);
#if windows
lime.app.Application.current.window.alert(resultStr, 'Error on lua script!');
#else
LuaUtils.luaTrace(lua, 'Error loading lua script: "$scriptName"\n' + resultStr, true, false, FlxColor.RED);
#end
lua = null;
return;
}
}
catch (e:Dynamic)
{
trace(e);
return;
}
trace('lua file loaded successfully:' + scriptName);
// Lua shit
set('Function_StopLua', Function_StopLua);
set('Function_Stop', Function_Stop);
set('Function_Continue', Function_Continue);
set('luaDebugMode', false);
set('luaDeprecatedWarnings', true);
set('inChartEditor', false);
// Song/Week shit
set('curBpm', Conductor.bpm);
set('bpm', PlayState.SONG.bpm);
set('scrollSpeed', PlayState.SONG.speed);
set('crochet', Conductor.crochet);
set('stepCrochet', Conductor.stepCrochet);
set('songLength', FlxG.sound.music.length);
set('songName', PlayState.SONG.song);
set('songPath', Paths.formatToSongPath(PlayState.SONG.song));
set('startedCountdown', false);
set('curStage', PlayState.SONG.stage);
set('isStoryMode', PlayState.isStoryMode);
set('difficulty', PlayState.storyDifficulty);
var difficultyName:String = CoolUtil.difficulties[PlayState.storyDifficulty];
set('difficultyName', difficultyName);
set('difficultyPath', Paths.formatToSongPath(difficultyName));
set('weekRaw', PlayState.storyWeek);
set('week', WeekData.weeksList[PlayState.storyWeek]);
set('seenCutscene', PlayState.seenCutscene);
// Camera poo
set('cameraX', 0);
set('cameraY', 0);
// Screen stuff
set('screenWidth', FlxG.width);
set('screenHeight', FlxG.height);
// PlayState cringe ass nae nae bullcrap
set('curBeat', 0);
set('curStep', 0);
set('curDecBeat', 0);
set('curDecStep', 0);
set('score', 0);
set('misses', 0);
set('hits', 0);
set('rating', 0);
set('ratingName', '');
set('ratingFC', '');
set('version', MainMenuState.psychEngineVersion.trim());
set('engineVersion', MainMenuState.psychEngineForkVersion.trim());
set('inGameOver', false);
set('mustHitSection', false);
set('altAnim', false);
set('gfSection', false);
set('npsSpeedMult', game.npsSpeedMult);
// these things are useless
set('polyphonyOppo', game.polyphonyOppo);
set('polyphonyBF', game.polyphonyBF);
// Gameplay settings
set('healthGainMult', game.healthGain);
set('healthLossMult', game.healthLoss);
set('playbackRate', game.playbackRate);
set('instakillOnMiss', game.instakillOnMiss);
set('botPlay', game.cpuControlled);
set('practice', game.practiceMode);
for (i in 0...4)
{
set('defaultPlayerStrumX' + i, 0);
set('defaultPlayerStrumY' + i, 0);
set('defaultOpponentStrumX' + i, 0);
set('defaultOpponentStrumY' + i, 0);
}
// Default character positions woooo
set('defaultBoyfriendX', game.BF_X);
set('defaultBoyfriendY', game.BF_Y);
set('defaultOpponentX', game.DAD_X);
set('defaultOpponentY', game.DAD_Y);
set('defaultGirlfriendX', game.GF_X);
set('defaultGirlfriendY', game.GF_Y);
// Character shit
set('boyfriendName', PlayState.SONG.player1);
set('dadName', PlayState.SONG.player2);
set('gfName', PlayState.SONG.gfVersion);
// Some settings, no jokes
set('downscroll', ClientPrefs.downScroll);
set('middlescroll', ClientPrefs.middleScroll);
set('framerate', ClientPrefs.framerate);
set('ghostTapping', ClientPrefs.ghostTapping);
set('hideHud', ClientPrefs.hideHud);
set('timeBarType', ClientPrefs.timeBarType);
set('scoreZoom', ClientPrefs.scoreZoom);
set('cameraZoomOnBeat', ClientPrefs.camZooms);
set('flashingLights', ClientPrefs.flashing);
set('noteOffset', ClientPrefs.noteOffset);
set('healthBarAlpha', ClientPrefs.healthBarAlpha);
set('noResetButton', ClientPrefs.noReset);
set('lowQuality', ClientPrefs.lowQuality);
set('shadersEnabled', ClientPrefs.shaders);
set('scriptName', scriptName);
set('currentModDirectory', Paths.currentModDirectory);
// If you don't want this to show, you can use the lua script to change it
set('user_path', CoolSystemStuff.getUserPath());
set("user_name", CoolSystemStuff.getUsername());
#if windows
set('buildTarget', 'windows');
#elseif linux
set('buildTarget', 'linux');
#elseif mac
set('buildTarget', 'mac');
#elseif html5
set('buildTarget', 'browser');
#elseif android
set('buildTarget', 'android');
#else
set('buildTarget', 'unknown');
#end
for (name => func in customFunctions)
{
if (func != null)
Lua_helper.add_callback(lua, name, func);
}
// shader shit
registerFunction("initLuaShader", function(name:String, glslVersion:Int = 120)
{
if (!ClientPrefs.shaders)
return false;
#if (MODS_ALLOWED && SHADERS_ALLOWED)
return initLuaShader(name, glslVersion);
#else
LuaUtils.luaTrace(lua, "initLuaShader | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
return false;
});
registerFunction("setSpriteShader", function(obj:String, shader:String)
{
if (!ClientPrefs.shaders)
return false;
#if (MODS_ALLOWED && SHADERS_ALLOWED)
if (!game.runtimeShaders.exists(shader) && !initLuaShader(shader))
{
LuaUtils.luaTrace(lua, 'setSpriteShader | Shader $shader is missing! Make sure you\'ve initialized your shader first!', false, false,
FlxColor.RED);
return false;
}
var killMe:Array<String> = obj.split('.');
var leObj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
leObj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (leObj != null)
{
var arr:Array<String> = game.runtimeShaders.get(shader);
leObj.shader = new ErrorHandledRuntimeShader(shader, arr[0], arr[1]);
return true;
}
#else
LuaUtils.luaTrace(lua, "setSpriteShader | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
return false;
});
registerFunction("removeSpriteShader", function(obj:String)
{
var killMe:Array<String> = obj.split('.');
var leObj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
leObj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (leObj != null)
{
leObj.shader = null;
return true;
}
return false;
});
// camera shaders
registerFunction("setCameraShader", function(cam:String, shader:String, ?index:String)
{
final funk = PlayState.instance;
if (!ClientPrefs.shaders)
return false;
if (index == null || index.length < 1)
index = shader;
#if (MODS_ALLOWED && SHADERS_ALLOWED)
if (!funk.runtimeShaders.exists(shader) && !funk.initLuaShader(shader))
{
LuaUtils.luaTrace(lua, 'addShaderToCam | Shader $shader is missing! Make sure you\'ve initialized your shader first!', false, false,
FlxColor.RED);
return false;
}
var arr:Array<String> = funk.runtimeShaders.get(shader);
var camera = LuaUtils.getCam(cam);
@:privateAccess {
if (camera.filters == null)
camera.filters = [];
final filter = new ShaderFilter(new ErrorHandledRuntimeShader(shader, arr[0], arr[1]));
storedFilters.set(index, filter);
camera.filters.push(filter);
}
return true;
#else
LuaUtils.luaTrace(lua, "addShaderToCam | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
return false;
});
registerFunction("removeCameraShader", function(cam:String, shader:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
if (!ClientPrefs.shaders)
return false;
final camera = LuaUtils.getCam(cam);
@:privateAccess {
if (!storedFilters.exists(shader))
{
LuaUtils.luaTrace(lua, 'removeCamShader | $shader does not exist!', false, false, FlxColor.YELLOW);
return false;
}
if (camera.filters == null)
{
LuaUtils.luaTrace(lua, 'removeCamShader | camera $cam does not have any shaders!', false, false, FlxColor.YELLOW);
return false;
}
camera.filters.remove(storedFilters.get(shader));
storedFilters.remove(shader);
return true;
}
#else
LuaUtils.luaTrace(lua, 'removeCamShader | Platform unsupported for Runtime Shaders!', false, false, FlxColor.RED);
#end
return false;
});
registerFunction("getShaderBool", function(obj:String, prop:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
{
return null;
}
return shader.getBool(prop);
#else
LuaUtils.luaTrace(lua, "getShaderBool | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
return null;
#end
});
registerFunction("getShaderBoolArray", function(obj:String, prop:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
{
return null;
}
return shader.getBoolArray(prop);
#else
LuaUtils.luaTrace(lua, "getShaderBoolArray | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
return null;
#end
});
registerFunction("getShaderInt", function(obj:String, prop:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
{
return null;
}
return shader.getInt(prop);
#else
LuaUtils.luaTrace(lua, "getShaderInt | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
return null;
#end
});
registerFunction("getShaderIntArray", function(obj:String, prop:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
{
return null;
}
return shader.getIntArray(prop);
#else
LuaUtils.luaTrace(lua, "getShaderIntArray | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
return null;
#end
});
registerFunction("getShaderFloat", function(obj:String, prop:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
{
return null;
}
return shader.getFloat(prop);
#else
LuaUtils.luaTrace(lua, "getShaderFloat | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
return null;
#end
});
registerFunction("getShaderFloatArray", function(obj:String, prop:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
{
return null;
}
return shader.getFloatArray(prop);
#else
LuaUtils.luaTrace(lua, "getShaderFloatArray | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
return null;
#end
});
registerFunction("setShaderBool", function(obj:String, prop:String, value:Bool)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
shader.setBool(prop, value);
#else
LuaUtils.luaTrace(lua, "setShaderBool | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("setShaderBoolArray", function(obj:String, prop:String, values:Dynamic)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
shader.setBoolArray(prop, values);
#else
LuaUtils.luaTrace(lua, "setShaderBoolArray | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("setShaderInt", function(obj:String, prop:String, value:Int)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
shader.setInt(prop, value);
#else
LuaUtils.luaTrace(lua, "setShaderInt | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("setShaderIntArray", function(obj:String, prop:String, values:Dynamic)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
shader.setIntArray(prop, values);
#else
LuaUtils.luaTrace(lua, "setShaderIntArray | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("setShaderFloat", function(obj:String, prop:String, value:Float)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
shader.setFloat(prop, value);
#else
LuaUtils.luaTrace(lua, "setShaderFloat | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("setShaderFloatArray", function(obj:String, prop:String, values:Dynamic)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
shader.setFloatArray(prop, values);
#else
LuaUtils.luaTrace(lua, "setShaderFloatArray | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("setShaderSampler2D", function(obj:String, prop:String, bitmapdataPath:String)
{
#if (MODS_ALLOWED && SHADERS_ALLOWED)
var shader:FlxRuntimeShader = getShader(obj);
if (shader == null || !ClientPrefs.shaders)
return;
// trace('bitmapdatapath: $bitmapdataPath');
var value = Paths.image(bitmapdataPath);
if (value != null && value.bitmap != null)
{
// trace('Found bitmapdata. Width: ${value.bitmap.width} Height: ${value.bitmap.height}');
shader.setSampler2D(prop, value.bitmap);
}
#else
LuaUtils.luaTrace(lua, "setShaderSampler2D | Platform unsupported for Runtime Shaders!", false, false, FlxColor.RED);
#end
});
registerFunction("getRunningScripts", function()
{
var runningScripts:Array<String> = [];
for (idx in 0...PlayState.instance.luaArray.length)
runningScripts.push(PlayState.instance.luaArray[idx].scriptName);
return runningScripts;
});
registerFunction("callOnLuas", function(?funcName:String, ?args:Array<Dynamic>, ignoreStops = false, ignoreSelf = true, ?exclusions:Array<String>)
{
if (funcName == null)
{
#if (linc_luajit >= "0.0.6")
LuaL.error(lua, "bad argument #1 to 'callOnLuas' (string expected, got nil)");
#end
return;
}
if (args == null)
args = [];
if (exclusions == null)
exclusions = [];
Lua.getglobal(lua, 'scriptName');
final daScriptName = Lua.tostring(lua, -1);
Lua.pop(lua, 1);
if (ignoreSelf && !exclusions.contains(daScriptName))
exclusions.push(daScriptName);
PlayState.instance.callOnLuas(funcName, args, ignoreStops, exclusions);
});
registerFunction("callScript", function(?luaFile:String, ?funcName:String, ?args:Array<Dynamic>)
{
if (luaFile == null)
{
#if (linc_luajit >= "0.0.6")
LuaL.error(lua, "bad argument #1 to 'callScript' (string expected, got nil)");
#end
return;
}
if (funcName == null)
{
#if (linc_luajit >= "0.0.6")
LuaL.error(lua, "bad argument #2 to 'callScript' (string expected, got nil)");
#end
return;
}
if (args == null)
{
args = [];
}
var cervix = luaFile + ".lua";
if (luaFile.endsWith(".lua"))
cervix = luaFile;
var doPush = false;
#if MODS_ALLOWED
if (FileSystem.exists(Paths.modFolders(cervix)))
{
cervix = Paths.modFolders(cervix);
doPush = true;
}
else if (FileSystem.exists(cervix))
{
doPush = true;
}
else
{
cervix = Paths.getPreloadPath(cervix);
if (FileSystem.exists(cervix))
{
doPush = true;
}
}
#else
cervix = Paths.getPreloadPath(cervix);
if (Assets.exists(cervix))
{
doPush = true;
}
#end
if (doPush)
{
for (luaInstance in PlayState.instance.luaArray)
{
if (luaInstance.scriptName == cervix)
{
luaInstance.call(funcName, args);
return;
}
}
}
});
registerFunction("getGlobalFromScript", function(?luaFile:String, ?global:String)
{ // returns the global from a script
if (luaFile == null)
{
#if (linc_luajit >= "0.0.6")
LuaL.error(lua, "bad argument #1 to 'getGlobalFromScript' (string expected, got nil)");
#end
return;
}
if (global == null)
{
#if (linc_luajit >= "0.0.6")
LuaL.error(lua, "bad argument #2 to 'getGlobalFromScript' (string expected, got nil)");
#end
return;
}
var cervix = luaFile + ".lua";
if (luaFile.endsWith(".lua"))
cervix = luaFile;
var doPush = false;
#if MODS_ALLOWED
if (FileSystem.exists(Paths.modFolders(cervix)))
{
cervix = Paths.modFolders(cervix);
doPush = true;
}
else if (FileSystem.exists(cervix))
{
doPush = true;
}
else
{
cervix = Paths.getPreloadPath(cervix);
if (FileSystem.exists(cervix))
{
doPush = true;
}
}
#else
cervix = Paths.getPreloadPath(cervix);
if (Assets.exists(cervix))
{
doPush = true;
}
#end
if (doPush)
{
for (luaInstance in PlayState.instance.luaArray)
{
if (luaInstance.scriptName == cervix)
{
Lua.getglobal(luaInstance.lua, global);
if (Lua.isnumber(luaInstance.lua, -1))
{
Lua.pushnumber(lua, Lua.tonumber(luaInstance.lua, -1));
}
else if (Lua.isstring(luaInstance.lua, -1))
{
Lua.pushstring(lua, Lua.tostring(luaInstance.lua, -1));
}
else if (Lua.isboolean(luaInstance.lua, -1))
{
Lua.pushboolean(lua, Lua.toboolean(luaInstance.lua, -1));
}
else
{
Lua.pushnil(lua);
}
// TODO: table
Lua.pop(luaInstance.lua, 1); // remove the global
return;
}
}
}
});
registerFunction("loopTheSong", function(startingPoint:Float = 0)
{ // Hopefully this works!
Conductor.songPosition = startingPoint;
FlxG.sound.music.time = startingPoint;
PlayState.instance.loopCallback(startingPoint);
});
registerFunction("setGlobalFromScript", function(luaFile:String, global:String, val:Dynamic)
{ // returns the global from a script
var cervix = luaFile + ".lua";
if (luaFile.endsWith(".lua"))
cervix = luaFile;
var doPush = false;
#if MODS_ALLOWED
if (FileSystem.exists(Paths.modFolders(cervix)))
{
cervix = Paths.modFolders(cervix);
doPush = true;
}
else if (FileSystem.exists(cervix))
{
doPush = true;
}
else
{
cervix = Paths.getPreloadPath(cervix);
if (FileSystem.exists(cervix))
{
doPush = true;
}
}
#else
cervix = Paths.getPreloadPath(cervix);
if (Assets.exists(cervix))
{
doPush = true;
}
#end
if (doPush)
{
for (luaInstance in PlayState.instance.luaArray)
{
if (luaInstance.scriptName == cervix)
{
luaInstance.set(global, val);
}
}
}
});
set("isRunning", function(luaFile:String)
{
var cervix = luaFile + ".lua";
if (luaFile.endsWith(".lua"))
cervix = luaFile;
var doPush = false;
#if MODS_ALLOWED
if (FileSystem.exists(Paths.modFolders(cervix)))
{
cervix = Paths.modFolders(cervix);
doPush = true;
}
else if (FileSystem.exists(cervix))
{
doPush = true;
}
else
{
cervix = Paths.getPreloadPath(cervix);
if (FileSystem.exists(cervix))
{
doPush = true;
}
}
#else
cervix = Paths.getPreloadPath(cervix);
if (Assets.exists(cervix))
{
doPush = true;
}
#end
if (doPush)
{
for (luaInstance in PlayState.instance.luaArray)
{
if (luaInstance.scriptName == cervix)
return true;
}
}
return false;
});
registerFunction("addLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false)
{ // would be dope asf.
var cervix = luaFile + ".lua";
if (luaFile.endsWith(".lua"))
cervix = luaFile;
var doPush = false;
#if MODS_ALLOWED
if (FileSystem.exists(Paths.modFolders(cervix)))
{
cervix = Paths.modFolders(cervix);
doPush = true;
}
else if (FileSystem.exists(cervix))
{
doPush = true;
}
else
{
cervix = Paths.getPreloadPath(cervix);
if (FileSystem.exists(cervix))
{
doPush = true;
}
}
#else
cervix = Paths.getPreloadPath(cervix);
if (Assets.exists(cervix))
{
doPush = true;
}
#end
if (doPush)
{
if (!ignoreAlreadyRunning)
{
for (luaInstance in PlayState.instance.luaArray)
{
if (luaInstance.scriptName == cervix)
{
LuaUtils.luaTrace(lua, 'addLuaScript | The script "' + cervix + '" is already running!');
return;
}
}
}
PlayState.instance.luaArray.push(new FunkinLua(cervix));
return;
}
LuaUtils.luaTrace(lua, "addLuaScript | Script doesn't exist!", false, false, FlxColor.RED);
});
registerFunction("removeLuaScript", function(luaFile:String, ?ignoreAlreadyRunning:Bool = false)
{ // would be dope asf.
var cervix = luaFile + ".lua";
if (luaFile.endsWith(".lua"))
cervix = luaFile;
var doPush = false;
#if MODS_ALLOWED
if (FileSystem.exists(Paths.modFolders(cervix)))
{
cervix = Paths.modFolders(cervix);
doPush = true;
}
else if (FileSystem.exists(cervix))
{
doPush = true;
}
else
{
cervix = Paths.getPreloadPath(cervix);
if (FileSystem.exists(cervix))
{
doPush = true;
}
}
#else
cervix = Paths.getPreloadPath(cervix);
if (Assets.exists(cervix))
{
doPush = true;
}
#end
if (doPush)
{
if (!ignoreAlreadyRunning)
{
for (luaInstance in PlayState.instance.luaArray)
{
if (luaInstance.scriptName == cervix)
{
// LuaUtils.luaTrace(lua, 'The script "' + cervix + '" is already running!');
PlayState.instance.luaArray.remove(luaInstance);
return;
}
}
}
return;
}
LuaUtils.luaTrace(lua, "removeLuaScript | Script doesn't exist!", false, false, FlxColor.RED);
});
registerFunction("loadSong", function(?name:String = null, ?difficultyNum:Int = -1)
{
if (name == null || name.length < 1)
name = PlayState.SONG.song;
if (difficultyNum == -1)
difficultyNum = PlayState.storyDifficulty;
var poop = Highscore.formatSong(name, difficultyNum);
PlayState.SONG = Song.loadFromJson(poop, name);
PlayState.storyDifficulty = difficultyNum;
PlayState.instance.persistentUpdate = false;
LoadingState.loadAndSwitchState(PlayState.new);
FlxG.sound.music.pause();
FlxG.sound.music.volume = 0;
if (PlayState.instance.vocals != null)
{
PlayState.instance.vocals.pause();
PlayState.instance.vocals.volume = 0;
}
});
registerFunction("loadGraphic", function(variable:String, image:String, ?gridX:Int = 0, ?gridY:Int = 0)
{
var killMe:Array<String> = variable.split('.');
var spr:FlxSprite = getObjectDirectly(killMe[0]);
var animated = gridX != 0 || gridY != 0;
if (killMe.length > 1)
{
spr = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (spr != null && image != null && image.length > 0)
{
spr.loadGraphic(Paths.image(image), animated, gridX, gridY);
}
});
registerFunction("loadFrames", function(variable:String, image:String, spriteType:String = "sparrow")
{
var killMe:Array<String> = variable.split('.');
var spr:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
spr = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (spr != null && image != null && image.length > 0)
{
loadFrames(spr, image, spriteType);
}
});
registerFunction("getProperty", function(variable:String)
{
var result:Dynamic = null;
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
result = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
else
result = getVarInArray(getInstance(), variable);
return result;
});
registerFunction("setProperty", function(variable:String, value:Dynamic)
{
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
setVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1], value);
return true;
}
setVarInArray(getInstance(), variable, value);
return true;
});
registerFunction("getPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic)
{
var shitMyPants:Array<String> = obj.split('.');
var realObject:Dynamic = Reflect.getProperty(getInstance(), obj);
if (shitMyPants.length > 1)
realObject = getPropertyLoopThingWhatever(shitMyPants, true, false);
if (Std.isOfType(realObject, FlxTypedGroup))
{
var result:Dynamic = getGroupStuff(realObject.members[index], variable);
return result;
}
var leArray:Dynamic = realObject[index];
if (leArray != null)
{
var result:Dynamic = null;
if (Type.typeof(variable) == ValueType.TInt)
result = leArray[variable];
else
result = getGroupStuff(leArray, variable);
return result;
}
LuaUtils.luaTrace(lua, "getPropertyFromGroup | Object #" + index + " from group: " + obj + " doesn't exist!", false, false, FlxColor.RED);
return null;
});
registerFunction("setPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic, value:Dynamic)
{
var shitMyPants:Array<String> = obj.split('.');
var realObject:Dynamic = Reflect.getProperty(getInstance(), obj);
if (shitMyPants.length > 1)
realObject = getPropertyLoopThingWhatever(shitMyPants, true, false);
if (Std.isOfType(realObject, FlxTypedGroup))
{
setGroupStuff(realObject.members[index], variable, value);
return;
}
var leArray:Dynamic = realObject[index];
if (leArray != null)
{
if (Type.typeof(variable) == ValueType.TInt)
{
leArray[variable] = value;
return;
}
setGroupStuff(leArray, variable, value);
}
});
registerFunction("removeFromGroup", function(obj:String, index:Int, dontDestroy:Bool = false)
{
if (Std.isOfType(Reflect.getProperty(getInstance(), obj), FlxTypedGroup))
{
var sex = Reflect.getProperty(getInstance(), obj).members[index];
if (!dontDestroy)
sex.kill();
Reflect.getProperty(getInstance(), obj).remove(sex, true);
if (!dontDestroy)
sex.destroy();
return;
}
Reflect.getProperty(getInstance(), obj).remove(Reflect.getProperty(getInstance(), obj)[index]);
});
registerFunction("getPropertyFromClass", function(classVar:String, variable:String)
{
@:privateAccess
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
var coverMeInPiss:Dynamic = getVarInArray(Type.resolveClass(classVar), killMe[0]);
for (i in 1...killMe.length - 1)
{
coverMeInPiss = getVarInArray(coverMeInPiss, killMe[i]);
}
return getVarInArray(coverMeInPiss, killMe[killMe.length - 1]);
}
return getVarInArray(Type.resolveClass(classVar), variable);
});
registerFunction("setPropertyFromClass", function(classVar:String, variable:String, value:Dynamic)
{
@:privateAccess
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
var coverMeInPiss:Dynamic = getVarInArray(Type.resolveClass(classVar), killMe[0]);
for (i in 1...killMe.length - 1)
{
coverMeInPiss = getVarInArray(coverMeInPiss, killMe[i]);
}
setVarInArray(coverMeInPiss, killMe[killMe.length - 1], value);
return true;
}
setVarInArray(Type.resolveClass(classVar), variable, value);
return true;
});
// shitass stuff for epic coders like me B) *image of obama giving himself a medal*
registerFunction("getObjectOrder", function(obj:String)
{
var killMe:Array<String> = obj.split('.');
var leObj:FlxBasic = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
leObj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (leObj != null)
{
return getInstance().members.indexOf(leObj);
}
LuaUtils.luaTrace(lua, "getObjectOrder | Object " + obj + " doesn't exist!", false, false, FlxColor.RED);
return -1;
});
registerFunction("setObjectOrder", function(obj:String, position:Int)
{
var killMe:Array<String> = obj.split('.');
var leObj:FlxBasic = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
leObj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (leObj != null)
{
getInstance().remove(leObj, true);
getInstance().insert(position, leObj);
return;
}
LuaUtils.luaTrace(lua, "setObjectOrder | Object " + obj + " doesn't exist!", false, false, FlxColor.RED);
});
// gay ass tweens
registerFunction("doTweenX", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {x: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenX | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
registerFunction("doTweenScale", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
PlayState.instance.modchartTweens.set(tag,
FlxTween.tween(penisExam, {"scale.x": value, "scale.y": value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenScale | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
registerFunction("doTweenY", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {y: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenY | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
registerFunction("doTweenAngle", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {angle: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenAngle | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
registerFunction("doTweenAlpha", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {alpha: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenAlpha | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
registerFunction("doTweenZoom", function(tag:String, vars:String, value:Dynamic, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
if (vars == 'camHud' || vars == 'camGame' || vars == 'Hud' || vars == 'Game')
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(penisExam, {zoom: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenZoom | Can't tween object " + vars + ". Value needs to be a camera.", false, false, FlxColor.RED);
}
}
else
{
LuaUtils.luaTrace(lua, "doTweenZoom | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
registerFunction("doTweenColor", function(tag:String, vars:String, targetColor:String, duration:Float, ease:String)
{
var penisExam:Dynamic = tweenShit(tag, vars);
if (penisExam != null)
{
var color:Int = Std.parseInt(targetColor);
if (!targetColor.startsWith('0x'))
color = Std.parseInt('0xff' + targetColor);
var curColor:FlxColor = penisExam.color;
curColor.alphaFloat = penisExam.alpha;
PlayState.instance.modchartTweens.set(tag, FlxTween.color(penisExam, duration / PlayState.instance.playbackRate, curColor, color, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.modchartTweens.remove(tag);
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
}
}));
}
else
{
LuaUtils.luaTrace(lua, "doTweenColor | Couldn't find object: " + vars, false, false, FlxColor.RED);
}
});
// Tween shit, but for strums
registerFunction("noteTweenX", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {x: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("noteTweenY", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {y: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("noteTweenAngle", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {angle: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("noteTweenDirection", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {direction: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("mouseClicked", function(button:String)
{
var boobs = FlxG.mouse.justPressed;
switch (button)
{
case 'middle':
boobs = FlxG.mouse.justPressedMiddle;
case 'right':
boobs = FlxG.mouse.justPressedRight;
}
return boobs;
});
registerFunction("mousePressed", function(button:String)
{
var boobs = FlxG.mouse.pressed;
switch (button)
{
case 'middle':
boobs = FlxG.mouse.pressedMiddle;
case 'right':
boobs = FlxG.mouse.pressedRight;
}
return boobs;
});
registerFunction("mouseReleased", function(button:String)
{
var boobs = FlxG.mouse.justReleased;
switch (button)
{
case 'middle':
boobs = FlxG.mouse.justReleasedMiddle;
case 'right':
boobs = FlxG.mouse.justReleasedRight;
}
return boobs;
});
registerFunction("noteTweenAngle", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {angle: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("noteTweenAlpha", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {alpha: value}, duration / PlayState.instance.playbackRate, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("noteTweenScaleX", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {"scale.x": value - 0.3}, duration, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("noteTweenScaleY", function(tag:String, note:Int, value:Dynamic, duration:Float, ease:String)
{
cancelTween(tag);
if (note < 0)
note = 0;
var testicle:StrumNote = PlayState.instance.strumLineNotes.members[note % PlayState.instance.strumLineNotes.length];
if (testicle != null)
{
PlayState.instance.modchartTweens.set(tag, FlxTween.tween(testicle, {"scale.y": value - 0.3}, duration, {
ease: LuaUtils.getFlxEaseByString(ease),
onComplete: function(twn:FlxTween)
{
PlayState.instance.callOnLuas('onTweenCompleted', [tag]);
PlayState.instance.modchartTweens.remove(tag);
}
}));
}
});
registerFunction("cancelTween", function(tag:String)
{
cancelTween(tag);
});
registerFunction("runTimer", function(tag:String, time:Float = 1, loops:Int = 1)
{
cancelTimer(tag);
PlayState.instance.modchartTimers.set(tag, new FlxTimer().start(time, function(tmr:FlxTimer)
{
if (tmr.finished)
{
PlayState.instance.modchartTimers.remove(tag);
}
PlayState.instance.callOnLuas('onTimerCompleted', [tag, tmr.loops, tmr.loopsLeft]);
// trace('Timer Completed: ' + tag);
}, loops));
});
registerFunction("cancelTimer", function(tag:String)
{
cancelTimer(tag);
});
/*registerFunction("getPropertyAdvanced", function(varsStr:String) {
var variables:Array<String> = varsStr.replace(' ', '').split(',');
var leClass:Class<Dynamic> = Type.resolveClass(variables[0]);
if(variables.length > 2) {
var curProp:Dynamic = Reflect.getProperty(leClass, variables[1]);
if(variables.length > 3) {
for (i in 2...variables.length-1) {
curProp = Reflect.getProperty(curProp, variables[i]);
}
}
return Reflect.getProperty(curProp, variables[variables.length-1]);
} else if(variables.length == 2) {
return Reflect.getProperty(leClass, variables[variables.length-1]);
}
return null;
});
registerFunction("setPropertyAdvanced", function(varsStr:String, value:Dynamic) {
var variables:Array<String> = varsStr.replace(' ', '').split(',');
var leClass:Class<Dynamic> = Type.resolveClass(variables[0]);
if(variables.length > 2) {
var curProp:Dynamic = Reflect.getProperty(leClass, variables[1]);
if(variables.length > 3) {
for (i in 2...variables.length-1) {
curProp = Reflect.getProperty(curProp, variables[i]);
}
}
return Reflect.setProperty(curProp, variables[variables.length-1], value);
} else if(variables.length == 2) {
return Reflect.setProperty(leClass, variables[variables.length-1], value);
}
});*/
// stupid bietch ass functions
registerFunction("addScore", function(value:Float = 0)
{
PlayState.instance.songScore += value;
PlayState.instance.RecalculateRating();
});
registerFunction("addMisses", function(value:Int = 0)
{
PlayState.instance.songMisses += value;
PlayState.instance.RecalculateRating();
});
registerFunction("addHits", function(value:Int = 0)
{
PlayState.instance.songHits += value;
PlayState.instance.RecalculateRating();
});
registerFunction("addCombo", function(value:Int = 0)
{
PlayState.instance.combo += value;
PlayState.instance.RecalculateRating();
});
registerFunction("addNPS", function(value:Int = 0)
{
PlayState.instance.nps += value;
});
registerFunction("setScore", function(value:Float = 0)
{
var newScore:Float = value;
PlayState.instance.songScore = newScore;
PlayState.instance.RecalculateRating();
});
registerFunction("setMisses", function(value:Int = 0)
{
PlayState.instance.songMisses = value;
PlayState.instance.RecalculateRating();
});
registerFunction("setHits", function(value:Int = 0)
{
PlayState.instance.songHits = value;
PlayState.instance.RecalculateRating();
});
registerFunction("getScore", function()
{
return PlayState.instance.songScore;
});
registerFunction("getMisses", function()
{
return PlayState.instance.songMisses;
});
registerFunction("getHits", function()
{
return PlayState.instance.songHits;
});
registerFunction("setHealth", function(value:Float = 0)
{
PlayState.instance.health = value;
});
registerFunction("addHealth", function(value:Float = 0)
{
PlayState.instance.health += value;
});
registerFunction("addPlaybackSpeed", function(value:Float = 0)
{
PlayState.instance.playbackRate += value;
});
registerFunction("getHealth", function()
{
return PlayState.instance.health;
});
registerFunction("getPlaybackSpeed", function()
{
return PlayState.instance.playbackRate;
});
registerFunction("setPlaybackSpeed", function(value:Float = 0)
{
PlayState.instance.playbackRate = value;
});
registerFunction("changeMaxHealth", function(value:Float = 0)
{
{
var bar = PlayState.instance.healthBar;
PlayState.instance.maxHealth = value;
bar.setRange(0, value);
}
});
registerFunction("getMaxHealth", function()
{
return PlayState.instance.maxHealth;
});
registerFunction("getColorFromHex", function(color:String)
{
if (!color.startsWith('0x'))
color = '0xff' + color;
return Std.parseInt(color);
});
registerFunction("keyboardJustPressed", function(name:String)
{
return Reflect.getProperty(FlxG.keys.justPressed, name);
});
registerFunction("keyboardPressed", function(name:String)
{
return Reflect.getProperty(FlxG.keys.pressed, name);
});
registerFunction("keyboardReleased", function(name:String)
{
return Reflect.getProperty(FlxG.keys.justReleased, name);
});
registerFunction("anyGamepadJustPressed", function(name:String)
{
return FlxG.gamepads.anyJustPressed(name);
});
registerFunction("anyGamepadPressed", function(name:String)
{
return FlxG.gamepads.anyPressed(name);
});
registerFunction("anyGamepadReleased", function(name:String)
{
return FlxG.gamepads.anyJustReleased(name);
});
registerFunction("gamepadAnalogX", function(id:Int, ?leftStick:Bool = true)
{
var controller = FlxG.gamepads.getByID(id);
if (controller == null)
{
return 0.0;
}
return controller.getXAxis(leftStick ? LEFT_ANALOG_STICK : RIGHT_ANALOG_STICK);
});
registerFunction("gamepadAnalogY", function(id:Int, ?leftStick:Bool = true)
{
var controller = FlxG.gamepads.getByID(id);
if (controller == null)
{
return 0.0;
}
return controller.getYAxis(leftStick ? LEFT_ANALOG_STICK : RIGHT_ANALOG_STICK);
});
registerFunction("gamepadJustPressed", function(id:Int, name:String)
{
var controller = FlxG.gamepads.getByID(id);
if (controller == null)
{
return false;
}
return Reflect.getProperty(controller.justPressed, name) == true;
});
registerFunction("gamepadPressed", function(id:Int, name:String)
{
var controller = FlxG.gamepads.getByID(id);
if (controller == null)
{
return false;
}
return Reflect.getProperty(controller.pressed, name) == true;
});
registerFunction("gamepadReleased", function(id:Int, name:String)
{
var controller = FlxG.gamepads.getByID(id);
if (controller == null)
{
return false;
}
return Reflect.getProperty(controller.justReleased, name) == true;
});
registerFunction("keyJustPressed", function(name:String)
{
var key:Bool = false;
switch (name)
{
case 'left':
key = PlayState.instance.getControl('NOTE_LEFT_P');
case 'down':
key = PlayState.instance.getControl('NOTE_DOWN_P');
case 'up':
key = PlayState.instance.getControl('NOTE_UP_P');
case 'right':
key = PlayState.instance.getControl('NOTE_RIGHT_P');
case 'accept':
key = PlayState.instance.getControl('ACCEPT');
case 'back':
key = PlayState.instance.getControl('BACK');
case 'pause':
key = PlayState.instance.getControl('PAUSE');
case 'reset':
key = PlayState.instance.getControl('RESET');
case 'space':
key = FlxG.keys.justPressed.SPACE; // an extra key for convenience
}
return key;
});
registerFunction("keyPressed", function(name:String)
{
var key:Bool = false;
switch (name)
{
case 'left':
key = PlayState.instance.getControl('NOTE_LEFT');
case 'down':
key = PlayState.instance.getControl('NOTE_DOWN');
case 'up':
key = PlayState.instance.getControl('NOTE_UP');
case 'right':
key = PlayState.instance.getControl('NOTE_RIGHT');
case 'space':
key = FlxG.keys.pressed.SPACE; // an extra key for convenience
}
return key;
});
registerFunction("keyReleased", function(name:String)
{
var key:Bool = false;
switch (name)
{
case 'left':
key = PlayState.instance.getControl('NOTE_LEFT_R');
case 'down':
key = PlayState.instance.getControl('NOTE_DOWN_R');
case 'up':
key = PlayState.instance.getControl('NOTE_UP_R');
case 'right':
key = PlayState.instance.getControl('NOTE_RIGHT_R');
case 'space':
key = FlxG.keys.justReleased.SPACE; // an extra key for convenience
}
return key;
});
registerFunction("addCharacterToList", function(name:String, type:String)
{
var charType:Int = 0;
switch (type.toLowerCase())
{
case 'dad':
charType = 1;
case 'gf' | 'girlfriend':
charType = 2;
}
PlayState.instance.addCharacterToList(name, charType);
});
registerFunction("precacheImage", function(name:String)
{
Paths.image(name);
});
registerFunction("precacheSound", function(name:String)
{
Paths.sound(name);
});
registerFunction("precacheMusic", function(name:String)
{
Paths.music(name);
});
registerFunction("triggerEvent", function(name:String, arg1:Dynamic, arg2:Dynamic, strumTime:Float)
{
var value1:String = arg1;
var value2:String = arg2;
PlayState.instance.triggerEventNote(name, value1, value2, strumTime);
// trace('Triggered event: ' + name + ', ' + value1 + ', ' + value2);
return true;
});
registerFunction("startCountdown", function()
{
PlayState.instance.startCountdown();
return true;
});
registerFunction("endSong", function()
{
PlayState.instance.KillNotes();
PlayState.instance.endSong();
return true;
});
registerFunction("restartSong", function(?skipTransition:Bool = false)
{
PlayState.instance.persistentUpdate = false;
PauseSubState.restartSong(skipTransition);
return true;
});
registerFunction("exitSong", function(?skipTransition:Bool = false)
{
if (skipTransition)
{
FlxTransitionableState.skipNextTransIn = true;
FlxTransitionableState.skipNextTransOut = true;
}
if (FlxG.sound.music != null)
FlxG.sound.music.stop();
if (PlayState.isStoryMode)
FlxG.switchState(StoryMenuState.new);
else
FlxG.switchState(FreeplayState.new);
FlxG.sound.playMusic(Paths.music('freakyMenu'));
PlayState.changedDifficulty = false;
PlayState.chartingMode = false;
PlayState.instance.transitioning = true;
WeekData.loadTheFirstEnabledMod();
return true;
});
registerFunction("getSongPosition", function()
{
return Conductor.songPosition;
});
registerFunction("getCharacterX", function(type:String)
{
switch (type.toLowerCase())
{
case 'dad' | 'opponent':
return PlayState.instance.dadGroup.x;
case 'gf' | 'girlfriend':
return PlayState.instance.gfGroup.x;
default:
return PlayState.instance.boyfriendGroup.x;
}
});
registerFunction("setCharacterX", function(type:String, value:Float)
{
switch (type.toLowerCase())
{
case 'dad' | 'opponent':
PlayState.instance.dadGroup.x = value;
case 'gf' | 'girlfriend':
PlayState.instance.gfGroup.x = value;
default:
PlayState.instance.boyfriendGroup.x = value;
}
});
registerFunction("getCharacterY", function(type:String)
{
switch (type.toLowerCase())
{
case 'dad' | 'opponent':
return PlayState.instance.dadGroup.y;
case 'gf' | 'girlfriend':
return PlayState.instance.gfGroup.y;
default:
return PlayState.instance.boyfriendGroup.y;
}
});
registerFunction("setCharacterY", function(type:String, value:Float)
{
switch (type.toLowerCase())
{
case 'dad' | 'opponent':
PlayState.instance.dadGroup.y = value;
case 'gf' | 'girlfriend':
PlayState.instance.gfGroup.y = value;
default:
PlayState.instance.boyfriendGroup.y = value;
}
});
registerFunction("cameraSetTarget", function(target:String)
{
var isDad:Bool = false;
if (target == 'dad')
{
isDad = true;
}
PlayState.instance.moveCamera(isDad);
return isDad;
});
registerFunction("cameraShake", function(camera:String, intensity:Float, duration:Float)
{
LuaUtils.cameraFromString(camera).shake(intensity, duration / PlayState.instance.playbackRate);
});
registerFunction("cameraFlash", function(camera:String, color:String, duration:Float, forced:Bool)
{
var colorNum:Int = Std.parseInt(color);
if (!color.startsWith('0x'))
colorNum = Std.parseInt('0xff' + color);
LuaUtils.cameraFromString(camera).flash(colorNum, duration / PlayState.instance.playbackRate, null, forced);
});
registerFunction("cameraFade", function(camera:String, color:String, duration:Float, forced:Bool, ?fadeOut:Bool = false)
{
var colorNum:Int = Std.parseInt(color);
if (!color.startsWith('0x'))
colorNum = Std.parseInt('0xff' + color);
LuaUtils.cameraFromString(camera).fade(colorNum, duration / PlayState.instance.playbackRate, fadeOut, null, forced);
});
registerFunction("setRatingPercent", function(value:Float)
{
PlayState.instance.ratingPercent = value;
});
registerFunction("setRatingName", function(value:String)
{
PlayState.instance.ratingName = value;
});
registerFunction("setRatingFC", function(value:String)
{
PlayState.instance.ratingFC = value;
});
registerFunction("getMouseX", function(camera:String)
{
var cam:FlxCamera = LuaUtils.cameraFromString(camera);
return FlxG.mouse.getScreenPosition(cam).x;
});
registerFunction("getMouseY", function(camera:String)
{
var cam:FlxCamera = LuaUtils.cameraFromString(camera);
return FlxG.mouse.getScreenPosition(cam).y;
});
registerFunction("getMidpointX", function(variable:String)
{
var killMe:Array<String> = variable.split('.');
var obj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
obj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (obj != null)
return obj.getMidpoint().x;
return 0;
});
registerFunction("getMidpointY", function(variable:String)
{
var killMe:Array<String> = variable.split('.');
var obj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
obj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (obj != null)
return obj.getMidpoint().y;
return 0;
});
registerFunction("getGraphicMidpointX", function(variable:String)
{
var killMe:Array<String> = variable.split('.');
var obj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
obj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (obj != null)
return obj.getGraphicMidpoint().x;
return 0;
});
registerFunction("getGraphicMidpointY", function(variable:String)
{
var killMe:Array<String> = variable.split('.');
var obj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
obj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (obj != null)
return obj.getGraphicMidpoint().y;
return 0;
});
registerFunction("getScreenPositionX", function(variable:String)
{
var killMe:Array<String> = variable.split('.');
var obj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
obj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (obj != null)
return obj.getScreenPosition().x;
return 0;
});
registerFunction("getScreenPositionY", function(variable:String)
{
var killMe:Array<String> = variable.split('.');
var obj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
obj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (obj != null)
return obj.getScreenPosition().y;
return 0;
});
registerFunction("characterDance", function(character:String)
{
switch (character.toLowerCase())
{
case 'dad':
PlayState.instance.dad.dance();
case 'gf' | 'girlfriend':
if (PlayState.instance.gf != null)
PlayState.instance.gf.dance();
default:
PlayState.instance.boyfriend.dance();
}
});
registerFunction("makeLuaSprite", function(tag:String, image:String, x:Float, y:Float)
{
tag = tag.replace('.', '');
resetSpriteTag(tag);
var leSprite:ModchartSprite = new ModchartSprite(x, y);
if (image != null && image.length > 0)
{
leSprite.loadGraphic(Paths.image(image));
}
leSprite.antialiasing = ClientPrefs.globalAntialiasing;
PlayState.instance.modchartSprites.set(tag, leSprite);
leSprite.active = true;
});
registerFunction("makeAnimatedLuaSprite", function(tag:String, image:String, x:Float, y:Float, ?spriteType:String = "sparrow")
{
tag = tag.replace('.', '');
resetSpriteTag(tag);
var leSprite:ModchartSprite = new ModchartSprite(x, y);
loadFrames(leSprite, image, spriteType);
leSprite.antialiasing = ClientPrefs.globalAntialiasing;
PlayState.instance.modchartSprites.set(tag, leSprite);
});
registerFunction("makeGraphic", function(obj:String, width:Int, height:Int, color:String)
{
var colorNum:Int = Std.parseInt(color);
if (!color.startsWith('0x'))
colorNum = Std.parseInt('0xff' + color);
var spr:FlxSprite = PlayState.instance.getLuaObject(obj, false);
if (spr != null)
{
PlayState.instance.getLuaObject(obj, false).makeGraphic(width, height, colorNum);
return;
}
var object:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (object != null)
{
object.makeGraphic(width, height, colorNum);
}
});
registerFunction("addAnimationByPrefix", function(obj:String, name:String, prefix:String, framerate:Int = 24, loop:Bool = true)
{
if (PlayState.instance.getLuaObject(obj, false) != null)
{
var cock:FlxSprite = PlayState.instance.getLuaObject(obj, false);
cock.animation.addByPrefix(name, prefix, framerate, loop);
if (cock.animation.curAnim == null)
{
cock.animation.play(name, true);
}
return;
}
var cock:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (cock != null)
{
cock.animation.addByPrefix(name, prefix, framerate, loop);
if (cock.animation.curAnim == null)
{
cock.animation.play(name, true);
}
}
});
registerFunction("addAnimation", function(obj:String, name:String, frames:Array<Int>, framerate:Int = 24, loop:Bool = true)
{
if (PlayState.instance.getLuaObject(obj, false) != null)
{
var cock:FlxSprite = PlayState.instance.getLuaObject(obj, false);
cock.animation.add(name, frames, framerate, loop);
if (cock.animation.curAnim == null)
{
cock.animation.play(name, true);
}
return;
}
var cock:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (cock != null)
{
cock.animation.add(name, frames, framerate, loop);
if (cock.animation.curAnim == null)
{
cock.animation.play(name, true);
}
}
});
registerFunction("addAnimationByIndices", function(obj:String, name:String, prefix:String, indices:String, framerate:Int = 24)
{
return addAnimByIndices(obj, name, prefix, indices, framerate, false);
});
registerFunction("addAnimationByIndicesLoop", function(obj:String, name:String, prefix:String, indices:String, framerate:Int = 24)
{
return addAnimByIndices(obj, name, prefix, indices, framerate, true);
});
registerFunction("playAnim", function(obj:String, name:String, forced:Bool = false, ?reverse:Bool = false, ?startFrame:Int = 0)
{
if (PlayState.instance.getLuaObject(obj, false) != null)
{
var luaObj:FlxSprite = PlayState.instance.getLuaObject(obj, false);
if (luaObj.animation.getByName(name) != null)
{
luaObj.animation.play(name, forced, reverse, startFrame);
if (Std.isOfType(luaObj, ModchartSprite))
{
// convert luaObj to ModchartSprite
var obj:Dynamic = luaObj;
var luaObj:ModchartSprite = obj;
var daOffset = luaObj.animOffsets.get(name);
if (luaObj.animOffsets.exists(name))
{
luaObj.offset.set(daOffset[0], daOffset[1]);
}
}
}
return true;
}
var spr:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (spr != null)
{
if (spr.animation.getByName(name) != null)
{
if (Std.isOfType(spr, Character))
{
// convert spr to Character
var obj:Dynamic = spr;
var spr:Character = obj;
spr.playAnim(name, forced, reverse, startFrame);
}
else
spr.animation.play(name, forced, reverse, startFrame);
}
return true;
}
return false;
});
registerFunction("addOffset", function(obj:String, anim:String, x:Float, y:Float)
{
if (PlayState.instance.modchartSprites.exists(obj))
{
PlayState.instance.modchartSprites.get(obj).animOffsets.set(anim, [x, y]);
return true;
}
var char:Character = Reflect.getProperty(getInstance(), obj);
if (char != null)
{
char.addOffset(anim, x, y);
return true;
}
return false;
});
registerFunction("setScrollFactor", function(obj:String, scrollX:Float, scrollY:Float)
{
if (PlayState.instance.getLuaObject(obj, false) != null)
{
PlayState.instance.getLuaObject(obj, false).scrollFactor.set(scrollX, scrollY);
return;
}
var object:FlxObject = Reflect.getProperty(getInstance(), obj);
if (object != null)
{
object.scrollFactor.set(scrollX, scrollY);
}
});
registerFunction("addLuaSprite", function(tag:String, front:Bool = false)
{
if (PlayState.instance.modchartSprites.exists(tag))
{
var shit:ModchartSprite = PlayState.instance.modchartSprites.get(tag);
if (!shit.wasAdded)
{
if (front)
{
getInstance().add(shit);
}
else
{
if (PlayState.instance.isDead)
{
GameOverSubstate.instance.insert(GameOverSubstate.instance.members.indexOf(GameOverSubstate.instance.boyfriend), shit);
}
else
{
var position:Int = PlayState.instance.members.indexOf(PlayState.instance.gfGroup);
if (PlayState.instance.members.indexOf(PlayState.instance.boyfriendGroup) < position)
{
position = PlayState.instance.members.indexOf(PlayState.instance.boyfriendGroup);
}
else if (PlayState.instance.members.indexOf(PlayState.instance.dadGroup) < position)
{
position = PlayState.instance.members.indexOf(PlayState.instance.dadGroup);
}
PlayState.instance.insert(position, shit);
}
}
shit.wasAdded = true;
// trace('added a thing: ' + tag);
}
}
});
registerFunction("setGraphicSize", function(obj:String, x:Int, y:Int = 0, updateHitbox:Bool = true)
{
if (PlayState.instance.getLuaObject(obj) != null)
{
var shit:FlxSprite = PlayState.instance.getLuaObject(obj);
shit.setGraphicSize(x, y);
if (updateHitbox)
shit.updateHitbox();
return;
}
var killMe:Array<String> = obj.split('.');
var poop:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
poop = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (poop != null)
{
poop.setGraphicSize(x, y);
if (updateHitbox)
poop.updateHitbox();
return;
}
LuaUtils.luaTrace(lua, "setGraphicSize | Couldn't find object: " + obj, false, false, FlxColor.RED);
});
registerFunction("scaleObject", function(obj:String, x:Float, y:Float, updateHitbox:Bool = true)
{
if (PlayState.instance.getLuaObject(obj) != null)
{
var shit:FlxSprite = PlayState.instance.getLuaObject(obj);
shit.scale.set(x, y);
if (updateHitbox)
shit.updateHitbox();
return;
}
var killMe:Array<String> = obj.split('.');
var poop:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
poop = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (poop != null)
{
poop.scale.set(x, y);
if (updateHitbox)
poop.updateHitbox();
return;
}
LuaUtils.luaTrace(lua, "scaleObject | Couldn't find object: " + obj, false, false, FlxColor.RED);
});
registerFunction("updateHitbox", function(obj:String)
{
if (PlayState.instance.getLuaObject(obj) != null)
{
var shit:FlxSprite = PlayState.instance.getLuaObject(obj);
shit.updateHitbox();
return;
}
var poop:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (poop != null)
{
poop.updateHitbox();
return;
}
LuaUtils.luaTrace(lua, "updateHitbox | Couldn't find object: " + obj, false, false, FlxColor.RED);
});
registerFunction("updateHitboxFromGroup", function(group:String, index:Int)
{
if (Std.isOfType(Reflect.getProperty(getInstance(), group), FlxTypedGroup))
{
Reflect.getProperty(getInstance(), group).members[index].updateHitbox();
return;
}
Reflect.getProperty(getInstance(), group)[index].updateHitbox();
});
registerFunction("removeLuaSprite", function(tag:String, destroy:Bool = true)
{
if (!PlayState.instance.modchartSprites.exists(tag))
{
return;
}
var pee:ModchartSprite = PlayState.instance.modchartSprites.get(tag);
if (destroy)
{
pee.kill();
}
if (pee.wasAdded)
{
getInstance().remove(pee, true);
pee.wasAdded = false;
}
if (destroy)
{
pee.destroy();
PlayState.instance.modchartSprites.remove(tag);
}
});
registerFunction("luaSpriteExists", function(tag:String)
{
return PlayState.instance.modchartSprites.exists(tag);
});
registerFunction("luaTextExists", function(tag:String)
{
return PlayState.instance.modchartTexts.exists(tag);
});
registerFunction("luaSoundExists", function(tag:String)
{
return PlayState.instance.modchartSounds.exists(tag);
});
registerFunction("setHealthBarColors", function(leftHex:String, rightHex:String)
{
var left:FlxColor = Std.parseInt(leftHex);
if (!leftHex.startsWith('0x'))
left = Std.parseInt('0xff' + leftHex);
var right:FlxColor = Std.parseInt(rightHex);
if (!rightHex.startsWith('0x'))
right = Std.parseInt('0xff' + rightHex);
PlayState.instance.healthBar.createFilledBar(left, right);
PlayState.instance.healthBar.updateBar();
});
registerFunction("setTimeBarColors", function(leftHex:String, rightHex:String)
{
var left:FlxColor = Std.parseInt(leftHex);
if (!leftHex.startsWith('0x'))
left = Std.parseInt('0xff' + leftHex);
var right:FlxColor = Std.parseInt(rightHex);
if (!rightHex.startsWith('0x'))
right = Std.parseInt('0xff' + rightHex);
PlayState.instance.timeBar.createFilledBar(right, left);
PlayState.instance.timeBar.updateBar();
});
registerFunction("setObjectCamera", function(obj:String, camera:String = '')
{
var real = game.getLuaObject(obj);
if (real != null)
{
real.cameras = [LuaUtils.cameraFromString(camera)];
return true;
}
var killMe:Array<String> = obj.split('.');
var object:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
object = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (object != null)
{
object.cameras = [LuaUtils.cameraFromString(camera)];
return true;
}
LuaUtils.luaTrace(lua, "setObjectCamera | Object " + obj + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setBlendMode", function(obj:String, blend:String = '')
{
var real = game.getLuaObject(obj);
if (real != null)
{
real.blend = LuaUtils.blendModeFromString(blend);
return true;
}
var killMe:Array<String> = obj.split('.');
var spr:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
spr = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (spr != null)
{
spr.blend = LuaUtils.blendModeFromString(blend);
return true;
}
LuaUtils.luaTrace(lua, "setBlendMode | Object " + obj + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("screenCenter", function(obj:String, pos:String = 'xy')
{
var spr:FlxSprite = game.getLuaObject(obj);
if (spr == null)
{
var killMe:Array<String> = obj.split('.');
spr = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
spr = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
}
if (spr != null)
{
switch (pos.trim().toLowerCase())
{
case 'x':
spr.screenCenter(X);
return;
case 'y':
spr.screenCenter(Y);
return;
default:
spr.screenCenter(XY);
return;
}
}
LuaUtils.luaTrace(lua, "screenCenter | Object " + obj + " doesn't exist!", false, false, FlxColor.RED);
});
registerFunction("objectsOverlap", function(obj1:String, obj2:String)
{
var namesArray:Array<String> = [obj1, obj2];
var objectsArray:Array<FlxSprite> = [];
for (i in 0...namesArray.length)
{
var real = PlayState.instance.getLuaObject(namesArray[i]);
if (real != null)
{
objectsArray.push(real);
}
else
{
objectsArray.push(Reflect.getProperty(getInstance(), namesArray[i]));
}
}
if (!objectsArray.contains(null) && FlxG.overlap(objectsArray[0], objectsArray[1]))
{
return true;
}
return false;
});
registerFunction("getPixelColor", function(obj:String, x:Int, y:Int)
{
var killMe:Array<String> = obj.split('.');
var spr:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
spr = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (spr != null)
{
if (spr.framePixels != null)
spr.framePixels.getPixel32(x, y);
return spr.pixels.getPixel32(x, y);
}
return 0;
});
registerFunction("getRandomInt", function(min:Int, max:Int = FlxMath.MAX_VALUE_INT, exclude:String = '')
{
var excludeArray:Array<String> = exclude.split(',');
var toExclude:Array<Int> = [];
for (i in 0...excludeArray.length)
{
toExclude.push(Std.parseInt(excludeArray[i].trim()));
}
return FlxG.random.int(min, max, toExclude);
});
registerFunction("getRandomFloat", function(min:Float, max:Float = 1, exclude:String = '')
{
var excludeArray:Array<String> = exclude.split(',');
var toExclude:Array<Float> = [];
for (i in 0...excludeArray.length)
{
toExclude.push(Std.parseFloat(excludeArray[i].trim()));
}
return FlxG.random.float(min, max, toExclude);
});
registerFunction("getRandomBool", function(chance:Float = 50)
{
return FlxG.random.bool(chance);
});
registerFunction("startDialogue", function(dialogueFile:String, music:String = null)
{
var path:String;
#if MODS_ALLOWED
path = Paths.modsJson(Paths.formatToSongPath(PlayState.SONG.song) + '/' + dialogueFile);
if (!FileSystem.exists(path))
#end
path = Paths.json(Paths.formatToSongPath(PlayState.SONG.song) + '/' + dialogueFile);
LuaUtils.luaTrace(lua, 'startDialogue | Trying to load dialogue: ' + path);
#if MODS_ALLOWED
if (FileSystem.exists(path))
#else
if (Assets.exists(path))
#end
{
var shit:DialogueFile = DialogueBoxPsych.parseDialogue(path);
if (shit.dialogue.length > 0)
{
PlayState.instance.startDialogue(shit, music);
LuaUtils.luaTrace(lua, 'startDialogue | Successfully loaded dialogue', false, false, FlxColor.GREEN);
return true;
}
else
{
LuaUtils.luaTrace(lua, 'startDialogue | Your dialogue file is badly formatted!', false, false, FlxColor.RED);
}
}
else
{
LuaUtils.luaTrace(lua, 'startDialogue | Dialogue file not found', false, false, FlxColor.RED);
if (PlayState.instance.endingSong)
{
PlayState.instance.endSong();
}
else
{
PlayState.instance.startCountdown();
}
}
return false;
});
registerFunction("startVideo", function(videoFile:String)
{
#if VIDEOS_ALLOWED
if (FileSystem.exists(Paths.video(videoFile)))
{
PlayState.instance.startVideo(videoFile);
return true;
}
else
{
LuaUtils.luaTrace(lua, 'startVideo | Video file not found: ' + videoFile, false, false, FlxColor.RED);
}
return false;
#else
if (PlayState.instance.endingSong)
{
PlayState.instance.endSong();
}
else
{
PlayState.instance.startCountdown();
}
return true;
#end
});
registerFunction("playMusic", function(sound:String, volume:Float = 1, loop:Bool = false)
{
FlxG.sound.playMusic(Paths.music(sound), volume, loop);
});
registerFunction("playSound", function(sound:String, volume:Float = 1, ?tag:String = null)
{
if (tag != null && tag.length > 0)
{
tag = tag.replace('.', '');
if (PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).stop();
}
PlayState.instance.modchartSounds.set(tag, FlxG.sound.play(Paths.sound(sound), volume, false, function()
{
PlayState.instance.modchartSounds.remove(tag);
PlayState.instance.callOnLuas('onSoundFinished', [tag]);
}));
return;
}
FlxG.sound.play(Paths.sound(sound), volume);
});
registerFunction("stopSound", function(tag:String)
{
if (tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).stop();
PlayState.instance.modchartSounds.remove(tag);
}
});
registerFunction("pauseSound", function(tag:String)
{
if (tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).pause();
}
});
registerFunction("resumeSound", function(tag:String)
{
if (tag != null && tag.length > 1 && PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).play();
}
});
registerFunction("soundFadeIn", function(tag:String, duration:Float, fromValue:Float = 0, toValue:Float = 1)
{
if (tag == null || tag.length < 1)
{
FlxG.sound.music.fadeIn(duration / PlayState.instance.playbackRate, fromValue, toValue);
}
else if (PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).fadeIn(duration / PlayState.instance.playbackRate, fromValue, toValue);
}
});
registerFunction("soundFadeOut", function(tag:String, duration:Float, toValue:Float = 0)
{
if (tag == null || tag.length < 1)
{
FlxG.sound.music.fadeOut(duration / PlayState.instance.playbackRate, toValue);
}
else if (PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).fadeOut(duration / PlayState.instance.playbackRate, toValue);
}
});
registerFunction("soundFadeCancel", function(tag:String)
{
if (tag == null || tag.length < 1)
{
if (FlxG.sound.music.fadeTween != null)
{
FlxG.sound.music.fadeTween.cancel();
}
}
else if (PlayState.instance.modchartSounds.exists(tag))
{
var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag);
if (theSound.fadeTween != null)
{
theSound.fadeTween.cancel();
PlayState.instance.modchartSounds.remove(tag);
}
}
});
registerFunction("getSoundVolume", function(tag:String)
{
if (tag == null || tag.length < 1)
{
if (FlxG.sound.music != null)
{
return FlxG.sound.music.volume;
}
}
else if (PlayState.instance.modchartSounds.exists(tag))
{
return PlayState.instance.modchartSounds.get(tag).volume;
}
return 0;
});
registerFunction("setSoundVolume", function(tag:String, value:Float)
{
if (tag == null || tag.length < 1)
{
if (FlxG.sound.music != null)
{
FlxG.sound.music.volume = value;
}
}
else if (PlayState.instance.modchartSounds.exists(tag))
{
PlayState.instance.modchartSounds.get(tag).volume = value;
}
});
registerFunction("getSoundTime", function(tag:String)
{
if (tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag))
{
return PlayState.instance.modchartSounds.get(tag).time;
}
return 0;
});
registerFunction("setSoundTime", function(tag:String, value:Float)
{
if (tag != null && tag.length > 0 && PlayState.instance.modchartSounds.exists(tag))
{
var theSound:FlxSound = PlayState.instance.modchartSounds.get(tag);
if (theSound != null)
{
var wasResumed:Bool = theSound.playing;
theSound.pause();
theSound.time = value;
if (wasResumed)
theSound.play();
}
}
});
registerFunction("debugPrint", function(text1:Dynamic = '', text2:Dynamic = '', text3:Dynamic = '', text4:Dynamic = '', text5:Dynamic = '')
{
if (text1 == null)
text1 = '';
if (text2 == null)
text2 = '';
if (text3 == null)
text3 = '';
if (text4 == null)
text4 = '';
if (text5 == null)
text5 = '';
LuaUtils.luaTrace(lua, '' + text1 + text2 + text3 + text4 + text5, true, false);
});
addLocalCallback("close", function()
{
closed = true;
return closed;
});
for (name => func in registeredFunctions)
{
if (func != null)
Lua_helper.add_callback(lua, name, func);
}
#if ACHIEVEMENTS_ALLOWED Achievements.addLuaCallbacks(lua); #end
#if HSCRIPT_ALLOWED HScript.implement(this); #end
CustomSubstate.implement(this);
#if flxanimate FlxAnimateFunctions.implement(this); #end
registerFunction("changePresence", function(details:String, state:Null<String>, ?smallImageKey:String, ?hasStartTimestamp:Bool, ?endTimestamp:Float)
{
#if DISCORD_ALLOWED
DiscordClient.changePresence(details, state, smallImageKey, hasStartTimestamp, endTimestamp);
#end
});
// LUA TEXTS
registerFunction("makeLuaText", function(tag:String, text:String, width:Int, x:Float, y:Float)
{
tag = tag.replace('.', '');
resetTextTag(tag);
var leText:FlxText = new FlxText(x, y, width, text, 16);
leText.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
leText.cameras = [PlayState.instance.camHUD];
PlayState.instance.modchartTexts.set(tag, leText);
});
registerFunction("setTextString", function(tag:String, text:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
obj.text = text;
return true;
}
LuaUtils.luaTrace(lua, "setTextString | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextSize", function(tag:String, size:Int)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
obj.size = size;
return true;
}
LuaUtils.luaTrace(lua, "setTextSize | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextWidth", function(tag:String, width:Float)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
obj.fieldWidth = width;
return true;
}
LuaUtils.luaTrace(lua, "setTextWidth | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextBorder", function(tag:String, size:Int, color:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
var colorNum:Int = Std.parseInt(color);
if (!color.startsWith('0x'))
colorNum = Std.parseInt('0xff' + color);
obj.borderSize = size;
obj.borderColor = colorNum;
return true;
}
LuaUtils.luaTrace(lua, "setTextBorder | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextColor", function(tag:String, color:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
var colorNum:Int = Std.parseInt(color);
if (!color.startsWith('0x'))
colorNum = Std.parseInt('0xff' + color);
obj.color = colorNum;
return true;
}
LuaUtils.luaTrace(lua, "setTextColor | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextFont", function(tag:String, newFont:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
obj.font = Paths.font(newFont);
return true;
}
LuaUtils.luaTrace(lua, "setTextFont | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextItalic", function(tag:String, italic:Bool)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
obj.italic = italic;
return true;
}
LuaUtils.luaTrace(lua, "setTextItalic | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("setTextAlignment", function(tag:String, alignment:String = 'left')
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
obj.alignment = LEFT;
switch (alignment.trim().toLowerCase())
{
case 'right':
obj.alignment = RIGHT;
case 'center':
obj.alignment = CENTER;
}
return true;
}
LuaUtils.luaTrace(lua, "setTextAlignment | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return false;
});
registerFunction("getTextString", function(tag:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null && obj.text != null)
{
return obj.text;
}
LuaUtils.luaTrace(lua, "getTextString | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return null;
});
registerFunction("getTextSize", function(tag:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
return obj.size;
}
LuaUtils.luaTrace(lua, "getTextSize | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return -1;
});
registerFunction("getTextFont", function(tag:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
return obj.font;
}
LuaUtils.luaTrace(lua, "getTextFont | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return null;
});
registerFunction("getTextWidth", function(tag:String)
{
var obj:FlxText = getTextObject(tag);
if (obj != null)
{
return obj.fieldWidth;
}
LuaUtils.luaTrace(lua, "getTextWidth | Object " + tag + " doesn't exist!", false, false, FlxColor.RED);
return 0;
});
registerFunction("addLuaText", function(tag:String)
{
if (PlayState.instance.modchartTexts.exists(tag))
{
var shit:FlxText = PlayState.instance.modchartTexts.get(tag);
if (shit != null)
getInstance().add(shit);
}
});
registerFunction("removeLuaText", function(tag:String, destroy:Bool = true)
{
if (!PlayState.instance.modchartTexts.exists(tag))
{
return;
}
var pee:FlxText = PlayState.instance.modchartTexts.get(tag);
if (pee != null)
getInstance().remove(pee, true);
if (destroy)
{
pee.destroy();
PlayState.instance.modchartTexts.remove(tag);
}
});
registerFunction("initSaveData", function(name:String, ?folder:String = 'psychenginemods')
{
if (!PlayState.instance.modchartSaves.exists(name))
{
var save:FlxSave = new FlxSave();
// folder goes unused for flixel 5 users. @BeastlyGhost
save.bind(name, CoolUtil.getSavePath() + "/" + folder);
PlayState.instance.modchartSaves.set(name, save);
return;
}
LuaUtils.luaTrace(lua, 'initSaveData | Save file already initialized: ' + name);
});
registerFunction("flushSaveData", function(name:String)
{
if (PlayState.instance.modchartSaves.exists(name))
{
PlayState.instance.modchartSaves.get(name).flush();
return;
}
LuaUtils.luaTrace(lua, 'flushSaveData | Save file not initialized: ' + name, false, false, FlxColor.RED);
});
registerFunction("getDataFromSave", function(name:String, field:String, ?defaultValue:Dynamic = null)
{
if (PlayState.instance.modchartSaves.exists(name))
{
var retVal:Dynamic = Reflect.field(PlayState.instance.modchartSaves.get(name).data, field);
return retVal;
}
LuaUtils.luaTrace(lua, 'getDataFromSave | Save file not initialized: ' + name, false, false, FlxColor.RED);
return defaultValue;
});
registerFunction("setDataFromSave", function(name:String, field:String, value:Dynamic)
{
if (PlayState.instance.modchartSaves.exists(name))
{
Reflect.setField(PlayState.instance.modchartSaves.get(name).data, field, value);
return;
}
LuaUtils.luaTrace(lua, 'setDataFromSave | Save file not initialized: ' + name, false, false, FlxColor.RED);
});
registerFunction("checkFileExists", function(filename:String, ?absolute:Bool = false)
{
#if MODS_ALLOWED
if (absolute)
{
return FileSystem.exists(filename);
}
var path:String = Paths.modFolders(filename);
if (FileSystem.exists(path))
{
return true;
}
return FileSystem.exists(Paths.getPath('assets/$filename', TEXT));
#else
if (absolute)
{
return Assets.exists(filename);
}
return Assets.exists(Paths.getPath('assets/$filename', TEXT));
#end
});
registerFunction("saveFile", function(path:String, content:String, ?absolute:Bool = false)
{
try
{
if (!absolute)
File.saveContent(Paths.mods(path), content);
else
File.saveContent(path, content);
return true;
}
catch (e:Dynamic)
{
LuaUtils.luaTrace(lua, "saveFile | Error trying to save " + path + ": " + e, false, false, FlxColor.RED);
}
return false;
});
registerFunction("deleteFile", function(path:String, ?ignoreModFolders:Bool = false)
{
try
{
#if MODS_ALLOWED
if (!ignoreModFolders)
{
var lePath:String = Paths.modFolders(path);
if (FileSystem.exists(lePath))
{
FileSystem.deleteFile(lePath);
return true;
}
}
#end
var lePath:String = Paths.getPath(path, TEXT);
if (Assets.exists(lePath))
{
FileSystem.deleteFile(lePath);
return true;
}
}
catch (e:Dynamic)
{
LuaUtils.luaTrace(lua, "deleteFile | Error trying to delete " + path + ": " + e, false, false, FlxColor.RED);
}
return false;
});
registerFunction("getTextFromFile", function(path:String, ?ignoreModFolders:Bool = false)
{
return Paths.getTextFromFile(path, ignoreModFolders);
});
// DEPRECATED, DONT MESS WITH THESE SHITS, ITS JUST THERE FOR BACKWARD COMPATIBILITY
registerFunction("objectPlayAnimation", function(obj:String, name:String, forced:Bool = false, ?startFrame:Int = 0)
{
LuaUtils.luaTrace(lua, "objectPlayAnimation is deprecated! Use playAnim instead", false, true);
if (PlayState.instance.getLuaObject(obj, false) != null)
{
PlayState.instance.getLuaObject(obj, false).animation.play(name, forced, false, startFrame);
return true;
}
var spr:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (spr != null)
{
spr.animation.play(name, forced, false, startFrame);
return true;
}
return false;
});
registerFunction("characterPlayAnim", function(character:String, anim:String, ?forced:Bool = false)
{
LuaUtils.luaTrace(lua, "characterPlayAnim is deprecated! Use playAnim instead", false, true);
switch (character.toLowerCase())
{
case 'dad':
if (PlayState.instance.dad.animOffsets.exists(anim))
PlayState.instance.dad.playAnim(anim, forced);
case 'gf' | 'girlfriend':
if (PlayState.instance.gf != null && PlayState.instance.gf.animOffsets.exists(anim))
PlayState.instance.gf.playAnim(anim, forced);
default:
if (PlayState.instance.boyfriend.animOffsets.exists(anim))
PlayState.instance.boyfriend.playAnim(anim, forced);
}
});
registerFunction("luaSpriteMakeGraphic", function(tag:String, width:Int, height:Int, color:String)
{
LuaUtils.luaTrace(lua, "luaSpriteMakeGraphic is deprecated! Use makeGraphic instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
var colorNum:Int = Std.parseInt(color);
if (!color.startsWith('0x'))
colorNum = Std.parseInt('0xff' + color);
PlayState.instance.modchartSprites.get(tag).makeGraphic(width, height, colorNum);
}
});
registerFunction("luaSpriteAddAnimationByPrefix", function(tag:String, name:String, prefix:String, framerate:Int = 24, loop:Bool = true)
{
LuaUtils.luaTrace(lua, "luaSpriteAddAnimationByPrefix is deprecated! Use addAnimationByPrefix instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
var cock:ModchartSprite = PlayState.instance.modchartSprites.get(tag);
cock.animation.addByPrefix(name, prefix, framerate, loop);
if (cock.animation.curAnim == null)
{
cock.animation.play(name, true);
}
}
});
registerFunction("luaSpriteAddAnimationByIndices", function(tag:String, name:String, prefix:String, indices:String, framerate:Int = 24)
{
LuaUtils.luaTrace(lua, "luaSpriteAddAnimationByIndices is deprecated! Use addAnimationByIndices instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
var strIndices:Array<String> = indices.trim().split(',');
var die:Array<Int> = [];
for (i in 0...strIndices.length)
{
die.push(Std.parseInt(strIndices[i]));
}
var pussy:ModchartSprite = PlayState.instance.modchartSprites.get(tag);
pussy.animation.addByIndices(name, prefix, die, '', framerate, false);
if (pussy.animation.curAnim == null)
{
pussy.animation.play(name, true);
}
}
});
registerFunction("luaSpritePlayAnimation", function(tag:String, name:String, forced:Bool = false)
{
LuaUtils.luaTrace(lua, "luaSpritePlayAnimation is deprecated! Use playAnim instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
PlayState.instance.modchartSprites.get(tag).animation.play(name, forced);
}
});
registerFunction("setLuaSpriteCamera", function(tag:String, camera:String = '')
{
LuaUtils.luaTrace(lua, "setLuaSpriteCamera is deprecated! Use setObjectCamera instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
PlayState.instance.modchartSprites.get(tag).cameras = [LuaUtils.cameraFromString(camera)];
return true;
}
LuaUtils.luaTrace(lua, "Lua sprite with tag | " + tag + " doesn't exist!");
return false;
});
registerFunction("setLuaSpriteScrollFactor", function(tag:String, scrollX:Float, scrollY:Float)
{
LuaUtils.luaTrace(lua, "setLuaSpriteScrollFactor is deprecated! Use setScrollFactor instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
PlayState.instance.modchartSprites.get(tag).scrollFactor.set(scrollX, scrollY);
return true;
}
return false;
});
registerFunction("scaleLuaSprite", function(tag:String, x:Float, y:Float)
{
LuaUtils.luaTrace(lua, "scaleLuaSprite is deprecated! Use scaleObject instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
var shit:ModchartSprite = PlayState.instance.modchartSprites.get(tag);
shit.scale.set(x, y);
shit.updateHitbox();
return true;
}
return false;
});
registerFunction("getPropertyLuaSprite", function(tag:String, variable:String)
{
LuaUtils.luaTrace(lua, "getPropertyLuaSprite is deprecated! Use getProperty instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
var coverMeInPiss:Dynamic = Reflect.getProperty(PlayState.instance.modchartSprites.get(tag), killMe[0]);
for (i in 1...killMe.length - 1)
{
coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]);
}
return Reflect.getProperty(coverMeInPiss, killMe[killMe.length - 1]);
}
return Reflect.getProperty(PlayState.instance.modchartSprites.get(tag), variable);
}
return null;
});
registerFunction("setPropertyLuaSprite", function(tag:String, variable:String, value:Dynamic)
{
LuaUtils.luaTrace(lua, "setPropertyLuaSprite is deprecated! Use setProperty instead", false, true);
if (PlayState.instance.modchartSprites.exists(tag))
{
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
var coverMeInPiss:Dynamic = Reflect.getProperty(PlayState.instance.modchartSprites.get(tag), killMe[0]);
for (i in 1...killMe.length - 1)
{
coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]);
}
Reflect.setProperty(coverMeInPiss, killMe[killMe.length - 1], value);
return true;
}
Reflect.setProperty(PlayState.instance.modchartSprites.get(tag), variable, value);
return true;
}
LuaUtils.luaTrace(lua, "setPropertyLuaSprite | Lua sprite with tag: " + tag + " doesn't exist!");
return false;
});
registerFunction("musicFadeIn", function(duration:Float, fromValue:Float = 0, toValue:Float = 1)
{
FlxG.sound.music.fadeIn(duration / PlayState.instance.playbackRate, fromValue, toValue);
LuaUtils.luaTrace(lua, 'musicFadeIn is deprecated! Use soundFadeIn instead.', false, true);
});
registerFunction("musicFadeOut", function(duration:Float, toValue:Float = 0)
{
FlxG.sound.music.fadeOut(duration / PlayState.instance.playbackRate, toValue);
LuaUtils.luaTrace(lua, 'musicFadeOut is deprecated! Use soundFadeOut instead.', false, true);
});
// SHADER SHIT
if (ClientPrefs.shaders)
{
registerFunction("addChromaticAbberationEffect", function(camera:String, chromeOffset:Float = 0.005)
{
PlayState.instance.addShaderToCamera(camera, new ChromaticAberrationEffect(chromeOffset));
});
registerFunction("addScanlineEffect", function(camera:String, lockAlpha:Bool = false)
{
PlayState.instance.addShaderToCamera(camera, new ScanlineEffect(lockAlpha));
});
registerFunction("addGrainEffect", function(camera:String, grainSize:Float, lumAmount:Float, lockAlpha:Bool = false)
{
PlayState.instance.addShaderToCamera(camera, new GrainEffect(grainSize, lumAmount, lockAlpha));
});
registerFunction("addTiltshiftEffect", function(camera:String, blurAmount:Float, center:Float)
{
PlayState.instance.addShaderToCamera(camera, new TiltshiftEffect(blurAmount, center));
});
registerFunction("addVCREffect",
function(camera:String, glitchFactor:Float = 0.0, distortion:Bool = true, perspectiveOn:Bool = true, vignetteMoving:Bool = true)
{
PlayState.instance.addShaderToCamera(camera, new VCRDistortionEffect(glitchFactor, distortion, perspectiveOn, vignetteMoving));
});
// shader clear
registerFunction("clearShadersFromCamera", function(cameraName)
{
LuaUtils.cameraFromString(cameraName).filters = [];
});
registerFunction("addWiggleEffect",
function(camera:String, effectType:String, waveSpeed:Float = 0.1, waveFrq:Float = 0.1, waveAmp:Float = 0.1, ?verticalStrength:Float = 1,
?horizontalStrength:Float = 1)
{
PlayState.instance.addShaderToCamera(camera,
new WiggleEffectLua(effectType, waveSpeed, waveFrq, waveAmp, verticalStrength, horizontalStrength));
});
registerFunction("addGlitchEffect", function(camera:String, waveSpeed:Float = 0.1, waveFrq:Float = 0.1, waveAmp:Float = 0.1)
{
PlayState.instance.addShaderToCamera(camera, new GlitchEffect(waveSpeed, waveFrq, waveAmp));
});
registerFunction("addGlitchShader", function(camera:String, waveAmp:Float = 0.1, waveFrq:Float = 0.1, waveSpeed:Float = 0.1)
{
PlayState.instance.addShaderToCamera(camera, new GlitchEffect(waveSpeed, waveFrq, waveAmp));
});
registerFunction("addPulseEffect", function(camera:String, waveSpeed:Float = 0.1, waveFrq:Float = 0.1, waveAmp:Float = 0.1)
{
PlayState.instance.addShaderToCamera(camera, new PulseEffect(waveSpeed, waveFrq, waveAmp));
});
registerFunction("addDistortionEffect", function(camera:String, waveSpeed:Float = 0.1, waveFrq:Float = 0.1, waveAmp:Float = 0.1)
{
PlayState.instance.addShaderToCamera(camera, new DistortBGEffect(waveSpeed, waveFrq, waveAmp));
});
registerFunction("addInvertEffect", function(camera:String, lockAlpha:Bool = false)
{
PlayState.instance.addShaderToCamera(camera, new InvertColorsEffect(lockAlpha));
});
registerFunction("addGreyscaleEffect", function(camera:String)
{ // for dem funkies
PlayState.instance.addShaderToCamera(camera, new GreyscaleEffect());
});
registerFunction("addGrayscaleEffect", function(camera:String)
{ // for dem funkies
PlayState.instance.addShaderToCamera(camera, new GreyscaleEffect());
});
registerFunction("add3DEffect", function(camera:String, xrotation:Float = 0, yrotation:Float = 0, zrotation:Float = 0, depth:Float = 0)
{ // for dem funkies
PlayState.instance.addShaderToCamera(camera, new ThreeDEffect(xrotation, yrotation, zrotation, depth));
});
registerFunction("addBloomEffect", function(camera:String, intensity:Float = 0.35, blurSize:Float = 1.0)
{
PlayState.instance.addShaderToCamera(camera, new BloomEffect(blurSize / 512.0, intensity));
});
registerFunction("addBlockedGlitchEffect",
function(camera:String, res:Float = 1280, time:Float = 1, colorMult:Float = 1, colorTransform:Bool = true)
{
if (colorTransform)
PlayState.instance.addShaderToCamera(camera, new BlockedGlitchEffect(res, time, colorMult, colorTransform));
});
registerFunction("clearEffects", function(camera:String)
{
PlayState.instance.clearShaderFromCamera(camera);
});
}
// Other stuff
registerFunction("stringStartsWith", function(str:String, start:String)
{
return str.startsWith(start);
});
registerFunction("stringEndsWith", function(str:String, end:String)
{
return str.endsWith(end);
});
registerFunction("stringSplit", function(str:String, split:String)
{
return str.split(split);
});
registerFunction("stringTrim", function(str:String)
{
return str.trim();
});
registerFunction("directoryFileList", function(folder:String)
{
var list:Array<String> = [];
#if sys
if (FileSystem.exists(folder))
{
for (folder in FileSystem.readDirectory(folder))
{
if (!list.contains(folder))
{
list.push(folder);
}
}
}
#end
return list;
});
registerFunction("changeCursor",
function(path:String, visible:Bool = true, ?loadDefault:Bool = false, scale:Float = 1, xOffset:Int = 0, yOffset:Int = 0)
{
if (Paths.image(path) != null)
{
FlxG.mouse.visible = visible;
FlxG.mouse.unload();
FlxG.mouse.load(Paths.image(path).bitmap, scale, xOffset, yOffset);
LuaUtils.luaTrace(lua, 'Changed Cursor in $path');
}
else if (loadDefault || path == null || path.length <= 0)
{
FlxG.mouse.unload();
FlxG.mouse.visible = visible;
LuaUtils.luaTrace(lua, 'Loading default cursor');
}
else
{
LuaUtils.luaTrace(lua, 'Cursor in $path does not exist!', true, false, FlxColor.RED);
FlxG.mouse.unload();
FlxG.mouse.visible = visible;
// return;
}
});
call('onCreate', []);
#end
}
public function addLocalCallback(name:String, myFunction:Dynamic)
{
callbacks.set(name, myFunction);
Lua_helper.add_callback(lua, name, null); // just so that it gets called
}
public static function registerFunction(name:String, func:Dynamic):Void
registeredFunctions.set(name, func);
public static function isOfTypes(value:Any, types:Array<Dynamic>)
{
for (type in types)
{
if (Std.isOfType(value, type))
return true;
}
return false;
}
public static function setVarInArray(instance:Dynamic, variable:String, value:Dynamic):Any
{
var shit:Array<String> = variable.split('[');
if (shit.length > 1)
{
var blah:Dynamic = null;
if (PlayState.instance.variables.exists(shit[0]))
{
var retVal:Dynamic = PlayState.instance.variables.get(shit[0]);
if (retVal != null)
blah = retVal;
}
else
blah = Reflect.getProperty(instance, shit[0]);
for (i in 1...shit.length)
{
var leNum:Dynamic = shit[i].substr(0, shit[i].length - 1);
if (i >= shit.length - 1) // Last array
blah[leNum] = value;
else // Anything else
blah = blah[leNum];
}
return blah;
}
/*if(Std.isOfType(instance, Map))
instance.set(variable,value);
else */
if (PlayState.instance.variables.exists(variable))
{
PlayState.instance.variables.set(variable, value);
return true;
}
Reflect.setProperty(instance, variable, value);
return true;
}
public static function getVarInArray(instance:Dynamic, variable:String):Any
{
var shit:Array<String> = variable.split('[');
if (shit.length > 1)
{
var blah:Dynamic = null;
if (PlayState.instance.variables.exists(shit[0]))
{
var retVal:Dynamic = PlayState.instance.variables.get(shit[0]);
if (retVal != null)
blah = retVal;
}
else
blah = Reflect.getProperty(instance, shit[0]);
for (i in 1...shit.length)
{
var leNum:Dynamic = shit[i].substr(0, shit[i].length - 1);
blah = blah[leNum];
}
return blah;
}
if (PlayState.instance.variables.exists(variable))
{
var retVal:Dynamic = PlayState.instance.variables.get(variable);
if (retVal != null)
return retVal;
}
return Reflect.getProperty(instance, variable);
}
inline static function getTextObject(name:String):FlxText
{
return PlayState.instance.modchartTexts.exists(name) ? PlayState.instance.modchartTexts.get(name) : Reflect.getProperty(PlayState.instance, name);
}
#if (SHADERS_ALLOWED)
public function getShader(obj:String):FlxRuntimeShader
{
var killMe:Array<String> = obj.split('.');
var leObj:FlxSprite = getObjectDirectly(killMe[0]);
if (killMe.length > 1)
{
leObj = getVarInArray(getPropertyLoopThingWhatever(killMe), killMe[killMe.length - 1]);
}
if (leObj != null)
{
var shader:Dynamic = leObj.shader;
var shader:FlxRuntimeShader = shader;
return shader;
}
return null;
}
#end
function initLuaShader(name:String, ?glslVersion:Int = 120)
{
if (!ClientPrefs.shaders)
return false;
#if (SHADERS_ALLOWED)
if (PlayState.instance.runtimeShaders.exists(name))
{
LuaUtils.luaTrace(lua, 'Shader $name was already initialized!');
return true;
}
var foldersToCheck:Array<String> = [Paths.mods('shaders/')];
if (Paths.currentModDirectory != null && Paths.currentModDirectory.length > 0)
foldersToCheck.insert(0, Paths.mods(Paths.currentModDirectory + '/shaders/'));
for (mod in Paths.getGlobalMods())
foldersToCheck.insert(0, Paths.mods(mod + '/shaders/'));
for (folder in foldersToCheck)
{
if (FileSystem.exists(folder))
{
var frag:String = folder + name + '.frag';
var vert:String = folder + name + '.vert';
var found:Bool = false;
if (FileSystem.exists(frag))
{
frag = File.getContent(frag);
found = true;
}
else
frag = null;
if (FileSystem.exists(vert))
{
vert = File.getContent(vert);
found = true;
}
else
vert = null;
if (found)
{
PlayState.instance.runtimeShaders.set(name, [frag, vert]);
// trace('Found shader $name!');
return true;
}
}
}
LuaUtils.luaTrace(lua, 'Missing shader $name .frag AND .vert files!', false, false, FlxColor.RED);
#else
LuaUtils.luaTrace(lua, 'This platform doesn\'t support Runtime Shaders!', false, false, FlxColor.RED);
#end
return false;
}
function getGroupStuff(leArray:Dynamic, variable:String)
{
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
var coverMeInPiss:Dynamic = Reflect.getProperty(leArray, killMe[0]);
for (i in 1...killMe.length - 1)
{
coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]);
}
switch (Type.typeof(coverMeInPiss))
{
case ValueType.TClass(haxe.ds.StringMap) | ValueType.TClass(haxe.ds.ObjectMap) | ValueType.TClass(haxe.ds.IntMap) | ValueType.TClass(haxe.ds.EnumValueMap):
return coverMeInPiss.get(killMe[killMe.length - 1]);
default:
return Reflect.getProperty(coverMeInPiss, killMe[killMe.length - 1]);
};
}
switch (Type.typeof(leArray))
{
case ValueType.TClass(haxe.ds.StringMap) | ValueType.TClass(haxe.ds.ObjectMap) | ValueType.TClass(haxe.ds.IntMap) | ValueType.TClass(haxe.ds.EnumValueMap):
return leArray.get(variable);
default:
return Reflect.getProperty(leArray, variable);
};
}
function loadFrames(spr:FlxSprite, image:String, spriteType:String)
{
switch (spriteType.toLowerCase().trim())
{
// it never seemed like anyone used this, so it's gone. We've got flxanimate anyway
/*
case "texture", "textureatlas", "tex":
case "texture_noaa", "textureatlas_noaa", "tex_noaa":
// Deprecated loader — only kept for legacy support
// You should use FlxAnimate instead!
spr.frames = AtlasFrameMaker.construct(
image,
null,
spriteType.indexOf("_noaa") == -1
);
trace("Using legacy TextureAtlas loader. Consider migrating to FlxAnimate.");
*/
case 'aseprite' | 'jsoni8':
spr.frames = Paths.getAsepriteAtlas(image);
case "packer" | "packeratlas" | "pac":
spr.frames = Paths.getPackerAtlas(image);
default:
spr.frames = Paths.getSparrowAtlas(image);
}
}
function setGroupStuff(leArray:Dynamic, variable:String, value:Dynamic)
{
var killMe:Array<String> = variable.split('.');
if (killMe.length > 1)
{
var coverMeInPiss:Dynamic = Reflect.getProperty(leArray, killMe[0]);
for (i in 1...killMe.length - 1)
{
coverMeInPiss = Reflect.getProperty(coverMeInPiss, killMe[i]);
}
Reflect.setProperty(coverMeInPiss, killMe[killMe.length - 1], value);
return;
}
Reflect.setProperty(leArray, variable, value);
}
function resetTextTag(tag:String)
{
if (!PlayState.instance.modchartTexts.exists(tag))
{
return;
}
var pee:FlxText = PlayState.instance.modchartTexts.get(tag);
if (pee != null)
PlayState.instance.remove(pee, true);
pee.destroy();
PlayState.instance.modchartTexts.remove(tag);
}
function resetSpriteTag(tag:String)
{
if (!PlayState.instance.modchartSprites.exists(tag))
{
return;
}
var pee:ModchartSprite = PlayState.instance.modchartSprites.get(tag);
pee.kill();
if (pee.wasAdded)
{
PlayState.instance.remove(pee, true);
}
pee.destroy();
PlayState.instance.modchartSprites.remove(tag);
}
function cancelTween(tag:String)
{
if (PlayState.instance.modchartTweens.exists(tag))
{
PlayState.instance.modchartTweens.get(tag).cancel();
PlayState.instance.modchartTweens.get(tag).destroy();
PlayState.instance.modchartTweens.remove(tag);
}
}
function tweenShit(tag:String, vars:String)
{
cancelTween(tag);
var variables:Array<String> = vars.split('.');
var sexyProp:Dynamic = getObjectDirectly(variables[0]);
if (variables.length > 1)
{
sexyProp = getVarInArray(getPropertyLoopThingWhatever(variables), variables[variables.length - 1]);
}
return sexyProp;
}
function cancelTimer(tag:String)
{
if (PlayState.instance.modchartTimers.exists(tag))
{
var theTimer:FlxTimer = PlayState.instance.modchartTimers.get(tag);
theTimer.cancel();
theTimer.destroy();
PlayState.instance.modchartTimers.remove(tag);
}
}
public var lastCalledFunction:String = '';
public static var lastCalledScript:FunkinLua = null;
public function call(func:String, args:Array<Dynamic>):Dynamic
{
#if LUA_ALLOWED
if (closed)
return Function_Continue;
lastCalledFunction = func;
lastCalledScript = this;
try
{
if (lua == null)
return Function_Continue;
Lua.getglobal(lua, func);
var type:Int = Lua.type(lua, -1);
if (type != Lua.LUA_TFUNCTION)
{
if (type > Lua.LUA_TNIL)
LuaUtils.luaTrace(lua, "ERROR (" + func + "): attempt to call a " + typeToString(type) + " value", false, false, FlxColor.RED);
Lua.pop(lua, 1);
return Function_Continue;
}
for (arg in args)
Convert.toLua(lua, arg);
var status:Int = Lua.pcall(lua, args.length, 1, 0);
// Checks if it's not successful, then show a error.
if (status != Lua.LUA_OK)
{
var error:String = LuaUtils.getErrorMessage(lua, status);
LuaUtils.luaTrace(lua, "ERROR (" + func + "): " + error, false, false, FlxColor.RED);
return Function_Continue;
}
// If successful, pass and then return the result.
var result:Dynamic = cast Convert.fromLua(lua, -1);
if (result == null)
result = Function_Continue;
Lua.pop(lua, 1);
return result;
}
catch (e:Dynamic)
{
trace(e);
}
#end
return Function_Continue;
}
static function addAnimByIndices(obj:String, name:String, prefix:String, indices:String, framerate:Int = 24, loop:Bool = false)
{
var strIndices:Array<String> = indices.trim().split(',');
var die:Array<Int> = [];
for (i in 0...strIndices.length)
{
die.push(Std.parseInt(strIndices[i]));
}
if (PlayState.instance.getLuaObject(obj, false) != null)
{
var pussy:FlxSprite = PlayState.instance.getLuaObject(obj, false);
pussy.animation.addByIndices(name, prefix, die, '', framerate, loop);
if (pussy.animation.curAnim == null)
{
pussy.animation.play(name, true);
}
return true;
}
var pussy:FlxSprite = Reflect.getProperty(getInstance(), obj);
if (pussy != null)
{
pussy.animation.addByIndices(name, prefix, die, '', framerate, loop);
if (pussy.animation.curAnim == null)
{
pussy.animation.play(name, true);
}
return true;
}
return false;
}
public static function getPropertyLoopThingWhatever(killMe:Array<String>, ?checkForTextsToo:Bool = true, ?getProperty:Bool = true):Dynamic
{
var coverMeInPiss:Dynamic = getObjectDirectly(killMe[0], checkForTextsToo);
var end = killMe.length;
if (getProperty)
end = killMe.length - 1;
for (i in 1...end)
{
coverMeInPiss = getVarInArray(coverMeInPiss, killMe[i]);
}
return coverMeInPiss;
}
public static function getObjectDirectly(objectName:String, ?checkForTextsToo:Bool = true):Dynamic
{
var coverMeInPiss:Dynamic = PlayState.instance.getLuaObject(objectName, checkForTextsToo);
if (coverMeInPiss == null)
coverMeInPiss = getVarInArray(getInstance(), objectName);
return coverMeInPiss;
}
function typeToString(type:Int):String
{
#if LUA_ALLOWED
switch (type)
{
case Lua.LUA_TBOOLEAN:
return "boolean";
case Lua.LUA_TNUMBER:
return "number";
case Lua.LUA_TSTRING:
return "string";
case Lua.LUA_TTABLE:
return "table";
case Lua.LUA_TFUNCTION:
return "function";
}
if (type <= Lua.LUA_TNIL)
return "nil";
#end
return "unknown";
}
public function set(variable:String, data:Dynamic)
{
#if LUA_ALLOWED
if (lua == null)
return;
if (Reflect.isFunction(data))
{
// Bind as a callable Lua function
Lua_helper.add_callback(lua, variable, data);
return;
}
// Otherwise, treat it like a variable
Convert.toLua(lua, data);
Lua.setglobal(lua, variable);
#end
}
public function stop()
{
#if LUA_ALLOWED
if (lua == null)
{
return;
}
Lua.close(lua);
lua = null;
#if HSCRIPT_ALLOWED // TODO: make this not rely on Lua
if (hscript != null)
hscript.interp = null;
hscript = null;
#end
#end
}
public static inline function getInstance()
{
return PlayState.instance.isDead ? GameOverSubstate.instance : PlayState.instance;
}
}
// hi guys, my name is "secret"!