diff --git a/source/AnimationDebug.hx b/source/AnimationDebug.hx index 7da01d0..d5eee0d 100644 --- a/source/AnimationDebug.hx +++ b/source/AnimationDebug.hx @@ -449,38 +449,48 @@ class AnimationDebug extends MusicBeatState charJson = chara.charProperties; animList = []; charAnims = ["**Unbind"]; - if (chara.charXml != null){ - if(chara.charXml.trim().substring(0,1) == "{"){ // Probably a sprite atlas - var obj:flixel.graphics.atlas.TexturePackerAtlas = Json.parse(chara.charXml); - inline function addAnim(name:String){ - if(name.lastIndexOf('-') != -1 ) name = name.substring(0,name.lastIndexOf('-') - 1); - else if(name.lastIndexOf('0') != -1)name = name.substring(0,name.lastIndexOf('0') - 1); - if(!charAnims.contains(name))charAnims.push(name); - } - // yes I stole this from flxatlasframes, fight me - if ((obj.frames is Array)){ - for (frame in Lambda.array(obj.frames)){ - addAnim(frame.filename); - } - }else{ - for (frameName in Reflect.fields(obj.frames)){ - addAnim(frameName); - } - } - }else{ - var charAnimsContains:Map = []; - var regTP:EReg = (~/ = []; + @:privateAccess{ + for(name=>_ in chara.frames.framesByName){ + if(!regTP.match(name)) continue; var matched = regTP.matched(1); if (charAnimsContains.exists(matched)) continue; - charAnimsContains[matched] = true; charAnims.push(matched); } - } - } + } + // var regTP:EReg = (~/ Finish"); uiMap["animStart"] = new FlxUINumericStepper(140, 130, 1, 0,0); uiMap["animFinish"] = new FlxUINumericStepper(140, 130, 1, 0,0); diff --git a/source/FuckState.hx b/source/FuckState.hx index 30f34dc..1abf5ab 100644 --- a/source/FuckState.hx +++ b/source/FuckState.hx @@ -31,6 +31,108 @@ class FuckState extends FlxUIState { public static var useOpenFL:Bool = false; public static var lastERROR = ""; public static var allowLogWrite:Bool = true; + public static function generateReport(error:String = "UNKNOWN ERROR?",type:String = "CRASH"):Bool{ + + var dateNow:String = ""; + var err = ""; + try{ + var funnyQuip = "insert funny line here"; + var _date = Date.now(); + try{ + var jokes = [ + "Hey look, mom! I'm on a crash report!", + "This wasn't supposed to go down like this...", + "Don't look at me that way.. I tried", + "Ow, that really hurt :(", + "missingno", + "Did I ask for your opinion?", + "Oh lawd it crashing", + "get stickbugged lmao", + "Mom? Come pick me up. I'm scared...", + "It's just standing there... Menacingly.", + "Are you having fun? I'm having fun.", + "That crash though", + "I'm out of ideas.", + "Where do we go from here?", + "Coded in Haxe.", + "Oh what the hell?", + "I just wanted to have fun.. :(", + "Oh no, not this again", + "null object reference is real and haunts us", + 'What is a error exactly?', + "I just got ratioed :(", + "L + Ratio + Skill Issue", + "Now with more crashes", + "I'm out of ideas.", + "me when null object reference", + 'you looked at me funny :(', + 'Hey VSauce, Michael here. What is an error?', + 'AAAHHHHHHHHHHHHHH! Don\'t mind me, I\'m practicing my screaming', + 'crash% speedrun less goooo!', + 'hey look, the consequences of my actions are coming to haunt me', + 'time to go to stack overflow for a solution', + 'you\'re mother', + 'sex pt 2: electric boobaloo', + 'sex pt 3: gone wrong', + 'the stalemate button was boobytrapped', + 'mf shoulda just stayed with psych engine :sob:', + 'super engine moment', + 'Another one bites the dust', + "It's fine, everything is good. What do you mean this is a crash report?" + + ]; + funnyQuip = jokes[Std.int(Math.random() * jokes.length - 1) ]; // I know, this isn't FlxG.random but fuck you the game just crashed + }catch(e){} + err = '# Super Engine Crash Report: \n# $funnyQuip\n$error'; + if(!SELoader.exists('crashReports/')){ + SELoader.createDirectory('crashReports/'); + } + + dateNow = StringTools.replace(StringTools.replace(_date.toString(), " ", "_"), ":", "."); + try{ + currentStateName = haxe.rtti.Rtti.getRtti(cast FlxG.state).path; + }catch(e){} + try{ + err +="\n\n # ---------- SYSTEM INFORMATION --------"; + + err +='\n Operating System: ${Sys.systemName()}'; + err +='\n Working Path: ${SELoader.absolutePath('')}'; + err +='\n Current Working Directory: ${Sys.getCwd()}'; + err +='\n Executable path: ${Sys.programPath()}'; + err +='\n Arguments: ${Sys.args()}'; + err +="\n # ---------- GAME INFORMATION ----------"; + err +='\n Version: ${MainMenuState.ver}'; + err +='\n Buildtype: ${MainMenuState.compileType}'; + err +='\n Debug: ${SESave.data.animDebug}'; + err +='\n Registered character count: ${TitleState.characters.length}'; + err +='\n Scripts: ${SESave.data.scripts}'; + err +='\n State: ${currentStateName}'; + err +='\n Save: ${SESave.data}'; + err +='\n # --------------------------------------'; + + }catch(e){ + trace('Unable to get system information! ${e.message}'); + } + try{ + SELoader.saveContent('crashReports/SUPERENGINE_${type}-${dateNow}.log',err); + }catch(e){ + sys.io.File.saveContent('crashReports/SUPERENGINE_${type}-${dateNow}.log',err); + + } + + + trace('Wrote a crash report to ./crashReports/SUPERENGINE_${type}-${dateNow}.log!'); + trace('Crash Report:\n$err'); + return true; + }catch(e){ + trace('Unable to write a crash report!'); + if(err != null && err.indexOf('SYSTEM INFORMATION') != -1){ + trace('Here is generated crash report:\n$err'); + + } + } + return false; + } // This function has a lot of try statements. // The game just crashed, we need as many failsafes as possible to prevent the game from closing or crash looping @:keep inline public static function FUCK(e:Dynamic,?info:String = "unknown",_forced:Bool = false,_FATAL:Bool = false,_rawError:Bool=false){ @@ -87,7 +189,6 @@ class FuckState extends FlxUIState { }catch(e){} } var saved = false; - var dateNow:String = ""; var err = ""; exception += _stack; @@ -95,96 +196,8 @@ class FuckState extends FlxUIState { if(lastERROR != exception && allowLogWrite){ lastERROR = exception; - try{ - var funnyQuip = "insert funny line here"; - var _date = Date.now(); - try{ - var jokes = [ - "Hey look, mom! I'm on a crash report!", - "This wasn't supposed to go down like this...", - "Don't look at me that way.. I tried", - "Ow, that really hurt :(", - "missingno", - "Did I ask for your opinion?", - "Oh lawd it crashing", - "get stickbugged lmao", - "Mom? Come pick me up. I'm scared...", - "It's just standing there... Menacingly.", - "Are you having fun? I'm having fun.", - "That crash though", - "I'm out of ideas.", - "Where do we go from here?", - "Coded in Haxe.", - "Oh what the hell?", - "I just wanted to have fun.. :(", - "Oh no, not this again", - "null object reference is real and haunts us", - 'What is a error exactly?', - "I just got ratioed :(", - "L + Ratio + Skill Issue", - "Now with more crashes", - "I'm out of ideas.", - "me when null object reference", - 'you looked at me funny :(', - 'Hey VSauce, Michael here. What is an error?', - 'AAAHHHHHHHHHHHHHH! Don\'t mind me, I\'m practicing my screaming', - 'crash% speedrun less goooo!', - 'hey look, the consequences of my actions are coming to haunt me', - 'time to go to stack overflow for a solution', - 'you\'re mother', - 'sex pt 2: electric boobaloo', - 'sex pt 3: gone wrong', - 'the stalemate button was boobytrapped', - 'mf shoulda just stayed with psych engine :sob:', - 'super engine moment', - 'Another one bites the dust', - "It's fine, everything is good. What do you mean this is a crash report?" - - ]; - funnyQuip = jokes[Std.int(Math.random() * jokes.length - 1) ]; // I know, this isn't FlxG.random but fuck you the game just crashed - }catch(e){} - err = '# Super Engine Crash Report: \n# $funnyQuip\n${exception}\nThis happened in ${info}'; - if(!SELoader.exists('crashReports/')){ - SELoader.createDirectory('crashReports/'); - } + saved = generateReport('${exception}\nThis happened in ${info}','CRASH'); - dateNow = StringTools.replace(StringTools.replace(_date.toString(), " ", "_"), ":", "."); - try{ - currentStateName = haxe.rtti.Rtti.getRtti(cast FlxG.state).path; - }catch(e){} - try{ - err +="\n\n # ---------- SYSTEM INFORMATION --------"; - - err +='\n Operating System: ${Sys.systemName()}'; - err +='\n Working Path: ${SELoader.absolutePath('')}'; - err +='\n Current Working Directory: ${Sys.getCwd()}'; - err +='\n Executable path: ${Sys.programPath()}'; - err +='\n Arguments: ${Sys.args()}'; - err +="\n # ---------- GAME INFORMATION ----------"; - err +='\n Version: ${MainMenuState.ver}'; - err +='\n Buildtype: ${MainMenuState.compileType}'; - err +='\n Debug: ${SESave.data.animDebug}'; - err +='\n Registered character count: ${TitleState.characters.length}'; - err +='\n Scripts: ${SESave.data.scripts}'; - err +='\n State: ${currentStateName}'; - err +='\n Save: ${SESave.data}'; - err +='\n # --------------------------------------'; - - }catch(e){ - trace('Unable to get system information! ${e.message}'); - } - sys.io.File.saveContent('crashReports/SUPERENGINE_CRASH-${dateNow}.log',err); - - saved = true; - trace('Wrote a crash report to ./crashReports/SUPERENGINE_CRASH-${dateNow}.log!'); - trace('Crash Report:\n$err'); - }catch(e){ - trace('Unable to write a crash report!'); - if(err != null && err.indexOf('SYSTEM INFORMATION') != -1){ - trace('Here is generated crash report:\n$err'); - - } - } } Main.renderLock.release(); if(Main.game == null || _rawError || !TitleState.initialized || useOpenFL){ diff --git a/source/HealthIcon.hx b/source/HealthIcon.hx index 727b96c..84f2f57 100644 --- a/source/HealthIcon.hx +++ b/source/HealthIcon.hx @@ -19,7 +19,7 @@ class HealthIcon extends FlxSprite public var trackingOffset:Float = 0; // public var pathh = "mods/characters"; - public function new(?char:String = 'bf', ?isPlayer:Bool = false,?clone:String = "",?isMenuIcon:Bool = false,?path:String = "mods/characters") { + public function new(?char:String = 'face', ?isPlayer:Bool = false,?clone:String = "",?isMenuIcon:Bool = false,?path:String = "mods/characters") { super(); this.isPlayer = isPlayer; this.isMenuIcon = isMenuIcon; @@ -48,13 +48,13 @@ class HealthIcon extends FlxSprite if(char is CharInfo){ charInfo = cast(char); } - if(char.namespace == "INTERNAL"){ - changeSprite(charInfo?.getNamespacedName() ?? "face"); - return; - } if(charInfo == null){ trace('Invalid type passed, defaulting to vanilla'); - changeSprite('INTERNAL|bf'); + changeSprite('face'); + return; + } + if(charInfo.nameSpace == "INTERNAL"){ + changeSprite(charInfo?.getNamespacedName() ?? "face"); return; } @@ -112,7 +112,7 @@ class HealthIcon extends FlxSprite public function changeSprite(?char:String = 'face',?clone:String = "face",?useClone:Bool = true,?pathh:String = "mods/characters") { if(char == hichar) return; if(char == "lonely") char = "face"; - var chars:Array = ["INTERNAL|bf","INTERNAL|gf","face",'EVENTNOTE','gf']; + var chars:Array = ["INTERNAL|bf","INTERNAL|gf","internal|bf","internal|gf",'bf',"face",'EVENTNOTE','gf']; var relAnims:Bool = true; var _path = ""; @@ -169,15 +169,13 @@ class HealthIcon extends FlxSprite if(chars.contains(char.toLowerCase())){ // For vanilla characters if (relAnims){ - animation.add('bf-car', [0, 1], 0, false, isPlayer); - animation.add('bf-christmas', [0, 1], 0, false, isPlayer); if(graphic.width > 451){ // Old icon grid MainMenuState.errorMessage += ('You are using a really old iconGrid, this is usually caused by updating from a really old version of the game\nPlease reinstall the game'); }else{ // Based icon grid + animation.add('internal|bf', [0, 1], 0, false, isPlayer); + animation.add('internal|gf', [2], 0, false, isPlayer); animation.add('gf', [2], 0, false, isPlayer); - animation.add('INTERNAL|gf', [2], 0, false, isPlayer); - - animation.add('EVENTNOTE', [5, 5], 0, false, false); + animation.add('eventnote', [5, 5], 0, false, false); } } animation.play(char.toLowerCase()); diff --git a/source/LoadingScreen.hx b/source/LoadingScreen.hx index d9df46c..c0a4ede 100644 --- a/source/LoadingScreen.hx +++ b/source/LoadingScreen.hx @@ -11,6 +11,7 @@ import openfl.text.TextFormat; import flixel.math.FlxMath; import flixel.text.FlxText; import lime.app.Application; +import se.SEProfiler; @:NullSafety(StrictThreaded) class LoadingScreen extends Sprite{ public static var object:LoadingScreen; @@ -261,6 +262,7 @@ import lime.app.Application; forceHide(); return; } + SEProfiler.decay = false; // object.alpha = 1; if(tween != null){tween.cancel();} isVisible = object.funni = true; @@ -277,6 +279,7 @@ import lime.app.Application; } public static function forceHide(){ if(object == null) return; + SEProfiler.decay = true; if(tween != null){tween.cancel();} isVisible = object.funni = false; object.alpha = 0; @@ -287,6 +290,7 @@ import lime.app.Application; public static function hide(){ if(Main.game != null) Main.game.blockUpdate = Main.game.blockDraw = false; if(object == null) return; + SEProfiler.decay = true; if(!object.funni){ object.alpha = 0; return; diff --git a/source/Note.hx b/source/Note.hx index b6fe174..8a0f9c3 100644 --- a/source/Note.hx +++ b/source/Note.hx @@ -240,8 +240,8 @@ class Note extends FlxSprite case 1:if (SESave.data.cpuStrums) {PlayState.instance.DadStrumPlayAnim(noteData);} }; // Strums if(noteAnimation != null){ - var anim = (if(noteAnimation == "") getNoteAnim(noteData) else noteAnimation); - var char = (if(char == null)PlayState.getCharFromID(charID,true) else char); + var anim = ((noteAnimation == "") ? getNoteAnim(noteData) : noteAnimation); + var char = ((char == null) ? PlayState.getCharFromID(charID,true) : char); if(!isSustainNote && char.animName == anim){ char.animation.play('idle',true); } diff --git a/source/OptionsMenu.hx b/source/OptionsMenu.hx index d63dbcc..305f6a3 100644 --- a/source/OptionsMenu.hx +++ b/source/OptionsMenu.hx @@ -168,7 +168,8 @@ class OptionsMenu extends MusicBeatState new HCBoolOption("Seperate PE chars from SE Chars","Add -pe to Psych character ID's to prevent conflicts","PECharSeperate",ReloadCharlist.RELOAD), new HCBoolOption("Add Psych Engine Characters","(Requires a reload of character list) Allows Psych characters to load.\nPsych Characters are not properly implemented yet","PECharLoading",ReloadCharlist.RELOAD), new HCBoolOption("Load Psych Events","Attempts to load Psych events from songs(Experimental)","loadPsychEvents"), - new HCBoolOption("Quick reloading songs","Allows songs to quick-reload when you restart. This can break some songs","QuickReloading"), + new HCBoolOption("Quick reloading songs","Allows songs to quick-reload when you restart. This can break some songs or scripts","QuickReloading"), + new HCBoolOption("Ignore Errors","Ignore some errors and save a report instead","ignoreErrors"), ],'Toggle compatibility with specific features from mods/engines'), new OptionCategory("Performance", [ new FPSCapOption("Cap your Frames Per Second, This controls how fast the game will update your screen"), diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index 9ee2e33..2678ea8 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -139,7 +139,7 @@ class PauseSubState extends MusicBeatSubstate { restarts.borderSize = 2; restarts.updateHitbox(); restarts.alignment=RIGHT; - SEUIUtilities.addSpacedUI(this,{y:15,objects:[ + SEUIUtilities.addSpacedUI(this,{x:FlxG.width - 5,y:15,objects:[ [levelInfo], [levelDifficulty], [restarts] @@ -149,10 +149,6 @@ class PauseSubState extends MusicBeatSubstate { levelDifficulty.alpha = 0; levelInfo.alpha = 0; - levelInfo.x = FlxG.width - levelInfo.width ; - levelDifficulty.x = FlxG.width - 20; - restarts.x = FlxG.width - 20; - FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartIn}); FlxTween.tween(levelInfo, {alpha: 1}, 0.4, {ease: FlxEase.bounceOut, startDelay: 0.3}); FlxTween.tween(levelDifficulty, {alpha: 1}, 0.4, {ease: FlxEase.bounceOut, startDelay: 0.3}); diff --git a/source/SELoader.hx b/source/SELoader.hx index 4affa32..4f32b88 100644 --- a/source/SELoader.hx +++ b/source/SELoader.hx @@ -65,6 +65,7 @@ class SELoader { static public var cache:InternalCache = new InternalCache(); public static var AssetPathCache:Map=[]; + public static var AssetPathListingCache:Map>=[]; public static var aliases:Map=[]; public static var PATH(default,set):String = ''; @@ -126,7 +127,6 @@ class SELoader { return (PATH + path).replace('//','/'); // Fixes paths having //'s in them } - public static function getAssetPath(path:String,?namespace:String = ""):String{ if(#if windows path.substring(1,2) == ':' || #end path.substring(0,1) == "/" || rawMode){ rawMode=false; @@ -283,6 +283,8 @@ class SELoader { } public static function reset(){ cache.clear(); + AssetPathListingCache = []; + AssetPathCache=[]; gc(); } @:keep inline public static function getContent(textPath:String):String{return loadText(textPath,false);} @@ -464,6 +466,30 @@ class SELoader { return FileSystem.exists(getPath(path)); } public static function readDirectory(path:String):Array{ + if(!SESave.data.HDDMode && (path.startsWith('assets/') || path.startsWith('assets:'))){ + path = path.substring(7); + if(AssetPathListingCache[path] != null){ + return AssetPathListingCache[path].copy(); + } + var modsFolder = new SEDirectory(getRawPath('mods/')); + var packsFolder = modsFolder.newDirectory('packs/'); + var listing:Map = []; + for (pack in orderList(SELoader.readDirectory(packsFolder.toString()))){ + if(exists('$packsFolder/$pack/assets/$path')){ + for(p in readDirectory('$packsFolder/$pack/assets/$path')){ + listing[p]=true; + } + } + if(exists('$packsFolder/$pack/assets/shared/$path')){ + for(p in readDirectory('$packsFolder/$pack/assets/shared/$path')){ + listing[p]=true; + } + } + } + var list = AssetPathListingCache[path] = []; + for(key in listing.keys()) list.push(key); + return list.copy(); + } return FileSystem.readDirectory(getPath(path)); } public static function readDirectories(paths:Array):Array{ diff --git a/source/ScriptMusicBeatState.hx b/source/ScriptMusicBeatState.hx index 62549e2..7798aad 100644 --- a/source/ScriptMusicBeatState.hx +++ b/source/ScriptMusicBeatState.hx @@ -408,7 +408,7 @@ class ScriptMusicBeatState extends MusicBeatState{ if (SELoader.exists(_path)){ if(brtool == null) brtool = getBRTools(_path,v); - trace("$nameSpace - $_path"); + trace('$nameSpace - $_path'); for (i in CoolUtil.orderList(SELoader.readDirectory(_path))) { if(i.endsWith(".hscript") || #if linc_luajit i.endsWith(".lua") || #end i.endsWith(".hx")){ var cont = false; diff --git a/source/ScriptableState.hx b/source/ScriptableState.hx index 9c83165..1323a3f 100644 --- a/source/ScriptableState.hx +++ b/source/ScriptableState.hx @@ -143,8 +143,9 @@ class SelectScriptableState extends SearchMenuState{ } public static function handleError(err:String){ - try{ScriptableStateManager.die();}catch(e){} - MainMenuState.handleError(err); + // try{ScriptableStateManager.die();}catch(e){} + // MainMenuState.handleError(err); + throw(err); // Main.game.forceStateSwitch(new SelectScriptableState(err)); } diff --git a/source/SearchMenuState.hx b/source/SearchMenuState.hx index 22bfea2..b1969a3 100644 --- a/source/SearchMenuState.hx +++ b/source/SearchMenuState.hx @@ -242,9 +242,10 @@ class SearchMenuState extends ScriptMusicBeatState { curSelected = 0; if(reload){CoolUtil.clearFlxGroup(grpSongs);} songs = []; - var i:Int = 0; var query = new EReg((~/[-_ ]/g).replace(search.toLowerCase().replace('\\','\\\\'),'[-_ ]'),'i'); // Regex that allows _ and - for songs to still pop up if user puts space, game ignores - and _ when showing + callInterp('reloadList',[query]); + if(cancelCurrentFunction) return; for (char in searchList){ if(search == "" || query.match(char.toLowerCase()) ){ addToList(char,i); diff --git a/source/multi/MultiMenuState.hx b/source/multi/MultiMenuState.hx index 6646a80..ca34849 100644 --- a/source/multi/MultiMenuState.hx +++ b/source/multi/MultiMenuState.hx @@ -400,19 +400,14 @@ class MultiMenuState extends onlinemod.OfflineMenuState { } if (SELoader.exists("mods/packs")){ for (name in orderList(SELoader.readDirectory("mods/packs"))){ - // dataDir = "mods/packs/" + dataDir + "/charts/"; + LoadingScreen.loadingText = 'Scanning mods/packs/$name'; var catMatch = query.match(name.toLowerCase()); - // var dataDir = SELoader.anyExists(['${baseDir}charts/','${baseDir}data/']); - // !SELoader.exists(dataDir) && !SELoader.exists(dataDir = "mods/packs/" + name + "/data/") - // if(dataDir == null) continue; _packCount++; if(!catMatch){ emptyCats.push(name); continue; } var catID = categories.length; - // var containsSong = false; - // var dirs = orderList(SELoader.readDirectory(dataDir)); var baseDir = 'mods/packs/$name/'; var folderSongs:Array = SELoader.getSongsFromFolder(baseDir); diff --git a/source/se/SEProfiler.hx b/source/se/SEProfiler.hx index 544aac5..f22b0c3 100644 --- a/source/se/SEProfiler.hx +++ b/source/se/SEProfiler.hx @@ -5,6 +5,7 @@ import flixel.math.FlxMath; class SEProfiler{ public static var enabled:Bool = false; + public static var decay:Bool = true; public static var list:Map = []; @:keep inline public static function init(){ getProfiler('update',true); @@ -76,6 +77,7 @@ class SEProfiler{ } // TODO If this doesn't do anything extra soon, i'll remove the useless if and just make it return the check @:keep inline function update():Bool{ + if(!SEProfiler.decay) return false; ticksSinceUpdate++; if(!keep && ticksSinceUpdate > 120){ return true; diff --git a/version.downloadMe b/version.downloadMe index 9c56bbe..f35228c 100644 --- a/version.downloadMe +++ b/version.downloadMe @@ -1,4 +1,4 @@ -24.07.17.0300; +24.07.28.1348; * Better Psych character support(Still kinda experimental but should be more stable) * Fix some small errors * Fix characters not loading due to using ID instead of folderName