diff --git a/assets/data/dialogue/characters/senpai.hx b/assets/data/dialogue/characters/senpai.hx index cd17b115..1ea774d7 100644 --- a/assets/data/dialogue/characters/senpai.hx +++ b/assets/data/dialogue/characters/senpai.hx @@ -1,6 +1,6 @@ function postHide() { if(curTween != null) { - if(animation.curAnim?.name == 'angry-show') curTween.cancel(); + if(getAnimName() == 'angry-show') curTween.cancel(); else curTween.percent = 1; } -} \ No newline at end of file +} diff --git a/source/flx3d/Flx3DCamera.hx b/source/flx3d/Flx3DCamera.hx index c2405144..d4f76229 100644 --- a/source/flx3d/Flx3DCamera.hx +++ b/source/flx3d/Flx3DCamera.hx @@ -87,7 +87,7 @@ class Flx3DCamera extends FlxCamera { default: new OBJParser(); }, (event:Asset3DEvent) -> { if (event.asset != null && event.asset.assetType == Asset3DType.MESH) { - var mesh:Mesh = cast(event.asset, Mesh); + var mesh:Mesh = cast event.asset; if (material != null) mesh.material = material; meshes.push(mesh); diff --git a/source/flx3d/Flx3DView.hx b/source/flx3d/Flx3DView.hx index 1856c507..59413e77 100644 --- a/source/flx3d/Flx3DView.hx +++ b/source/flx3d/Flx3DView.hx @@ -60,7 +60,7 @@ class Flx3DView extends FlxView3D { default: new OBJParser(); }, (event:Asset3DEvent) -> { if (event.asset != null && event.asset.assetType == Asset3DType.MESH) { - var mesh:Mesh = cast(event.asset, Mesh); + var mesh:Mesh = cast event.asset; if (material != null) mesh.material = material; meshes.push(mesh); diff --git a/source/funkin/backend/FunkinSprite.hx b/source/funkin/backend/FunkinSprite.hx index e084c5a6..a3a0a5f9 100644 --- a/source/funkin/backend/FunkinSprite.hx +++ b/source/funkin/backend/FunkinSprite.hx @@ -1,10 +1,13 @@ package funkin.backend; import flixel.addons.effects.FlxSkewedSprite; +import flixel.animation.FlxAnimation; import flixel.math.FlxMatrix; import flixel.math.FlxPoint; import flixel.math.FlxRect; import flixel.system.FlxAssets.FlxGraphicAsset; +import flixel.util.typeLimit.OneOfTwo; +import flxanimate.animate.FlxAnim.FlxSymbolAnimation; import funkin.backend.scripting.events.PlayAnimContext; import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.system.interfaces.IOffsetCompatible; @@ -321,6 +324,12 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I lastAnimContext = Context; } + public function getAnim(name:String):OneOfTwo { + if(animateAtlas != null) + return animateAtlas.anim.getByName(name); + return animation.getByName(name); + } + public inline function getAnimOffset(name:String) { if (animOffsets.exists(name)) @@ -362,7 +371,11 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I } public inline function isAnimFinished() { - return animateAtlas != null ? (animateAtlas.anim.finished) : (animation.curAnim != null ? animation.curAnim.finished : true); + return animateAtlas != null ? animateAtlas.anim.finished : (animation.curAnim != null ? animation.curAnim.finished : true); + } + + public inline function isAnimAtEnd() { + return animateAtlas != null ? animateAtlas.anim.isAtEnd : (animation.curAnim != null ? animation.curAnim.isAtEnd : false); } override function updateAnimation(elapsed:Float) { diff --git a/source/funkin/backend/MusicBeatGroup.hx b/source/funkin/backend/MusicBeatGroup.hx index ec6f2693..5cccf0f6 100644 --- a/source/funkin/backend/MusicBeatGroup.hx +++ b/source/funkin/backend/MusicBeatGroup.hx @@ -4,12 +4,12 @@ import funkin.backend.system.interfaces.IBeatReceiver; class MusicBeatGroup extends FlxTypedSpriteGroup implements IBeatReceiver { public function beatHit(curBeat:Int) { - for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat); + for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver = cast e;_;}).beatHit(curBeat); } public function stepHit(curStep:Int) { - for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep); + for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver = cast e;_;}).stepHit(curStep); } public function measureHit(curMeasure:Int) { - for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).measureHit(curMeasure); + for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver = cast e;_;}).measureHit(curMeasure); } } \ No newline at end of file diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index 35dbfd04..eca2968c 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -196,19 +196,19 @@ class MusicBeatState extends FlxState implements IBeatReceiver @:dox(hide) public function stepHit(curStep:Int):Void { - for(e in members) if (e != null && e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep); + for(e in members) if (e != null && e is IBeatReceiver) ({var _:IBeatReceiver=cast e;_;}).stepHit(curStep); call("stepHit", [curStep]); } @:dox(hide) public function beatHit(curBeat:Int):Void { - for(e in members) if (e != null && e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat); + for(e in members) if (e != null && e is IBeatReceiver) ({var _:IBeatReceiver=cast e;_;}).beatHit(curBeat); call("beatHit", [curBeat]); } @:dox(hide) public function measureHit(curMeasure:Int):Void { - for(e in members) if (e != null && e is IBeatReceiver) cast(e, IBeatReceiver).measureHit(curMeasure); + for(e in members) if (e != null && e is IBeatReceiver) ({var _:IBeatReceiver=cast e;_;}).measureHit(curMeasure); call("measureHit", [curMeasure]); } @@ -282,8 +282,9 @@ class MusicBeatState extends FlxState implements IBeatReceiver public override function resetSubState() { super.resetSubState(); if (subState != null && subState is MusicBeatSubstate) { - cast(subState, MusicBeatSubstate).parent = this; - cast(subState, MusicBeatSubstate).onSubstateOpen(); + var subState:MusicBeatSubstate = cast subState; + subState.parent = this; + subState.onSubstateOpen(); } } } diff --git a/source/funkin/backend/MusicBeatSubstate.hx b/source/funkin/backend/MusicBeatSubstate.hx index e571d32a..aebafb20 100644 --- a/source/funkin/backend/MusicBeatSubstate.hx +++ b/source/funkin/backend/MusicBeatSubstate.hx @@ -185,19 +185,19 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver @:dox(hide) public function stepHit(curStep:Int):Void { - for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep); + for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver=cast e;_;}).stepHit(curStep); call("stepHit", [curStep]); } @:dox(hide) public function beatHit(curBeat:Int):Void { - for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat); + for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver=cast e;_;}).beatHit(curBeat); call("beatHit", [curBeat]); } @:dox(hide) public function measureHit(curMeasure:Int):Void { - for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).measureHit(curMeasure); + for(e in members) if (e is IBeatReceiver) ({var _:IBeatReceiver=cast e;_;}).measureHit(curMeasure); call("measureHit", [curMeasure]); } @@ -260,7 +260,8 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver public override function resetSubState() { if (subState != null && subState is MusicBeatSubstate) { - cast(subState, MusicBeatSubstate).parent = this; + var subState:MusicBeatSubstate = cast subState; + subState.parent = this; super.resetSubState(); if (subState != null) cast(subState, MusicBeatSubstate).onSubstateOpen(); diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx index 81b35d96..0fd0931b 100644 --- a/source/funkin/backend/assets/Paths.hx +++ b/source/funkin/backend/assets/Paths.hx @@ -113,17 +113,28 @@ class Paths return scriptPath; } - static public function chart(song:String, ?difficulty:String = "normal"):String { + static public function chart(song:String, ?difficulty:String = "normal"):String + { difficulty = difficulty.toLowerCase(); song = song.toLowerCase(); return getPath('songs/$song/charts/$difficulty.json', null); } - static public function character(character:String):String { + inline static public function character(character:String):String + { return getPath('data/characters/$character.xml', null); } + /** + * Gets the name of a registered font. + * @param font The font's path (if it's already passed as a font name, the same name will be returned) + */ + inline static public function getFontName(font:String) + { + return OpenFlAssets.exists(font, FONT) ? OpenFlAssets.getFont(font).fontName : font; + } + inline static public function font(key:String) { return getPath('fonts/$key'); diff --git a/source/funkin/backend/scripting/MultiThreadedScript.hx b/source/funkin/backend/scripting/MultiThreadedScript.hx index 3ba51f52..24754c7c 100644 --- a/source/funkin/backend/scripting/MultiThreadedScript.hx +++ b/source/funkin/backend/scripting/MultiThreadedScript.hx @@ -33,8 +33,8 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe if (parentScript != null) { if (script is HScript && parentScript is HScript) { - var hscript = cast(script, HScript); - var parentHScript = cast(parentScript, HScript); + var hscript:HScript = cast script; + var parentHScript:HScript = cast parentScript; hscript.interp.variables = parentHScript.interp.variables; hscript.interp.publicVariables = parentHScript.interp.publicVariables; diff --git a/source/funkin/backend/scripting/events/CharacterNodeEvent.hx b/source/funkin/backend/scripting/events/CharacterNodeEvent.hx new file mode 100644 index 00000000..9577a64f --- /dev/null +++ b/source/funkin/backend/scripting/events/CharacterNodeEvent.hx @@ -0,0 +1,21 @@ +package funkin.backend.scripting.events; + +import funkin.game.Character; +import haxe.xml.Access; + +final class CharacterNodeEvent extends CancellableEvent { + /** + * The character instance + */ + public var character:Character; + + /** + * The node which is currently being parsed + */ + public var node:Access; + + /** + * The name of the node, quicker access than e.node.name + */ + public var name:String; +} \ No newline at end of file diff --git a/source/funkin/backend/scripting/events/CharacterXMLEvent.hx b/source/funkin/backend/scripting/events/CharacterXMLEvent.hx new file mode 100644 index 00000000..e4f107fd --- /dev/null +++ b/source/funkin/backend/scripting/events/CharacterXMLEvent.hx @@ -0,0 +1,16 @@ +package funkin.backend.scripting.events; + +import funkin.game.Character; +import haxe.xml.Access; + +final class CharacterXMLEvent extends CancellableEvent { + /** + * The character instance + */ + public var character:Character; + + /** + * The xml + */ + public var xml:Access; +} \ No newline at end of file diff --git a/source/funkin/backend/system/Conductor.hx b/source/funkin/backend/system/Conductor.hx index 8d4ef85a..f9758b94 100644 --- a/source/funkin/backend/system/Conductor.hx +++ b/source/funkin/backend/system/Conductor.hx @@ -181,7 +181,11 @@ class Conductor private static var __updateMeasure:Bool; private static function update() { - if (FlxG.state != null && FlxG.state is MusicBeatState && cast(FlxG.state, MusicBeatState).cancelConductorUpdate) return; + if (FlxG.state != null && FlxG.state is MusicBeatState) { + var state:MusicBeatState = cast FlxG.state; + if(state.cancelConductorUpdate) + return; + } __updateSongPos(FlxG.elapsed); @@ -233,7 +237,7 @@ class Conductor var state = FlxG.state; while(state != null) { if (state is IBeatReceiver && (state.subState == null || state.persistentUpdate)) { - var st = cast(state, IBeatReceiver); + var st:IBeatReceiver = cast state; if (curStep > oldStep) { for(i in oldStep...curStep) { st.stepHit(i+1); diff --git a/source/funkin/backend/system/Flags.hx b/source/funkin/backend/system/Flags.hx index 0999e759..2ccee499 100644 --- a/source/funkin/backend/system/Flags.hx +++ b/source/funkin/backend/system/Flags.hx @@ -32,9 +32,9 @@ class Flags { var splitContent = [for(e in data.split("\n")) if ((trimmed = e.trim()) != "") trimmed]; for(line in splitContent) { - if (line.startsWith(";")) continue; - if (line.startsWith("#")) continue; - if (line.startsWith("//")) continue; + if(line.startsWith(";")) continue; + if(line.startsWith("#")) continue; + if(line.startsWith("//")) continue; if(line.length == 0) continue; if(line.charAt(0) == "[" && line.charAt(line.length-1) == "]") continue; @@ -43,10 +43,9 @@ class Flags { var name = line.substr(0, index).trim(); var value = line.substr(index+1).trim(); - if (value.length > 1 && value.charCodeAt(0) == '"'.code && value.charCodeAt(value.length-1) == '"'.code) - value = value.substr(1, value.length - 2); - - if (value.length == 0 || name.length == 0) + var wasQuoted = value.length > 1 && value.charCodeAt(0) == '"'.code && value.charCodeAt(value.length-1) == '"'.code; + if(wasQuoted) value = value.substr(1, value.length - 2); + if((!wasQuoted && value.length == 0) || name.length == 0) continue; if(!flags.exists(name)) diff --git a/source/funkin/backend/system/framerate/SystemInfo.hx b/source/funkin/backend/system/framerate/SystemInfo.hx index 979670e5..da961981 100644 --- a/source/funkin/backend/system/framerate/SystemInfo.hx +++ b/source/funkin/backend/system/framerate/SystemInfo.hx @@ -91,7 +91,7 @@ class SystemInfo extends FramerateCategory { #end if(openfl.display3D.Context3D.__glMemoryTotalAvailable != -1) { - var vRAMBytes:UInt = cast(flixel.FlxG.stage.context3D.gl.getParameter(openfl.display3D.Context3D.__glMemoryTotalAvailable), UInt); + var vRAMBytes:UInt = cast flixel.FlxG.stage.context3D.gl.getParameter(openfl.display3D.Context3D.__glMemoryTotalAvailable); if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0) Logs.trace('Unable to grab GPU VRAM', ERROR, RED); else diff --git a/source/funkin/backend/system/macros/FlagMacro.macro.hx b/source/funkin/backend/system/macros/FlagMacro.macro.hx index 477512c0..3f827d7b 100644 --- a/source/funkin/backend/system/macros/FlagMacro.macro.hx +++ b/source/funkin/backend/system/macros/FlagMacro.macro.hx @@ -52,6 +52,10 @@ class FlagMacro { parser = macro value.split(",").map((e) -> e.trim()); case macro: Array: parser = macro value.split(","); + case macro: Array: + parser = macro value.split(",").map((e) -> Std.parseInt(e)); + case macro: Array: + parser = macro value.split(",").map((e) -> Std.parseFloat(e)); case macro: Array: parser = macro value.split(",").map((e) -> { e = e.trim(); @@ -59,6 +63,8 @@ class FlagMacro { }); case macro: Int: parser = macro Std.parseInt(value); + case macro: Float: + parser = macro Std.parseFloat(value); case macro: String: parser = macro value; case macro: Bool: @@ -145,7 +151,7 @@ class FlagMacro { case TPath({name: "Map", pack: []}): Context.error("Flag " + field.name + " cannot be a Map", field.pos); default: - Context.error("Flag " + field.name + " must be either a Bool, Int, String, Array, Array or Array", field.pos); + Context.error("Flag " + field.name + " must be either a Bool, Int, Float, String, Array, Array, Array, Array or Array", field.pos); } if(parser == null) { diff --git a/source/funkin/backend/system/modules/AudioSwitchFix.hx b/source/funkin/backend/system/modules/AudioSwitchFix.hx index c7065f0c..9ca1f3d3 100644 --- a/source/funkin/backend/system/modules/AudioSwitchFix.hx +++ b/source/funkin/backend/system/modules/AudioSwitchFix.hx @@ -62,6 +62,7 @@ final class AudioSwitchFix { } } +@:dox(hide) typedef PlayingSound = { var sound:FlxSound; var time:Float; diff --git a/source/funkin/backend/system/modules/CrashHandler.hx b/source/funkin/backend/system/modules/CrashHandler.hx index 6a460ac1..61c5029d 100644 --- a/source/funkin/backend/system/modules/CrashHandler.hx +++ b/source/funkin/backend/system/modules/CrashHandler.hx @@ -20,10 +20,10 @@ final class CrashHandler { public static function onUncaughtError(e:UncaughtErrorEvent) { var m:String = e.error; if (Std.isOfType(e.error, Error)) { - var err = cast(e.error, Error); + var err:Error = cast e.error; m = '${err.message}'; } else if (Std.isOfType(e.error, ErrorEvent)) { - var err = cast(e.error, ErrorEvent); + var err:ErrorEvent = cast e.error; m = '${err.text}'; } var stack = CallStack.exceptionStack(); diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 56dd7634..7236a18e 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -636,7 +636,7 @@ final class CoolUtil var fmt = new FlxTextFormat(); fmt.format.color = Reflect.hasField(fmtt, "color") ? FlxColor.fromString(fmtt.color) : text.color; - fmt.format.font = Reflect.hasField(fmtt, "font") ? Paths.font(fmtt.font) : text.font; + fmt.format.font = Reflect.hasField(fmtt, "font") ? Paths.getFontName(Paths.font(fmtt.font)) : text.font; fmt.format.size = Reflect.hasField(fmtt, "size") ? Std.parseInt(fmtt.size) : text.size; fmt.format.italic = Reflect.hasField(fmtt, "italic") ? fmtt.italic == "true" : text.italic; fmt.format.bold = Reflect.hasField(fmtt, "bold") ? fmtt.bold == "true" : text.bold; diff --git a/source/funkin/backend/utils/MemoryUtil.hx b/source/funkin/backend/utils/MemoryUtil.hx index e3a64b02..e646aba1 100644 --- a/source/funkin/backend/utils/MemoryUtil.hx +++ b/source/funkin/backend/utils/MemoryUtil.hx @@ -151,25 +151,4 @@ final class MemoryUtil { #end return "Unknown"; } - - private static var _nb:Int = 0; - private static var _nbD:Int = 0; - private static var _zombie:Dynamic; - - public static function destroyFlixelZombies() { - #if cpp - // Gc.enterGCFreeZone(); - - while ((_zombie = Gc.getNextZombie()) != null) { - _nb++; - if (_zombie is flixel.util.FlxDestroyUtil.IFlxDestroyable) { - flixel.util.FlxDestroyUtil.destroy(cast(_zombie, flixel.util.FlxDestroyUtil.IFlxDestroyable)); - _nbD++; - } - } - Sys.println('Zombies: ${_nb}; IFlxDestroyable Zombies: ${_nbD}'); - - // Gc.exitGCFreeZone(); - #end - } } \ No newline at end of file diff --git a/source/funkin/backend/utils/NativeAPI.hx b/source/funkin/backend/utils/NativeAPI.hx index b599b090..e8320160 100644 --- a/source/funkin/backend/utils/NativeAPI.hx +++ b/source/funkin/backend/utils/NativeAPI.hx @@ -116,8 +116,8 @@ class NativeAPI { if(backgroundColor == NONE) backgroundColor = BLACK; - var fg = cast(foregroundColor, Int); - var bg = cast(backgroundColor, Int); + var fg:Int = cast foregroundColor; + var bg:Int = cast backgroundColor; Windows.setConsoleColors((bg * 16) + fg); #elseif sys Sys.print("\x1b[0m"); diff --git a/source/funkin/backend/utils/XMLUtil.hx b/source/funkin/backend/utils/XMLUtil.hx index d2dcf417..8ff95a6b 100644 --- a/source/funkin/backend/utils/XMLUtil.hx +++ b/source/funkin/backend/utils/XMLUtil.hx @@ -6,6 +6,13 @@ import funkin.backend.FunkinSprite.XMLAnimType; import funkin.backend.FunkinSprite; import funkin.game.Character; import funkin.backend.system.ErrorCode; +import funkin.backend.FunkinSprite.XMLAnimType; +import flixel.util.FlxColor; +import haxe.xml.Access; +import funkin.backend.scripting.Script; +import funkin.backend.scripting.DummyScript; +import funkin.backend.scripting.ScriptPack; +import flixel.util.typeLimit.OneOfTwo; import funkin.backend.system.interfaces.IOffsetCompatible; import haxe.xml.Access; @@ -257,7 +264,7 @@ final class XMLUtil { cast(sprite, IOffsetCompatible).addOffset(animData.name, animData.x, animData.y); if (sprite is FunkinSprite) { - var xmlSpr = cast(sprite, FunkinSprite); + var xmlSpr:FunkinSprite = cast sprite; var name = animData.name; switch(animData.animType) { case BEAT: @@ -333,6 +340,51 @@ final class XMLUtil { } } +class XMLImportedScriptInfo { + public var path:String; + public var shortLived:Bool = false; + public var loadBefore:Bool = true; + public var importStageSprites:Bool = false; // maybe will change later?? - Nex + public var parentScriptPack:ScriptPack = null; + + public function new(path:String, parentScriptPack:ScriptPack) { + this.parentScriptPack = parentScriptPack; + this.path = path; + } + + public function getScript():Script + return parentScriptPack == null ? null : parentScriptPack.getByPath(path); + + public static function prepareInfos(node:Access, parentScriptPack:ScriptPack, ?onScriptPreLoad:XMLImportedScriptInfo->Void):XMLImportedScriptInfo { + if (!node.has.script || parentScriptPack == null) return null; + + var folder = node.getAtt("folder").getDefault("data/scripts/"); + if (!folder.endsWith("/")) folder += "/"; + + var path = Paths.script(folder + node.getAtt("script")); + var daScript = Script.create(path); + if (daScript is DummyScript) { + Logs.trace('Script Extension at ${path} does not exist.', ERROR); + return null; + } + + var infos = new XMLImportedScriptInfo(daScript.path, parentScriptPack); + infos.shortLived = node.getAtt("isShortLived") == "true" || node.getAtt("shortLived") == "true"; + infos.importStageSprites = node.getAtt("importStageSprites") == "true"; + @:privateAccess infos.loadBefore = shouldLoadBefore(node); + + if (onScriptPreLoad != null) onScriptPreLoad(infos); + parentScriptPack.add(daScript); + daScript.set("scriptInfo", infos); + daScript.load(); + + return infos; + } + + @:dox(hide) public static inline function shouldLoadBefore(node:Access):Bool + return node.getAtt("loadBefore") != "false"; +} + typedef AnimData = { var name:String; var anim:String; diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 328a7d82..12582162 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -714,7 +714,8 @@ class Charter extends UIState { } for (group in [notesGroup, localEventsGroup, globalEventsGroup]) { - cast(group, FlxTypedGroup).forEach(function(s) { + var group:FlxTypedGroup = cast group; + group.forEach(function(s) { s.selected = false; if (gridActionType == NONE) { if (s is CharterNote) { @@ -779,21 +780,27 @@ class Charter extends UIState { selectionBox.bHeight = Std.int(Math.abs(mousePos.y - dragStartPos.y)); } else { if (FlxG.keys.pressed.SHIFT) { - for (group in [notesGroup, localEventsGroup, globalEventsGroup]) - for(n in cast(group, FlxTypedGroup)) + for (group in [notesGroup, localEventsGroup, globalEventsGroup]) { + var group:FlxTypedGroup = cast group; + for(n in group) if (n.handleSelection(selectionBox) && selection.contains(n)) selection.remove(n); + } } else if (FlxG.keys.pressed.CONTROL) { - for (group in [notesGroup, localEventsGroup, globalEventsGroup]) - for(n in cast(group, FlxTypedGroup)) + for (group in [notesGroup, localEventsGroup, globalEventsGroup]) { + var group:FlxTypedGroup = cast group; + for(n in group) if (n.handleSelection(selectionBox) && !selection.contains(n)) selection.push(n); + } } else { selection = []; - for (group in [notesGroup, localEventsGroup, globalEventsGroup]) - for(n in cast(group, FlxTypedGroup)) + for (group in [notesGroup, localEventsGroup, globalEventsGroup]) { + var group:FlxTypedGroup = cast group; + for(n in group) if (n.handleSelection(selectionBox)) selection.push(n); + } } selection = __fixSelection(selection); @@ -849,8 +856,14 @@ class Charter extends UIState { changePoint.put(); } - if (s is CharterNote) cast(s, CharterNote).snappedToStrumline = true; - if (s is UISprite) cast(s, UISprite).cursor = CLICK; + if (s is CharterNote) { + var s:CharterNote = cast s; + s.snappedToStrumline = true; + } + if (s is UISprite) { + var s:UISprite = cast s; + s.cursor = CLICK; + } } if (!(verticalChange == 0 && horizontalChange == 0)) { notesGroup.sortNotes(); localEventsGroup.sortEvents(); globalEventsGroup.sortEvents(); @@ -1061,9 +1074,9 @@ class Charter extends UIState { if (selection.length <= 0) return []; notesGroup.autoSort = false; - for (objects in [notesGroup, localEventsGroup, globalEventsGroup]) { - var group = cast(objects, FlxTypedGroup); - var member = 0; + for (group in [notesGroup, localEventsGroup, globalEventsGroup]) { + var group:FlxTypedGroup = cast group; + var member:Int = 0; while(member < group.members.length) { var s = group.members[member]; if (selection.contains(s)) @@ -1433,7 +1446,7 @@ class Charter extends UIState { var note:CharterNote = cast s; CNote(note.step - minStep, note.id, note.strumLineID, note.susLength, note.type); } else if (s is CharterEvent) { - var event = cast(s,CharterEvent); + var event:CharterEvent = cast s; CEvent(event.step - minStep, [for (event in event.events) Reflect.copy(event)], event.global); } ]; @@ -2031,9 +2044,9 @@ typedef SelectionDragChange = { public inline function loop(onNote:CharterNote->Void, ?onEvent:CharterEvent->Void, ?draggableOnly:Bool = true) { for (s in this) { if (s is CharterNote && onNote != null && (draggableOnly ? s.draggable: true)) - onNote(cast(s, CharterNote)); + onNote(cast s); else if (s is CharterEvent && onEvent != null && (draggableOnly ? s.draggable: true)) - onEvent(cast(s, CharterEvent)); + onEvent(cast s); } } } diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 8fefb087..a93c90a0 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -69,7 +69,7 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { generateDefaultIcon(event.name); case "Camera Movement": // custom icon for camera movement - var state = cast(FlxG.state, Charter); + var state:Charter = cast FlxG.state; if (event.params != null && event.params[0] != null && event.params[0] >= 0 && event.params[0] < state.strumLines.length) { // camera movement, use health icon var icon = Character.getIconFromCharName(state.strumLines.members[event.params[0]].strumLine.characters[0]); diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 586907a3..31c7eae3 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -33,7 +33,7 @@ class CharterNoteGroup extends FlxTypedGroup { noteFunc(__loopSprite); } for(c in Charter.selection.copy()) - if (c != null && c is CharterNote) noteFunc(cast (c, CharterNote)); + if (c != null && c is CharterNote) noteFunc(cast c); __currentlyLooping = oldCur; } diff --git a/source/funkin/editors/charter/CharterNoteHoverer.hx b/source/funkin/editors/charter/CharterNoteHoverer.hx index 3341e8d0..729110bb 100644 --- a/source/funkin/editors/charter/CharterNoteHoverer.hx +++ b/source/funkin/editors/charter/CharterNoteHoverer.hx @@ -47,7 +47,7 @@ class CharterNoteHoverer extends CharterNote { for (s in Charter.selection) { if (s != null && s.draggable && s is CharterNote) { - var draggingNote:CharterNote = cast(s, CharterNote); + var draggingNote:CharterNote = cast s; y = (draggingNote.step + verticalChange); if (!FlxG.keys.pressed.SHIFT) y -= ((draggingNote.step + verticalChange) diff --git a/source/funkin/editors/ui/UIFileExplorer.hx b/source/funkin/editors/ui/UIFileExplorer.hx index 85294dfa..1e0154c7 100644 --- a/source/funkin/editors/ui/UIFileExplorer.hx +++ b/source/funkin/editors/ui/UIFileExplorer.hx @@ -55,8 +55,10 @@ class UIFileExplorer extends UISliceSprite { if (uiElement != null) { uiElement.alpha = alpha; - if (uiElement is UIButton) - cast(uiElement, UIButton).selectable = selectable; + if (uiElement is UIButton) { + var uiElement:UIButton = cast uiElement; + uiElement.selectable = selectable; + } } } diff --git a/source/funkin/editors/ui/UITopMenu.hx b/source/funkin/editors/ui/UITopMenu.hx index 7e4120a2..d705da4e 100644 --- a/source/funkin/editors/ui/UITopMenu.hx +++ b/source/funkin/editors/ui/UITopMenu.hx @@ -21,9 +21,12 @@ class UITopMenu extends UISliceSprite { public override function update(elapsed:Float) { anyMenuOpened = false; - for(c in members) if (cast(c, UITopMenuButton).curMenu.contextMenuOpened()) { - anyMenuOpened = true; - break; + for(c in members) { + var c:UITopMenuButton = cast c; + if (c.curMenu.contextMenuOpened()) { + anyMenuOpened = true; + break; + } } super.update(elapsed); diff --git a/source/funkin/editors/ui/UIUtil.hx b/source/funkin/editors/ui/UIUtil.hx index 4036184f..77ec0e4e 100644 --- a/source/funkin/editors/ui/UIUtil.hx +++ b/source/funkin/editors/ui/UIUtil.hx @@ -7,7 +7,7 @@ import funkin.editors.ui.UIContextMenu.UIContextMenuOption; @:access(flixel.FlxSprite) class UIUtil { public static function follow(spr:FlxSprite, target:FlxSprite, x:Float = 0, y:Float = 0) { - spr._cameras = target is UISprite ? cast(target, UISprite).__lastDrawCameras : target.cameras; + spr._cameras = target is UISprite ? ({var _:UISprite = cast target;_;}).__lastDrawCameras : target.cameras; spr.x = target.x + x; spr.y = target.y + y; spr.scrollFactor.set(target.scrollFactor.x, target.scrollFactor.y); diff --git a/source/funkin/game/Character.hx b/source/funkin/game/Character.hx index 8e4361c5..9f3834e7 100644 --- a/source/funkin/game/Character.hx +++ b/source/funkin/game/Character.hx @@ -10,6 +10,9 @@ import flixel.util.FlxColor; import funkin.backend.FunkinSprite; import funkin.backend.scripting.DummyScript; import funkin.backend.scripting.Script; +import funkin.backend.scripting.ScriptPack; +import funkin.backend.scripting.events.CharacterNodeEvent; +import funkin.backend.scripting.events.CharacterXMLEvent; import funkin.backend.scripting.events.DanceEvent; import funkin.backend.scripting.events.DirectionAnimEvent; import funkin.backend.scripting.events.PlayAnimContext; @@ -48,8 +51,13 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset public var globalOffset:FlxPoint = FlxPoint.get(0, 0); public var extraOffset:FlxPoint = FlxPoint.get(0, 0); - public var script:Script; public var xml:Access; + public var scripts:ScriptPack; + public var xmlImportedScripts:Array = []; + public var script(default, set):Script; + + public function prepareInfos(node:Access) + return XMLImportedScriptInfo.prepareInfos(node, scripts, (infos) -> xmlImportedScripts.push(infos)); public var idleSuffix:String = ""; public var stunned(default, set):Bool = false; @@ -76,16 +84,15 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset script = Script.create(Paths.script(Path.withoutExtension(Paths.xml('characters/$curCharacter')), null, true)); else script = new DummyScript(curCharacter); - script.setParent(this); script.load(); buildCharacter(xml); - script.call("create"); + scripts.call("create"); if (script == null) script = new DummyScript(curCharacter); - script.call("postCreate"); + scripts.call("postCreate"); } @:noCompletion var __swappedLeftRightAnims:Bool = false; @@ -119,7 +126,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset override function update(elapsed:Float) { super.update(elapsed); - script.call("update", [elapsed]); + scripts.call("update", [elapsed]); if (stunned) { __stunnedTime += elapsed; if (__stunnedTime > 5 / 60) @@ -138,7 +145,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset if(debugMode) return; var event = EventManager.get(DanceEvent).recycle(danced); - script.call("onDance", [event]); + scripts.call("onDance", [event]); if (event.cancelled) return; if (isDanceLeftDanceRight) @@ -168,14 +175,14 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset */ public var danceOnBeat:Bool = true; public override function beatHit(curBeat:Int) { - script.call("beatHit", [curBeat]); + scripts.call("beatHit", [curBeat]); if (danceOnBeat && (curBeat + beatOffset) % beatInterval == 0 && !__lockAnimThisFrame) tryDance(); } public override function stepHit(curStep:Int) - script.call("stepHit", [curStep]); + scripts.call("stepHit", [curStep]); @:noCompletion var __reverseDrawProcedure:Bool = false; public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect { @@ -310,7 +317,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset public override function playAnim(AnimName:String, ?Force:Bool, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0) { var event = EventManager.get(PlayAnimEvent).recycle(AnimName, Force, Reversed, Frame, Context); - script.call("onPlayAnim", [event]); + scripts.call("onPlayAnim", [event]); if (event.cancelled) return; super.playAnim(event.animName, event.force, event.context, event.reverse, event.startingFrame); @@ -325,16 +332,16 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset var event = EventManager.get(PointEvent).recycle( midpoint.x + (isPlayer ? -100 : 150) + globalOffset.x + cameraOffset.x, midpoint.y - 100 + globalOffset.y + cameraOffset.y); - script.call("onGetCamPos", [event]); + scripts.call("onGetCamPos", [event]); midpoint.put(); return new FlxPoint(event.x, event.y); } public override function destroy() { - if(script != null) { - script.call('destroy'); - script.destroy(); + if(scripts != null) { + scripts.call('destroy'); + scripts.destroy(); } super.destroy(); @@ -378,9 +385,18 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset } public inline function buildCharacter(xml:Access) { - this.xml = xml; // Modders wassup :D + for(node in xml.elements) + switch(node.name) { + case "use-extension" | "extension" | "ext": + if (!XMLImportedScriptInfo.shouldLoadBefore(node)) continue; + prepareInfos(node); + } + + xml = scripts.event("onCharacterXMLParsed", EventManager.get(CharacterXMLEvent).recycle(this, xml)).xml; + sprite = curCharacter; spriteAnimType = BEAT; + this.xml = xml; // Modders wassup :D if (xml.x.exists("isPlayer")) playerOffsets = (xml.x.get("isPlayer") == "true"); if (xml.x.exists("x")) globalOffset.x = Std.parseFloat(xml.x.get("x")); @@ -404,9 +420,19 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset if (hasInterval) beatInterval = Std.parseInt(xml.x.get("interval")); loadSprite(Paths.image('characters/$sprite')); + for(node in xml.elements) { + switch(node.name) { + case "anim": + XMLUtil.addXMLAnimation(this, node); + case "use-extension" | "extension" | "ext": + if (XMLImportedScriptInfo.shouldLoadBefore(node)) continue; + prepareInfos(node); + default: + // nothing + } - for (anim in xml.nodes.anim) - XMLUtil.addXMLAnimation(this, anim); + scripts.event("onCharacterNodeParsed", EventManager.get(CharacterNodeEvent).recycle(this, node, node.name)); + } for (attribute in xml.x.attributes()) if (!characterProperties.contains(attribute)) @@ -414,6 +440,14 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset fixChar(__switchAnims, !hasInterval); dance(); + + for (info in xmlImportedScripts) if (info.shortLived) { + var script = info.getScript(); + if (script == null) continue; + + scripts.remove(script); + script.destroy(); + } } public static var characterProperties:Array = [ @@ -497,6 +531,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset return stunned = b; } + // ---- Backwards compat ---- // Interval at which the character will dance (higher number = slower dance) @:noCompletion public var danceInterval(get, set):Int; @:noCompletion private function set_danceInterval(v:Int) @@ -504,13 +539,29 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset @:noCompletion private function get_danceInterval() return beatInterval; + private function set_script(script:Script):Script { + if (scripts == null) (scripts = new ScriptPack("Character")).setParent(this); + + var lastIndex = scripts.scripts.indexOf(this.script); + if(lastIndex >= 0) { + if(script == null) // last != null && new == null + scripts.scripts.splice(lastIndex, 1); + else // last != null && new != null + scripts.scripts[lastIndex] = script; + } else if(script != null) // last == null + scripts.insert(0, script); + + return this.script = script; + } + // ---- end of Backwards compat ---- + public static var FALLBACK_CHARACTER:String = "bf"; public static var FALLBACK_DEAD_CHARACTER:String = "bf-dead"; public static function getXMLFromCharName(character:OneOfTwo):Access { var char:Character = null; if (character is Character) { - char = cast(character, Character); + char = cast character; character = char.curCharacter; } diff --git a/source/funkin/game/Note.hx b/source/funkin/game/Note.hx index e9c1bb35..5cc35051 100644 --- a/source/funkin/game/Note.hx +++ b/source/funkin/game/Note.hx @@ -213,7 +213,7 @@ class Note extends FlxSprite public var strumRelativePos:Bool = true; override function drawComplex(camera:FlxCamera) { - var downscrollCam = (camera is HudCamera ? cast(camera, HudCamera).downscroll : false); + var downscrollCam = (camera is HudCamera ? ({var _:HudCamera=cast camera;_;}).downscroll : false); flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0)); if (downscrollCam) { frameOffset.y += __notePosFrameOffset.y * 2; diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 036f4a3a..f3962944 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -160,6 +160,11 @@ class PlayState extends MusicBeatState * Boyfriend character */ public var boyfriend(get, set):Character; + /** + * Boyfriend character + * Same as boyfriend, just shorter + **/ + public var bf(get, set):Character; /** * Strum line position @@ -870,12 +875,12 @@ class PlayState extends MusicBeatState Conductor.songPosition = 0; Conductor.songPosition -= Conductor.crochet * introLength - Conductor.songOffset; - var swagCounter:Int = 0; - - startTimer = new FlxTimer().start(Conductor.crochet / 1000, function(tmr:FlxTimer) - { - countdown(swagCounter++); - }, introLength); + if(introLength > 0) { + var swagCounter:Int = 0; + startTimer = new FlxTimer().start(Conductor.crochet / 1000, (tmr:FlxTimer) -> { + countdown(swagCounter++); + }, introLength); + } scripts.call("onPostStartCountdown"); } @@ -1055,7 +1060,7 @@ class PlayState extends MusicBeatState vocals.pause(); } - if (!startTimer.finished) + if (startTimer != null && !startTimer.finished) startTimer.active = false; } @@ -1075,7 +1080,7 @@ class PlayState extends MusicBeatState resyncVocals(); } - if (!startTimer.finished) + if (startTimer != null && !startTimer.finished) startTimer.active = true; paused = false; @@ -1859,6 +1864,16 @@ class PlayState extends MusicBeatState strumLines.members[1].characters = [bf]; return bf; } + private function set_bf(bf:Character):Character { + if (strumLines != null && strumLines.members[1] != null) + strumLines.members[1].characters = [bf]; + return bf; + } + private function get_bf():Character { + if (strumLines != null && strumLines.members[1] != null) + return strumLines.members[1].characters[0]; + return null; + } private function get_dad():Character { if (strumLines != null && strumLines.members[0] != null) return strumLines.members[0].characters[0]; diff --git a/source/funkin/game/Stage.hx b/source/funkin/game/Stage.hx index 9e5ce76c..e3f0ad4c 100644 --- a/source/funkin/game/Stage.hx +++ b/source/funkin/game/Stage.hx @@ -3,6 +3,9 @@ package funkin.game; import flixel.util.typeLimit.OneOfTwo; import flixel.FlxState; import flixel.math.FlxPoint; +import haxe.xml.Access; +import funkin.backend.utils.XMLUtil.XMLImportedScriptInfo; +import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.scripting.DummyScript; import funkin.backend.scripting.Script; import funkin.backend.scripting.events.StageNodeEvent; @@ -43,6 +46,9 @@ class Stage extends FlxBasic implements IBeatReceiver { public function setStagesSprites(script:Script) for (k=>e in stageSprites) script.set(k, e); + public function prepareInfos(node:Access) + return XMLImportedScriptInfo.prepareInfos(node, PlayState.instance.scripts, (infos) -> xmlImportedScripts.push(infos)); + public function new(stage:String, ?state:FlxState, autoLoad:Bool = true) { super(); @@ -151,7 +157,7 @@ class Stage extends FlxBasic implements IBeatReceiver { PlayState.instance.add(PlayState.instance.comboGroup); PlayState.instance.comboGroup; case "use-extension" | "extension" | "ext": - if (__shouldLoadBefore(node) || XMLImportedScriptInfo.prepareInfos(node, this) == null) continue; + if (XMLImportedScriptInfo.shouldLoadBefore(node) || prepareInfos(node) == null) continue; null; default: null; } @@ -241,13 +247,10 @@ class Stage extends FlxBasic implements IBeatReceiver { @:dox(hide) private function __pushNcheckNode(array:Array, node:Access) { array.push(node); - if ((node.name == "use-extension" || node.name == "extension" || node.name == "ext") && __shouldLoadBefore(node)) - XMLImportedScriptInfo.prepareInfos(node, this); + if ((node.name == "use-extension" || node.name == "extension" || node.name == "ext") && XMLImportedScriptInfo.shouldLoadBefore(node)) + prepareInfos(node); } - @:dox(hide) private static inline function __shouldLoadBefore(node:Access):Bool - return node.getAtt("loadBefore") != "false"; - public function addCharPos(name:String, node:Access, ?nonXMLInfo:StageCharPosInfo):StageCharPos { var charPos = new StageCharPos(); charPos.visible = charPos.active = false; @@ -439,45 +442,4 @@ typedef OldCharInfo = { var alpha:Float; var zoomFactor:Float; var angle:Float; -} - -class XMLImportedScriptInfo { - public var path:String; - public var shortLived:Bool = false; - public var loadBefore:Bool = true; - public var importStageSprites:Bool = false; - - public function new(path:String) - this.path = path; - - public function getScript():Script - return PlayState.instance == null ? null : PlayState.instance.scripts.getByPath(path); - - public static function prepareInfos(node:Access, ?stage:Stage):XMLImportedScriptInfo { - if (!node.has.script || PlayState.instance == null) return null; - - var folder = node.getAtt("folder").getDefault("data/scripts/"); - if (!folder.endsWith("/")) folder += "/"; - - var path = Paths.script(folder + node.getAtt("script")); - var daScript = Script.create(path); - if (daScript is DummyScript) { - var msg = 'Script Extension at ${path} does not exist'; - if (stage != null) msg += ' through stage "${stage.stageName}"'; - Logs.trace(msg + ".", ERROR); - return null; - } - - var infos = new XMLImportedScriptInfo(daScript.path); - infos.shortLived = node.getAtt("isShortLived") == "true"; - infos.importStageSprites = node.getAtt("importStageSprites") == "true"; - @:privateAccess infos.loadBefore = Stage.__shouldLoadBefore(node); - - if (stage != null) stage.xmlImportedScripts.push(infos); - PlayState.instance.scripts.add(daScript); - daScript.set("scriptInfo", infos); - daScript.load(); - - return infos; - } } \ No newline at end of file diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx index 1ddc8999..d1b8fa1a 100644 --- a/source/funkin/game/StrumLine.hx +++ b/source/funkin/game/StrumLine.hx @@ -318,7 +318,7 @@ class StrumLine extends FlxTypedGroup { babyArrow.scrollSpeed = data.scrollSpeed; var event = EventManager.get(StrumCreationEvent).recycle(babyArrow, PlayState.instance.strumLines.members.indexOf(this), i, animPrefix); - event.__doAnimation = !MusicBeatState.skipTransIn; + event.__doAnimation = !MusicBeatState.skipTransIn && (PlayState.instance != null ? PlayState.instance.introLength > 0 : true); event = PlayState.instance.scripts.event("onStrumCreation", event); if (!event.cancelled) { diff --git a/source/funkin/menus/ModSwitchMenu.hx b/source/funkin/menus/ModSwitchMenu.hx index eb14ddcd..4746b565 100644 --- a/source/funkin/menus/ModSwitchMenu.hx +++ b/source/funkin/menus/ModSwitchMenu.hx @@ -2,6 +2,7 @@ package funkin.menus; #if MOD_SUPPORT import flixel.tweens.FlxTween; +import flixel.util.FlxColor; import funkin.backend.assets.ModsFolder; import haxe.io.Path; import sys.FileSystem; @@ -28,6 +29,8 @@ class ModSwitchMenu extends MusicBeatSubstate { alphabets = new FlxTypedGroup(); for(mod in mods) { var a = new Alphabet(0, 0, mod == null ? "DISABLE MODS" : mod, true); + if(mod == ModsFolder.currentModFolder) + a.color = FlxColor.LIME; a.isMenuItem = true; a.scrollFactor.set(); alphabets.add(a); diff --git a/source/funkin/menus/TitleState.hx b/source/funkin/menus/TitleState.hx index edf5dd26..e1245a1e 100644 --- a/source/funkin/menus/TitleState.hx +++ b/source/funkin/menus/TitleState.hx @@ -355,7 +355,7 @@ class IntroText { for(e in lines) { if (e is String) { var text = cast(e, String); - for(k=>e in state.curWacky) text = text.replace('{introText${k+1}', e); + for(k=>e in state.curWacky) text = text.replace('{introText${k+1}}', e); state.addMoreText(text); } else if (e is Dynamic) { var image:TitleStateImage = e; diff --git a/source/funkin/menus/credits/CreditsCodename.hx b/source/funkin/menus/credits/CreditsCodename.hx index 3e09c990..8ed343b6 100644 --- a/source/funkin/menus/credits/CreditsCodename.hx +++ b/source/funkin/menus/credits/CreditsCodename.hx @@ -11,9 +11,11 @@ using StringTools; class CreditsCodename extends funkin.options.OptionsScreen { public var error:Bool = false; public var author:String = "FNF-CNE-Devs"; + public var totalContributions:Int = 0; + public var mainDevCol:FlxColor = 0xFF9C35D5; public var minContrCol:FlxColor = 0xFFB4A7DA; - public var totalContributions:Int = 0; + public var contribFormats:Array = []; public override function new() { @@ -58,12 +60,17 @@ class CreditsCodename extends funkin.options.OptionsScreen { if(parent == null || parent.treeParent == null) return; var text:String = parent.treeParent.pathDesc.text; parent.treeParent.pathDesc.text = ""; - parent.treeParent.pathDesc.applyMarkup(text, [ + parent.treeParent.pathDesc.applyMarkup(text, contribFormats = [ new FlxTextFormatMarkerPair(new FlxTextFormat(mainDevCol), '*'), new FlxTextFormatMarkerPair(new FlxTextFormat(FlxColor.interpolate(minContrCol, mainDevCol, Options.contributors[curSelected].contributions / totalContributions)), '~') ]); } + override function close() { + super.close(); + for (frmt in contribFormats) parent.treeParent.pathDesc.removeFormat(frmt.format); + } + public function checkUpdate():Bool { var curTime:Float = Date.now().getTime(); if(Options.lastUpdated != null && curTime < Options.lastUpdated + 120000) return false; // Fuck you Github rate limits - Nex diff --git a/source/funkin/menus/ui/Alphabet.hx b/source/funkin/menus/ui/Alphabet.hx index 663fa1b1..dfc86584 100644 --- a/source/funkin/menus/ui/Alphabet.hx +++ b/source/funkin/menus/ui/Alphabet.hx @@ -41,7 +41,7 @@ class Alphabet extends FlxSpriteGroup private override function set_color(c:Int):Int { for(e in group.members) { if (e is AlphaCharacter) { - var char = cast(e, AlphaCharacter); + var char:AlphaCharacter = cast e; char.setColor(c, isBold); } }