diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bb826f7cc..5fa0b8acb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,6 +58,8 @@ jobs: run: echo "${{github.run_id}}" > VERSION - name: Compile run: haxelib run lime build Project.xml linux -Dbuildcrash --app-version="4.0.0-${{ github.run_id}}" + - name: Add Warning (linux-specific) + run: echo "libluajit-5.1-2 is required to run Lore Engine on Linux. Make sure you have it installed." > export/release/linux/bin/warning-LINUX.txt - name: Publish Artifact uses: actions/upload-artifact@v2.2.4 with: diff --git a/art/flashFiles/RECOVER_NOTE_assets_WHITE.fla b/art/flashFiles/RECOVER_NOTE_assets_WHITE.fla index 42bf61065..d0240bb11 100644 Binary files a/art/flashFiles/RECOVER_NOTE_assets_WHITE.fla and b/art/flashFiles/RECOVER_NOTE_assets_WHITE.fla differ diff --git a/source/ClientPrefs.hx b/source/ClientPrefs.hx index f05ab6001..2b5c04698 100644 --- a/source/ClientPrefs.hx +++ b/source/ClientPrefs.hx @@ -35,7 +35,11 @@ class ClientPrefs { public static var framerate:Int = 60; public static var underlayAlpha:Int = 0; public static var hitSounds:String = "OFF"; - public static var optimization:Bool = false; + public static var optimization(get, null):Bool = false; + // realizing now this fucked up more than it fixed and i don't wanna go through all of the code and change it + public static function get_optimization():Bool { + return false; + } public static var ignoreSkin:Bool = false; public static var fpsPosition:String = "BOTTOM LEFT"; public static var ratingPosition:String = "HUD"; @@ -63,6 +67,7 @@ class ClientPrefs { public static var newTimeBar:Bool = true; public static var showMS:Bool = true; public static var checkForUpdates:Bool = true; + public static var compactFPS:Bool = false; public static var showFPSNum:Bool = true; public static var skipTransitions:Bool = false; @@ -157,7 +162,6 @@ class ClientPrefs { FlxG.save.data.framerate = framerate; FlxG.save.data.hitSounds = hitSounds; FlxG.save.data.hitsoundVolume = hitsoundVolume; - FlxG.save.data.optimization = optimization; FlxG.save.data.showScoreBar = showScoreBar; FlxG.save.data.pauseOnFocusLost = pauseOnFocusLost; FlxG.save.data.ignoreSkin = ignoreSkin; @@ -269,9 +273,6 @@ class ClientPrefs { if(FlxG.save.data.hitSounds != null) { hitSounds = FlxG.save.data.hitSounds; } - if(FlxG.save.data.optimization != null) { - optimization = FlxG.save.data.optimization; - } if(FlxG.save.data.tinyIcons != null) { tinyIcons = FlxG.save.data.tinyIcons; } diff --git a/source/FunkinLua.hx b/source/FunkinLua.hx index 7d402d8b7..278a4215a 100644 --- a/source/FunkinLua.hx +++ b/source/FunkinLua.hx @@ -10,6 +10,7 @@ import llua.Convert; import animateatlas.AtlasFrameMaker; import flixel.FlxG; +import lore.macros.MacroTools; import lime.app.Application; import flixel.tweens.FlxTween; import flixel.tweens.FlxEase; @@ -3581,11 +3582,11 @@ class HScript interp.variables.set("switchState", MusicBeatState.switchState); interp.variables.set("ModdedState", lore.ModdedState); interp.variables.set("ModdedSubState", lore.ModdedSubState); - interp.variables.set("FlxAxes", lore.FunkinHX._dynamicify(lore.macros.MacroTools.getMapFromAbstract(flixel.util.FlxAxes))); - interp.variables.set("FlxColor", lore.FunkinHX._dynamicify(lore.macros.MacroTools.getMapFromAbstract(flixel.util.FlxColor))); - interp.variables.set("FlxKey", lore.FunkinHX._dynamicify(lore.macros.MacroTools.getMapFromAbstract(flixel.input.keyboard.FlxKey))); + interp.variables.set("FlxAxes", MacroTools.getAbstract(flixel.util.FlxAxes)); + interp.variables.set("FlxColor", MacroTools.getAbstract(flixel.util.FlxColor)); + interp.variables.set("FlxKey", MacroTools.getAbstract(flixel.input.keyboard.FlxKey)); interp.variables.set("FlxPoint", flixel.math.FlxPoint.FlxBasePoint); - interp.variables.set("HScriptType", lore.FunkinHX._dynamicify(lore.macros.MacroTools.getMapFromAbstract(lore.FunkinHX.HScriptType))); + interp.variables.set("HScriptType", MacroTools.getAbstract(lore.FunkinHX.HScriptType)); } public function execute(codeToRun:String):Dynamic diff --git a/source/PlayState.hx b/source/PlayState.hx index ac6a1a9ef..6191235da 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -1,5 +1,6 @@ package; +import lore.SmoothBar; import Achievements; import Conductor.Rating; import DialogueBoxPsych; @@ -203,11 +204,11 @@ class PlayState extends MusicBeatState public var combo:Int = 0; private var healthBarBG:AttachedSprite; - public var healthBar:lore.SmoothBar; + public var healthBar:SmoothBar; var songPercent:Float = 0; private var timeBarBG:AttachedSprite; - public var timeBar:FlxBar; + public var timeBar:SmoothBar; public var marvs:Int = 0; @@ -1142,7 +1143,7 @@ class PlayState extends MusicBeatState timeBarBG.xAdd = -4; timeBarBG.yAdd = -4; - timeBar = new FlxBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, + timeBar = new SmoothBar(timeBarBG.x + 4, timeBarBG.y + 4, LEFT_TO_RIGHT, Std.int(timeBarBG.width - 8), Std.int(timeBarBG.height - 8), this, 'songPercent', 0, 1); timeBar.scrollFactor.set(); timeBar.createFilledBar(0xFF000000, 0xFFFFFFFF); @@ -1150,6 +1151,7 @@ class PlayState extends MusicBeatState timeBar.alpha = 0; timeBar.visible = showTime; timeBarBG.sprTracker = timeBar; + timeBar.setRange(0, 1); if(ClientPrefs.downScroll) timeTxt.y = ClientPrefs.newTimeBar ? timeBarBG.y - timeTxt.height - 3 : FlxG.height - 44 else timeTxt.y = ClientPrefs.newTimeBar ? timeBarBG.y + timeBarBG.height + 3 : 19; @@ -1318,7 +1320,7 @@ class PlayState extends MusicBeatState add(healthBarBG); if(ClientPrefs.downScroll) healthBarBG.y = 0.11 * FlxG.height; - healthBar = new lore.SmoothBar(healthBarBG.x + 4, healthBarBG.y + 4, RIGHT_TO_LEFT, Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, + healthBar = new SmoothBar(healthBarBG.x + 4, healthBarBG.y + 4, RIGHT_TO_LEFT, Std.int(healthBarBG.width - 8), Std.int(healthBarBG.height - 8), this, 'health', 0, 2); healthBar.scrollFactor.set(); healthBar.numDivisions = 1000; @@ -3389,8 +3391,10 @@ class PlayState extends MusicBeatState var iconOffset:Int = 26; // old: FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01) - iconP1.x = healthBar.x + (healthBar.width * (1 - (@:privateAccess healthBar._lerpValue / 2))) + (150 * iconP1.scale.x - 150) / 2 - iconOffset; - iconP2.x = healthBar.x + (healthBar.width * (1 - (@:privateAccess healthBar._lerpValue / 2))) - (150 * iconP2.scale.x) / 2 - iconOffset * 2; + @:privateAccess { + iconP1.x = healthBar.x + (healthBar.width * (1 - (healthBar._lerpValue / 2))) + (150 * iconP1.scale.x - 150) / 2 - iconOffset; + iconP2.x = healthBar.x + (healthBar.width * (1 - (healthBar._lerpValue / 2))) - (150 * iconP2.scale.x) / 2 - iconOffset * 2; + } if (health > 2) health = 2; diff --git a/source/WinAPI.hx b/source/WinAPI.hx index ef69625de..b97bfa1f5 100644 --- a/source/WinAPI.hx +++ b/source/WinAPI.hx @@ -36,25 +36,17 @@ class WinAPI { return alpha; } - // kudos to bing chatgpt thing i hate C++ - #if windows - @:functionCode(' - HWND hwnd = GetActiveWindow(); - HMENU hmenu = GetSystemMenu(hwnd, FALSE); - if (enable) { - EnableMenuItem(hmenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); - } else { - EnableMenuItem(hmenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); - } - ') - #end + // if there's one thing i love it's funny one liners public static function setCloseButtonEnabled(enable:Bool) { + #if windows + untyped EnableMenuItem(untyped GetSystemMenu(untyped GetActiveWindow(), false), untyped SC_CLOSE, untyped MF_BYCOMMAND | enable ? untyped MF_ENABLED : untyped MF_GRAYED); + #end return enable; } // from indie cross \/ \/ \/ public static function messageBoxYN(#if cpp msg:ConstCharStar = null, title:ConstCharStar = null #else msg:String = null, title:String = null #end):Bool { #if windows - var msgBox:Int = untyped MessageBox(null, msg, title, untyped __cpp__("MB_ICONQUESTION | MB_YESNO")); + var msgBox:Int = untyped MessageBox(null, msg, title, untyped MB_ICONQUESTION | untyped MB_YESNO); return msgBox == 6; #end return true; diff --git a/source/lore/FunkinHX.hx b/source/lore/FunkinHX.hx index 6b269620b..4738da29b 100644 --- a/source/lore/FunkinHX.hx +++ b/source/lore/FunkinHX.hx @@ -47,18 +47,6 @@ class FunkinHX implements IFlxDestroyable { return c; } - /** - * Takes a Hash and returns a Dynamic object. - * Used here to make map representations of static abstract fields be accessible like they are in an abstract before compiling. - * @param obj - * @return Dynamic - */ - private static function _dynamicify(obj:Map):Dynamic { - var nd:Dynamic = {}; - for (k => v in obj) Reflect.setField(nd, k, v); - return nd; - } - public function destroy():Void { interp = null; scriptName = null; @@ -89,7 +77,7 @@ class FunkinHX implements IFlxDestroyable { if (interp != null) interp.variables.remove(k); } - public function new(f:String, ?primer:FunkinHX->Void = null, ?type:HScriptType = FILE):Void { + public function new(?f:String, ?primer:FunkinHX->Void = null, ?type:HScriptType = FILE):Void { scriptName = f; scriptType = type; var ttr:String = null; @@ -108,13 +96,17 @@ class FunkinHX implements IFlxDestroyable { } } if (maliciousLines.length > 0) { - var alertText:String = 'Th${maliciousLines.length == 1 ? "is line" : "ese lines"} of code are potentially malicious:\n\n{lines}\n\nWould you like to continue executing the script?'; - alertText = alertText.replace("{lines}", maliciousLines.join("\n")); + var alertText:String = 'Th${maliciousLines.length == 1 ? "is line" : "ese lines"} of code are potentially malicious:\n\n${maliciousLines.join("\n")}\n\n'; + alertText += #if windows 'Would you like to continue executing the script?' #else 'Make sure you trust this script. If not, close the game immediately.' #end ; + #if !windows + openfl.Lib.application.window.alert(alertText, 'Potentially malicious code detected'); + #else var confirmation = WinAPI.messageBoxYN(alertText, 'Potentially malicious code detected'); if (!confirmation) { destroy(); return; } + #end } for (i in tempArray) tempBuf.add(i + "\n"); ttr = tempBuf.toString(); @@ -252,11 +244,11 @@ class FunkinHX implements IFlxDestroyable { set("switchState", MusicBeatState.switchState); set("ModdedState", ModdedState); set("ModdedSubState", ModdedSubState); - set("FlxAxes", _dynamicify(MacroTools.getMapFromAbstract(flixel.util.FlxAxes))); - set("FlxColor", _dynamicify(MacroTools.getMapFromAbstract(flixel.util.FlxColor))); - set("FlxKey", _dynamicify(MacroTools.getMapFromAbstract(flixel.input.keyboard.FlxKey))); + set("FlxAxes", MacroTools.getAbstract(flixel.util.FlxAxes)); + set("FlxColor", MacroTools.getAbstract(flixel.util.FlxColor)); + set("FlxKey", MacroTools.getAbstract(flixel.input.keyboard.FlxKey)); set("FlxPoint", flixel.math.FlxPoint.FlxBasePoint); - set("HScriptType", _dynamicify(MacroTools.getMapFromAbstract(HScriptType))); + set("HScriptType", MacroTools.getAbstract(HScriptType)); set("cast", inlineCast); if (primer != null) primer(this); @@ -302,14 +294,15 @@ class FunkinHX implements IFlxDestroyable { return ast; } - public function runFunc(f:String, args:Array = null):Any { + public function runFunc(f:String, ?args:Array):Any { if (!loaded) return null; + if (args == null) args = []; try { return interp.callMethod(f, args); } catch (e:Dynamic) { if (!ignoreErrors && !flixel.FlxG.keys.pressed.SHIFT) { + inline CoolUtil.blockExecution(0.25); // to give the player time to hold shift openfl.Lib.application.window.alert('Error with script: ' + scriptName + ' at line ' + interp.posInfos().lineNumber + ":\n" + e + '\n\nHold SHIFT to bypass the error if it\'s blocking gameplay.', 'Haxe script error'); - CoolUtil.blockExecution(0.25); // to give the player time to hold shift } return null; } diff --git a/source/lore/SmoothBar.hx b/source/lore/SmoothBar.hx index e98021360..6869bc3e0 100644 --- a/source/lore/SmoothBar.hx +++ b/source/lore/SmoothBar.hx @@ -830,8 +830,9 @@ class SmoothBar extends FlxSprite { if (parent != null) { - if (_lerp) _lerpValue = FlxMath.lerp(value, _lerpValue, CoolUtil.boundTo(1 - (elapsed * 40), 0, 1)); updateValueFromParent(); + if (_lerp) _lerpValue = FlxMath.lerp(value, _lerpValue, CoolUtil.boundTo(1 - (elapsed * 40), 0, 1)); + if (_lerpValue < 0) _lerpValue = 0; if (!fixedPosition) { diff --git a/source/lore/macros/MacroTools.hx b/source/lore/macros/MacroTools.hx index 82bdaf6c6..083ba0026 100644 --- a/source/lore/macros/MacroTools.hx +++ b/source/lore/macros/MacroTools.hx @@ -3,81 +3,60 @@ package lore.macros; import haxe.macro.Context; import haxe.macro.Expr; - +using Reflect; using haxe.macro.Tools; class MacroTools { // https://code.haxe.org/category/macros/add-git-commit-hash-in-build.html public static macro function getGitCommitHash():ExprOf { - #if (!display) - var commitHash:String = ""; + #if display + return macro $v{"XXXXXXX"}; + #end var process = new sys.io.Process('git', ['rev-parse', 'HEAD']); if (process.exitCode() != 0) { var message = process.stderr.readAll().toString(); trace('git commit error: ${message}'); - } else commitHash = process.stdout.readLine(); - - // Generates a string expression - return macro $v{commitHash}; - #else - // `#if display` is used for code completion. In this case returning an - // empty string is good enough; We don't want to call git on every hint. - var commitHash:String = ""; - return macro $v{commitHash}; - #end + return macro $v{"XXXXXXX"}; + } else return macro $v{process.stdout.readLine()}; } public static macro function getEngineVersion():ExprOf { - #if !display - return macro $v{sys.io.File.getContent("./engineVersion.txt")}; - #else - return macro $v{"X.X.X"} + #if display + return macro $v{"X.X.X"}; #end + return macro $v{sys.io.File.getContent("./engineVersion.txt")}; } // modified from flixel.system.macros.FlxMacroUtil - // you still have to use get (e.g. FlxColor.get("WHITE") instead of FlxColor.WHITE) but it seems to be the best i can do - // nevermind i slayed :3 - public static macro function getMapFromAbstract(typePath:Expr, invert:Bool = false, ?exclude:Array):ExprOf> - { - var type = Context.getType(typePath.toString()); - var values:Map = []; - - if (exclude == null) - exclude = []; - - switch (type.follow()) - { - case TAbstract(_.get() => ab, _): - for (f in ab.impl.get().statics.get()) - { - switch (f.kind) - { - case FVar(AccInline, _): - var value = 0; - switch (f.expr().expr) - { - case TCast(Context.getTypedExpr(_) => expr, _): - value = expr.getValue(); - default: - } - if (f.name.toUpperCase() == f.name && !exclude.contains(f.name)) // uppercase? - { - values.set(f.name, value); - } - default: - } + // returns dynamic directly now because i realized reflect still works in macro context + public static macro function getAbstract(typePath:Expr, ?exclude:Array):Expr { + #if display + return macro $v{{}}; + #end + + var finalExpr:Dynamic = {}; + + if (exclude == null) exclude = []; + + switch (Context.getType(typePath.toString()).follow()) { + case TAbstract(_.get() => ab, _): + for (f in ab.impl.get().statics.get()) { + switch (f.kind) { + case FVar(AccInline, _): + var value:Dynamic = null; + switch (f.expr().expr) { + case TCast(Context.getTypedExpr(_) => expr, _): + value = expr.getValue(); + default: + } + if (!exclude.contains(f.name)) finalExpr.setField(f.name, value); + default: } - default: - } - - var finalExpr:Map = []; - for (k => v in values) { - if (invert) finalExpr.set(v, k); - else finalExpr.set(k, v); - } - - return macro $v{finalExpr}; + } + default: } + + return macro $v{finalExpr}; + } } \ No newline at end of file diff --git a/source/options/GameplaySettingsSubState.hx b/source/options/GameplaySettingsSubState.hx index 796521dad..9503f832d 100644 --- a/source/options/GameplaySettingsSubState.hx +++ b/source/options/GameplaySettingsSubState.hx @@ -33,12 +33,6 @@ class GameplaySettingsSubState extends BaseOptionsMenu ); option.onChange = playHitsound; addOption(option); - var option:Option = new Option('Optimization', - "Remove unnecessary graphics from the game.", - 'optimization', - 'bool', - false); - addOption(option); var option:Option = new Option('Controller Mode', 'Check this if you want to play with\na controller instead of using your Keyboard.', 'controllerMode',