diff --git a/source/Main.hx b/source/Main.hx index 5043393f1..006b54e18 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -13,100 +13,101 @@ import openfl.net.NetStream; class Main extends Sprite { - var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels depending on your zoom). - var gameHeight:Int = 720; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom). - var initialState:Class = funkin.InitState; // The FlxState the game starts with. - var zoom:Float = -1; // If -1, zoom is automatically calculated to fit the window dimensions. - #if web - var framerate:Int = 60; // How many frames per second the game should run at. - #else - // TODO: This should probably be in the options menu? - var framerate:Int = 144; // How many frames per second the game should run at. - #end - var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode. - var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets + var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels depending on your zoom). + var gameHeight:Int = 720; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom). + var initialState:Class = funkin.InitState; // The FlxState the game starts with. + var zoom:Float = -1; // If -1, zoom is automatically calculated to fit the window dimensions. + #if web + var framerate:Int = 60; // How many frames per second the game should run at. + #else + // TODO: This should probably be in the options menu? + var framerate:Int = 144; // How many frames per second the game should run at. + #end + var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode. + var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets - // You can pretty much ignore everything from here on - your code should go in your states. + // You can pretty much ignore everything from here on - your code should go in your states. - public static function main():Void - { - Lib.current.addChild(new Main()); - } + public static function main():Void + { + Lib.current.addChild(new Main()); + } - public function new() - { - super(); + public function new() + { + super(); - // TODO: Replace this with loadEnabledMods(). - funkin.modding.PolymodHandler.loadAllMods(); + // TODO: Replace this with loadEnabledMods(). + funkin.modding.PolymodHandler.loadAllMods(); - if (stage != null) - { - init(); - } - else - { - addEventListener(Event.ADDED_TO_STAGE, init); - } - } + if (stage != null) + { + init(); + } + else + { + addEventListener(Event.ADDED_TO_STAGE, init); + } + } - private function init(?E:Event):Void - { - if (hasEventListener(Event.ADDED_TO_STAGE)) - { - removeEventListener(Event.ADDED_TO_STAGE, init); - } + function init(?event:Event):Void + { + if (hasEventListener(Event.ADDED_TO_STAGE)) + { + removeEventListener(Event.ADDED_TO_STAGE, init); + } - setupGame(); - } + setupGame(); + } - var video:Video; - var netStream:NetStream; - private var overlay:Sprite; + var video:Video; + var netStream:NetStream; + var overlay:Sprite; - public static var fpsCounter:FPS; - public static var memoryCounter:MemoryCounter; + public static var fpsCounter:FPS; + public static var memoryCounter:MemoryCounter; - private function setupGame():Void - { - /** - * The `zoom` argument of FlxGame was removed in the dev branch of Flixel, - * since it was considered confusing and unintuitive. - * If you want to change how the game scales when you resize the window, - * you can use `FlxG.scaleMode`. - * -Eric - */ + function setupGame():Void + { + /** + * The `zoom` argument of FlxGame was removed in the dev branch of Flixel, + * since it was considered confusing and unintuitive. + * If you want to change how the game scales when you resize the window, + * you can use `FlxG.scaleMode`. + * -Eric + */ - #if !debug - /** - * Someone was like "hey let's make a state that only runs code on debug builds" - * then put essential initialization code in it. - * The easiest fix is to make it run in all builds. - * -Eric - */ - // initialState = funkin.TitleState; - #end + #if !debug + /** + * Someone was like "hey let's make a state that only runs code on debug builds" + * then put essential initialization code in it. + * The easiest fix is to make it run in all builds. + * -Eric + */ + // TODO: Fix this properly. + // initialState = funkin.TitleState; + #end - initHaxeUI(); + initHaxeUI(); - addChild(new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen)); + addChild(new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen)); - #if debug - fpsCounter = new FPS(10, 3, 0xFFFFFF); - addChild(fpsCounter); - #if !html5 - memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF); - addChild(memoryCounter); - #end - #end - } + #if debug + fpsCounter = new FPS(10, 3, 0xFFFFFF); + addChild(fpsCounter); + #if !html5 + memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF); + addChild(memoryCounter); + #end + #end + } - function initHaxeUI() - { - // Calling this before any HaxeUI components get used is important: - // - It initializes the theme styles. - // - It scans the class path and registers any HaxeUI components. - Toolkit.init(); - Toolkit.theme = "dark"; // don't be cringe - } + function initHaxeUI():Void + { + // Calling this before any HaxeUI components get used is important: + // - It initializes the theme styles. + // - It scans the class path and registers any HaxeUI components. + Toolkit.init(); + Toolkit.theme = 'dark'; // don't be cringe + } } diff --git a/source/Preloader.hx b/source/Preloader.hx index 6d6240592..3603d1a16 100644 --- a/source/Preloader.hx +++ b/source/Preloader.hx @@ -12,47 +12,47 @@ import openfl.display.Sprite; class Preloader extends FlxBasePreloader { - public function new(MinDisplayTime:Float = 0, ?AllowedURLs:Array) - { - super(MinDisplayTime, AllowedURLs); - } + public function new(MinDisplayTime:Float = 0, ?AllowedURLs:Array) + { + super(MinDisplayTime, AllowedURLs); + } - var logo:Sprite; + var logo:Sprite; - override function create():Void - { - this._width = Lib.current.stage.stageWidth; - this._height = Lib.current.stage.stageHeight; + override function create():Void + { + this._width = Lib.current.stage.stageWidth; + this._height = Lib.current.stage.stageHeight; - var ratio:Float = this._width / 2560; // This allows us to scale assets depending on the size of the screen. + var ratio:Float = this._width / 2560; // This allows us to scale assets depending on the size of the screen. - logo = new Sprite(); - logo.addChild(new Bitmap(new LogoImage(0, 0))); // Sets the graphic of the sprite to a Bitmap object, which uses our embedded BitmapData class. - logo.scaleX = logo.scaleY = ratio; - logo.x = ((this._width) / 2) - ((logo.width) / 2); - logo.y = (this._height / 2) - ((logo.height) / 2); - addChild(logo); // Adds the graphic to the NMEPreloader's buffer. + logo = new Sprite(); + logo.addChild(new Bitmap(new LogoImage(0, 0))); // Sets the graphic of the sprite to a Bitmap object, which uses our embedded BitmapData class. + logo.scaleX = logo.scaleY = ratio; + logo.x = ((this._width) / 2) - ((logo.width) / 2); + logo.y = (this._height / 2) - ((logo.height) / 2); + addChild(logo); // Adds the graphic to the NMEPreloader's buffer. - super.create(); - } + super.create(); + } - override function update(Percent:Float):Void - { - if (Percent < 69) - { - logo.scaleX += Percent / 1920; - logo.scaleY += Percent / 1920; - logo.x -= Percent * 0.6; - logo.y -= Percent / 2; - } - else - { - logo.scaleX = this._width / 1280; - logo.scaleY = this._width / 1280; - logo.x = ((this._width) / 2) - ((logo.width) / 2); - logo.y = (this._height / 2) - ((logo.height) / 2); - } + override function update(Percent:Float):Void + { + if (Percent < 69) + { + logo.scaleX += Percent / 1920; + logo.scaleY += Percent / 1920; + logo.x -= Percent * 0.6; + logo.y -= Percent / 2; + } + else + { + logo.scaleX = this._width / 1280; + logo.scaleY = this._width / 1280; + logo.x = ((this._width) / 2) - ((logo.width) / 2); + logo.y = (this._height / 2) - ((logo.height) / 2); + } - super.update(Percent); - } + super.update(Percent); + } } diff --git a/source/funkin/Alphabet.hx b/source/funkin/Alphabet.hx index 85861720a..adf97933a 100644 --- a/source/funkin/Alphabet.hx +++ b/source/funkin/Alphabet.hx @@ -12,296 +12,295 @@ import flixel.util.FlxTimer; // @:deprecated("Use ui.AtlasText instead") class Alphabet extends FlxSpriteGroup { - public var delay:Float = 0.05; - public var paused:Bool = false; + public var delay:Float = 0.05; + public var paused:Bool = false; - // for menu shit - public var targetY:Float = 0; - public var isMenuItem:Bool = false; + // for menu shit + public var targetY:Float = 0; + public var isMenuItem:Bool = false; - public var text:String = ""; + public var text:String = ""; - var _finalText:String = ""; - var _curText:String = ""; + var _finalText:String = ""; + var _curText:String = ""; - public var widthOfWords:Float = FlxG.width; + public var widthOfWords:Float = FlxG.width; - var yMulti:Float = 1; + var yMulti:Float = 1; - // custom shit - // amp, backslash, question mark, apostrophy, comma, angry faic, period - var lastSprite:AlphaCharacter; - var xPosResetted:Bool = false; - var lastWasSpace:Bool = false; + // custom shit + // amp, backslash, question mark, apostrophy, comma, angry faic, period + var lastSprite:AlphaCharacter; + var xPosResetted:Bool = false; + var lastWasSpace:Bool = false; - var splitWords:Array = []; + var splitWords:Array = []; - var isBold:Bool = false; + var isBold:Bool = false; - public function new(x:Float = 0.0, y:Float = 0.0, text:String = "", ?bold:Bool = false, typed:Bool = false) - { - super(x, y); + public function new(x:Float = 0.0, y:Float = 0.0, text:String = "", ?bold:Bool = false, typed:Bool = false) + { + super(x, y); - _finalText = text; - this.text = text; - isBold = bold; + _finalText = text; + this.text = text; + isBold = bold; - if (text != "") - { - if (typed) - { - startTypedText(); - } - else - { - addText(); - } - } - } + if (text != "") + { + if (typed) + { + startTypedText(); + } + else + { + addText(); + } + } + } - public function addText() - { - doSplitWords(); + public function addText() + { + doSplitWords(); - var xPos:Float = 0; - for (character in splitWords) - { - // if (character.fastCodeAt() == " ") - // { - // } + var xPos:Float = 0; + for (character in splitWords) + { + // if (character.fastCodeAt() == " ") + // { + // } - if (character == " " || character == "-") - { - lastWasSpace = true; - } + if (character == " " || character == "-") + { + lastWasSpace = true; + } - if (AlphaCharacter.alphabet.indexOf(character.toLowerCase()) != -1) - // if (AlphaCharacter.alphabet.contains(character.toLowerCase())) - { - if (lastSprite != null) - { - xPos = lastSprite.x + lastSprite.width; - } + if (AlphaCharacter.alphabet.indexOf(character.toLowerCase()) != -1) // if (AlphaCharacter.alphabet.contains(character.toLowerCase())) + { + if (lastSprite != null) + { + xPos = lastSprite.x + lastSprite.width; + } - if (lastWasSpace) - { - xPos += 40; - lastWasSpace = false; - } + if (lastWasSpace) + { + xPos += 40; + lastWasSpace = false; + } - // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); - var letter:AlphaCharacter = new AlphaCharacter(xPos, 0); + // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); + var letter:AlphaCharacter = new AlphaCharacter(xPos, 0); - if (isBold) - letter.createBold(character); - else - { - letter.createLetter(character); - } + if (isBold) letter.createBold(character); + else + { + letter.createLetter(character); + } - add(letter); + add(letter); - lastSprite = letter; - } + lastSprite = letter; + } - // loopNum += 1; - } - } + // loopNum += 1; + } + } - function doSplitWords():Void - { - splitWords = _finalText.split(""); - } + function doSplitWords():Void + { + splitWords = _finalText.split(""); + } - public var personTalking:String = 'gf'; + public var personTalking:String = 'gf'; - public function startTypedText():Void - { - _finalText = text; - doSplitWords(); + public function startTypedText():Void + { + _finalText = text; + doSplitWords(); - // trace(arrayShit); + // trace(arrayShit); - var loopNum:Int = 0; + var loopNum:Int = 0; - var xPos:Float = 0; - var curRow:Int = 0; + var xPos:Float = 0; + var curRow:Int = 0; - new FlxTimer().start(0.05, function(tmr:FlxTimer) - { - // trace(_finalText.fastCodeAt(loopNum) + " " + _finalText.charAt(loopNum)); - if (_finalText.fastCodeAt(loopNum) == "\n".code) - { - yMulti += 1; - xPosResetted = true; - xPos = 0; - curRow += 1; - } + new FlxTimer().start(0.05, function(tmr:FlxTimer) + { + // trace(_finalText.fastCodeAt(loopNum) + " " + _finalText.charAt(loopNum)); + if (_finalText.fastCodeAt(loopNum) == "\n".code) + { + yMulti += 1; + xPosResetted = true; + xPos = 0; + curRow += 1; + } - if (splitWords[loopNum] == " ") - { - lastWasSpace = true; - } + if (splitWords[loopNum] == " ") + { + lastWasSpace = true; + } - #if (haxe >= "4.0.0") - var isNumber:Bool = AlphaCharacter.numbers.contains(splitWords[loopNum]); - var isSymbol:Bool = AlphaCharacter.symbols.contains(splitWords[loopNum]); - #else - var isNumber:Bool = AlphaCharacter.numbers.indexOf(splitWords[loopNum]) != -1; - var isSymbol:Bool = AlphaCharacter.symbols.indexOf(splitWords[loopNum]) != -1; - #end + #if (haxe >= "4.0.0") + var isNumber:Bool = AlphaCharacter.numbers.contains(splitWords[loopNum]); + var isSymbol:Bool = AlphaCharacter.symbols.contains(splitWords[loopNum]); + #else + var isNumber:Bool = AlphaCharacter.numbers.indexOf(splitWords[loopNum]) != -1; + var isSymbol:Bool = AlphaCharacter.symbols.indexOf(splitWords[loopNum]) != -1; + #end - if (AlphaCharacter.alphabet.indexOf(splitWords[loopNum].toLowerCase()) != -1 || isNumber || isSymbol) - // if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol) + if (AlphaCharacter.alphabet.indexOf(splitWords[loopNum].toLowerCase()) != -1 + || isNumber + || isSymbol) // if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol) - { - if (lastSprite != null && !xPosResetted) - { - lastSprite.updateHitbox(); - xPos += lastSprite.width + 3; - // if (isBold) - // xPos -= 80; - } - else - { - xPosResetted = false; - } + { + if (lastSprite != null && !xPosResetted) + { + lastSprite.updateHitbox(); + xPos += lastSprite.width + 3; + // if (isBold) + // xPos -= 80; + } + else + { + xPosResetted = false; + } - if (lastWasSpace) - { - xPos += 20; - lastWasSpace = false; - } - // trace(_finalText.fastCodeAt(loopNum) + " " + _finalText.charAt(loopNum)); + if (lastWasSpace) + { + xPos += 20; + lastWasSpace = false; + } + // trace(_finalText.fastCodeAt(loopNum) + " " + _finalText.charAt(loopNum)); - // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); - var letter:AlphaCharacter = new AlphaCharacter(xPos, 55 * yMulti); - letter.row = curRow; - if (isBold) - { - letter.createBold(splitWords[loopNum]); - } - else - { - if (isNumber) - { - letter.createNumber(splitWords[loopNum]); - } - else if (isSymbol) - { - letter.createSymbol(splitWords[loopNum]); - } - else - { - letter.createLetter(splitWords[loopNum]); - } + // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); + var letter:AlphaCharacter = new AlphaCharacter(xPos, 55 * yMulti); + letter.row = curRow; + if (isBold) + { + letter.createBold(splitWords[loopNum]); + } + else + { + if (isNumber) + { + letter.createNumber(splitWords[loopNum]); + } + else if (isSymbol) + { + letter.createSymbol(splitWords[loopNum]); + } + else + { + letter.createLetter(splitWords[loopNum]); + } - letter.x += 90; - } + letter.x += 90; + } - if (FlxG.random.bool(40)) - { - var daSound:String = "GF_"; - FlxG.sound.play(Paths.soundRandom(daSound, 1, 4)); - } + if (FlxG.random.bool(40)) + { + var daSound:String = "GF_"; + FlxG.sound.play(Paths.soundRandom(daSound, 1, 4)); + } - add(letter); + add(letter); - lastSprite = letter; - } + lastSprite = letter; + } - loopNum += 1; + loopNum += 1; - tmr.time = FlxG.random.float(0.04, 0.09); - }, splitWords.length); - } + tmr.time = FlxG.random.float(0.04, 0.09); + }, splitWords.length); + } - override function update(elapsed:Float) - { - if (isMenuItem) - { - var scaledY = FlxMath.remapToRange(targetY, 0, 1, 0, 1.3); + override function update(elapsed:Float) + { + if (isMenuItem) + { + var scaledY = FlxMath.remapToRange(targetY, 0, 1, 0, 1.3); - y = CoolUtil.coolLerp(y, (scaledY * 120) + (FlxG.height * 0.48), 0.16); - x = CoolUtil.coolLerp(x, (targetY * 20) + 90, 0.16); - } + y = CoolUtil.coolLerp(y, (scaledY * 120) + (FlxG.height * 0.48), 0.16); + x = CoolUtil.coolLerp(x, (targetY * 20) + 90, 0.16); + } - super.update(elapsed); - } + super.update(elapsed); + } } class AlphaCharacter extends FlxSprite { - public static var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; + public static var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; - public static var numbers:String = "1234567890"; + public static var numbers:String = "1234567890"; - public static var symbols:String = "|~#$%()*+-:;<=>@[]^_.,'!?"; + public static var symbols:String = "|~#$%()*+-:;<=>@[]^_.,'!?"; - public var row:Int = 0; + public var row:Int = 0; - public function new(x:Float, y:Float) - { - super(x, y); - var tex = Paths.getSparrowAtlas('alphabet'); - frames = tex; + public function new(x:Float, y:Float) + { + super(x, y); + var tex = Paths.getSparrowAtlas('alphabet'); + frames = tex; - antialiasing = true; - } + antialiasing = true; + } - public function createBold(letter:String) - { - animation.addByPrefix(letter, letter.toUpperCase() + " bold", 24); - animation.play(letter); - updateHitbox(); - } + public function createBold(letter:String) + { + animation.addByPrefix(letter, letter.toUpperCase() + " bold", 24); + animation.play(letter); + updateHitbox(); + } - public function createLetter(letter:String):Void - { - var letterCase:String = "lowercase"; - if (letter.toLowerCase() != letter) - { - letterCase = 'capital'; - } + public function createLetter(letter:String):Void + { + var letterCase:String = "lowercase"; + if (letter.toLowerCase() != letter) + { + letterCase = 'capital'; + } - animation.addByPrefix(letter, letter + " " + letterCase, 24); - animation.play(letter); - updateHitbox(); + animation.addByPrefix(letter, letter + " " + letterCase, 24); + animation.play(letter); + updateHitbox(); - FlxG.log.add('the row' + row); + FlxG.log.add('the row' + row); - y = (110 - height); - y += row * 60; - } + y = (110 - height); + y += row * 60; + } - public function createNumber(letter:String):Void - { - animation.addByPrefix(letter, letter, 24); - animation.play(letter); + public function createNumber(letter:String):Void + { + animation.addByPrefix(letter, letter, 24); + animation.play(letter); - updateHitbox(); - } + updateHitbox(); + } - public function createSymbol(letter:String) - { - switch (letter) - { - case '.': - animation.addByPrefix(letter, 'period', 24); - animation.play(letter); - y += 50; - case "'": - animation.addByPrefix(letter, 'apostraphie', 24); - animation.play(letter); - y -= 0; - case "?": - animation.addByPrefix(letter, 'question mark', 24); - animation.play(letter); - case "!": - animation.addByPrefix(letter, 'exclamation point', 24); - animation.play(letter); - } + public function createSymbol(letter:String) + { + switch (letter) + { + case '.': + animation.addByPrefix(letter, 'period', 24); + animation.play(letter); + y += 50; + case "'": + animation.addByPrefix(letter, 'apostraphie', 24); + animation.play(letter); + y -= 0; + case "?": + animation.addByPrefix(letter, 'question mark', 24); + animation.play(letter); + case "!": + animation.addByPrefix(letter, 'exclamation point', 24); + animation.play(letter); + } - updateHitbox(); - } + updateHitbox(); + } } diff --git a/source/funkin/ButtonRemapSubstate.hx b/source/funkin/ButtonRemapSubstate.hx index 35c7a1476..376cc4d54 100644 --- a/source/funkin/ButtonRemapSubstate.hx +++ b/source/funkin/ButtonRemapSubstate.hx @@ -4,8 +4,8 @@ import flixel.FlxSubState; class ButtonRemapSubstate extends FlxSubState { - public function new() - { - super(); - } + public function new() + { + super(); + } } diff --git a/source/funkin/ComboCounter.hx b/source/funkin/ComboCounter.hx index 67b7a0fb3..ac8606691 100644 --- a/source/funkin/ComboCounter.hx +++ b/source/funkin/ComboCounter.hx @@ -7,136 +7,135 @@ import flixel.util.FlxTimer; class ComboCounter extends FlxTypedSpriteGroup { - var effectStuff:FlxSprite; + var effectStuff:FlxSprite; - var wasComboSetup:Bool = false; - var daCombo:Int = 0; + var wasComboSetup:Bool = false; + var daCombo:Int = 0; - var grpNumbers:FlxTypedGroup; + var grpNumbers:FlxTypedGroup; - var onScreenTime:Float = 0; + var onScreenTime:Float = 0; - public function new(x:Float, y:Float, daCombo:Int = 0) - { - super(x, y); + public function new(x:Float, y:Float, daCombo:Int = 0) + { + super(x, y); - this.daCombo = daCombo; + this.daCombo = daCombo; - effectStuff = new FlxSprite(0, 0); - effectStuff.frames = Paths.getSparrowAtlas('noteCombo'); - effectStuff.animation.addByPrefix('funny', 'NOTE COMBO animation', 24, false); - effectStuff.animation.play('funny'); - effectStuff.antialiasing = true; - effectStuff.animation.finishCallback = function(nameThing) - { - kill(); - }; - effectStuff.setGraphicSize(Std.int(effectStuff.width * 0.7)); - add(effectStuff); + effectStuff = new FlxSprite(0, 0); + effectStuff.frames = Paths.getSparrowAtlas('noteCombo'); + effectStuff.animation.addByPrefix('funny', 'NOTE COMBO animation', 24, false); + effectStuff.animation.play('funny'); + effectStuff.antialiasing = true; + effectStuff.animation.finishCallback = function(nameThing) + { + kill(); + }; + effectStuff.setGraphicSize(Std.int(effectStuff.width * 0.7)); + add(effectStuff); - grpNumbers = new FlxTypedGroup(); - // add(grpNumbers); - } + grpNumbers = new FlxTypedGroup(); + // add(grpNumbers); + } - public function forceFinish():Void - { - if (onScreenTime < 0.9) - { - new FlxTimer().start((Conductor.crochet / 1000) * 0.25, function(tmr) - { - forceFinish(); - }); - } - else - effectStuff.animation.play('funny', true, false, 18); - } + public function forceFinish():Void + { + if (onScreenTime < 0.9) + { + new FlxTimer().start((Conductor.crochet / 1000) * 0.25, function(tmr) + { + forceFinish(); + }); + } + else + effectStuff.animation.play('funny', true, false, 18); + } - override function update(elapsed:Float) - { - onScreenTime += elapsed; + override function update(elapsed:Float) + { + onScreenTime += elapsed; - if (effectStuff.animation.curAnim.curFrame == 17) - effectStuff.animation.pause(); + if (effectStuff.animation.curAnim.curFrame == 17) effectStuff.animation.pause(); - if (effectStuff.animation.curAnim.curFrame == 2 && !wasComboSetup) - { - setupCombo(daCombo); - } + if (effectStuff.animation.curAnim.curFrame == 2 && !wasComboSetup) + { + setupCombo(daCombo); + } - if (effectStuff.animation.curAnim.curFrame == 18) - { - grpNumbers.forEach(function(spr:ComboNumber) - { - spr.animation.reset(); - }); - } + if (effectStuff.animation.curAnim.curFrame == 18) + { + grpNumbers.forEach(function(spr:ComboNumber) + { + spr.animation.reset(); + }); + } - if (effectStuff.animation.curAnim.curFrame == 20) - { - grpNumbers.forEach(function(spr:ComboNumber) - { - spr.kill(); - }); - } + if (effectStuff.animation.curAnim.curFrame == 20) + { + grpNumbers.forEach(function(spr:ComboNumber) + { + spr.kill(); + }); + } - super.update(elapsed); - } + super.update(elapsed); + } - function setupCombo(daCombo:Int) - { - FlxG.sound.play(Paths.sound('comboSound')); + function setupCombo(daCombo:Int) + { + FlxG.sound.play(Paths.sound('comboSound')); - wasComboSetup = true; - var loopNum:Int = 0; + wasComboSetup = true; + var loopNum:Int = 0; - while (daCombo > 0) - { - var comboNumber:ComboNumber = new ComboNumber(450 - (100 * loopNum), 20 + 14 * loopNum, daCombo % 10); - comboNumber.setGraphicSize(Std.int(comboNumber.width * 0.7)); - grpNumbers.add(comboNumber); - add(comboNumber); + while (daCombo > 0) + { + var comboNumber:ComboNumber = new ComboNumber(450 - (100 * loopNum), 20 + 14 * loopNum, daCombo % 10); + comboNumber.setGraphicSize(Std.int(comboNumber.width * 0.7)); + grpNumbers.add(comboNumber); + add(comboNumber); - loopNum += 1; + loopNum += 1; - daCombo = Math.floor(daCombo / 10); - } + daCombo = Math.floor(daCombo / 10); + } - // var comboNumber:ComboNumber = new ComboNumber(420, 0, 0); + // var comboNumber:ComboNumber = new ComboNumber(420, 0, 0); - // add to both, in the group just for ez organize/accessing - // grpNumbers.add(comboNumber); - // add(comboNumber); + // add to both, in the group just for ez organize/accessing + // grpNumbers.add(comboNumber); + // add(comboNumber); - // var comboNumber2:ComboNumber = new ComboNumber(420 - 134, 44, 0); - // grpNumbers.add(comboNumber2); - // add(comboNumber2); - } + // var comboNumber2:ComboNumber = new ComboNumber(420 - 134, 44, 0); + // grpNumbers.add(comboNumber2); + // add(comboNumber2); + } } class ComboNumber extends FlxSprite { - public function new(x:Float, y:Float, digit:Int) - { - super(x - 20, y); + public function new(x:Float, y:Float, digit:Int) + { + super(x - 20, y); - var stringNum:String = Std.string(digit); - frames = Paths.getSparrowAtlas('noteComboNumbers'); - animation.addByPrefix(stringNum, stringNum, 24, false); - animation.play(stringNum); - antialiasing = true; - updateHitbox(); - } + var stringNum:String = Std.string(digit); + frames = Paths.getSparrowAtlas('noteComboNumbers'); + animation.addByPrefix(stringNum, stringNum, 24, false); + animation.play(stringNum); + antialiasing = true; + updateHitbox(); + } - var shiftedX:Bool = false; + var shiftedX:Bool = false; - override function update(elapsed:Float) - { - if (animation.curAnim.curFrame == 2 && !shiftedX) - { - shiftedX = true; - x += 20; - } + override function update(elapsed:Float) + { + if (animation.curAnim.curFrame == 2 && !shiftedX) + { + shiftedX = true; + x += 20; + } - super.update(elapsed); - } + super.update(elapsed); + } } diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 8fb057ae9..d1176fa03 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -18,12 +18,12 @@ class Conductor * The list of time changes in the song. * There should be at least one time change (at the beginning of the song) to define the BPM. */ - private static var timeChanges:Array = []; + static var timeChanges:Array = []; /** * The current time change. */ - private static var currentTimeChange:SongTimeChange; + static var currentTimeChange:SongTimeChange; /** * The current position in the song in milliseconds. @@ -38,11 +38,9 @@ class Conductor static function get_bpm():Float { - if (bpmOverride != null) - return bpmOverride; + if (bpmOverride != null) return bpmOverride; - if (currentTimeChange == null) - return 100; + if (currentTimeChange == null) return 100; return currentTimeChange.bpm; } @@ -76,8 +74,7 @@ class Conductor static function get_timeSignatureNumerator():Int { - if (currentTimeChange == null) - return 4; + if (currentTimeChange == null) return 4; return currentTimeChange.timeSignatureNum; } @@ -86,8 +83,7 @@ class Conductor static function get_timeSignatureDenominator():Int { - if (currentTimeChange == null) - return 4; + if (currentTimeChange == null) return 4; return currentTimeChange.timeSignatureDen; } @@ -131,22 +127,21 @@ class Conductor return timeSignatureNumerator * 4; } - private function new() {} + function new() {} public static function getLastBPMChange() { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } + var lastChange:BPMChangeEvent = + { + stepTime: 0, + songTime: 0, + bpm: 0 + } for (i in 0...Conductor.bpmChangeMap.length) { - if (Conductor.songPosition >= Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; + if (Conductor.songPosition >= Conductor.bpmChangeMap[i].songTime) lastChange = Conductor.bpmChangeMap[i]; - if (Conductor.songPosition < Conductor.bpmChangeMap[i].songTime) - break; + if (Conductor.songPosition < Conductor.bpmChangeMap[i].songTime) break; } return lastChange; } @@ -162,8 +157,7 @@ class Conductor */ public static function forceBPM(?bpm:Float = null) { - if (bpm != null) - trace('[CONDUCTOR] Forcing BPM to ' + bpm); + if (bpm != null) trace('[CONDUCTOR] Forcing BPM to ' + bpm); else trace('[CONDUCTOR] Resetting BPM to default'); Conductor.bpmOverride = bpm; @@ -178,8 +172,7 @@ class Conductor */ public static function update(songPosition:Float = null) { - if (songPosition == null) - songPosition = (FlxG.sound.music != null) ? FlxG.sound.music.time + Conductor.offset : 0.0; + if (songPosition == null) songPosition = (FlxG.sound.music != null) ? FlxG.sound.music.time + Conductor.offset : 0.0; var oldBeat = currentBeat; var oldStep = currentStep; @@ -190,11 +183,9 @@ class Conductor currentTimeChange = timeChanges[0]; for (i in 0...timeChanges.length) { - if (songPosition >= timeChanges[i].timeStamp) - currentTimeChange = timeChanges[i]; + if (songPosition >= timeChanges[i].timeStamp) currentTimeChange = timeChanges[i]; - if (songPosition < timeChanges[i].timeStamp) - break; + if (songPosition < timeChanges[i].timeStamp) break; } if (currentTimeChange == null && bpmOverride == null && FlxG.sound.music != null) @@ -216,11 +207,9 @@ class Conductor } // FlxSignals are really cool. - if (currentStep != oldStep) - stepHit.dispatch(); + if (currentStep != oldStep) stepHit.dispatch(); - if (currentBeat != oldBeat) - beatHit.dispatch(); + if (currentBeat != oldBeat) beatHit.dispatch(); } @:deprecated // Switch to TimeChanges instead. @@ -236,11 +225,12 @@ class Conductor if (SongLoad.getSong()[i].changeBPM && SongLoad.getSong()[i].bpm != curBPM) { curBPM = SongLoad.getSong()[i].bpm; - var event:BPMChangeEvent = { - stepTime: totalSteps, - songTime: totalPos, - bpm: curBPM - }; + var event:BPMChangeEvent = + { + stepTime: totalSteps, + songTime: totalPos, + bpm: curBPM + }; bpmChangeMap.push(event); } diff --git a/source/funkin/Controls.hx b/source/funkin/Controls.hx index ef649f6c6..9fc2610ba 100644 --- a/source/funkin/Controls.hx +++ b/source/funkin/Controls.hx @@ -28,72 +28,72 @@ import lime.ui.Haptic; */ enum Control { - // List notes in order from left to right on gameplay screen. - NOTE_LEFT; - NOTE_DOWN; - NOTE_UP; - NOTE_RIGHT; - UI_UP; - UI_LEFT; - UI_RIGHT; - UI_DOWN; - RESET; - ACCEPT; - BACK; - PAUSE; - #if CAN_CHEAT - CHEAT; - #end + // List notes in order from left to right on gameplay screen. + NOTE_LEFT; + NOTE_DOWN; + NOTE_UP; + NOTE_RIGHT; + UI_UP; + UI_LEFT; + UI_RIGHT; + UI_DOWN; + RESET; + ACCEPT; + BACK; + PAUSE; + #if CAN_CHEAT + CHEAT; + #end } @:enum abstract Action(String) to String from String { - var UI_UP = "ui_up"; - var UI_LEFT = "ui_left"; - var UI_RIGHT = "ui_right"; - var UI_DOWN = "ui_down"; - var UI_UP_P = "ui_up-press"; - var UI_LEFT_P = "ui_left-press"; - var UI_RIGHT_P = "ui_right-press"; - var UI_DOWN_P = "ui_down-press"; - var UI_UP_R = "ui_up-release"; - var UI_LEFT_R = "ui_left-release"; - var UI_RIGHT_R = "ui_right-release"; - var UI_DOWN_R = "ui_down-release"; - var NOTE_UP = "note_up"; - var NOTE_LEFT = "note_left"; - var NOTE_RIGHT = "note_right"; - var NOTE_DOWN = "note_down"; - var NOTE_UP_P = "note_up-press"; - var NOTE_LEFT_P = "note_left-press"; - var NOTE_RIGHT_P = "note_right-press"; - var NOTE_DOWN_P = "note_down-press"; - var NOTE_UP_R = "note_up-release"; - var NOTE_LEFT_R = "note_left-release"; - var NOTE_RIGHT_R = "note_right-release"; - var NOTE_DOWN_R = "note_down-release"; - var ACCEPT = "accept"; - var BACK = "back"; - var PAUSE = "pause"; - var RESET = "reset"; - #if CAN_CHEAT - var CHEAT = "cheat"; - #end + var UI_UP = "ui_up"; + var UI_LEFT = "ui_left"; + var UI_RIGHT = "ui_right"; + var UI_DOWN = "ui_down"; + var UI_UP_P = "ui_up-press"; + var UI_LEFT_P = "ui_left-press"; + var UI_RIGHT_P = "ui_right-press"; + var UI_DOWN_P = "ui_down-press"; + var UI_UP_R = "ui_up-release"; + var UI_LEFT_R = "ui_left-release"; + var UI_RIGHT_R = "ui_right-release"; + var UI_DOWN_R = "ui_down-release"; + var NOTE_UP = "note_up"; + var NOTE_LEFT = "note_left"; + var NOTE_RIGHT = "note_right"; + var NOTE_DOWN = "note_down"; + var NOTE_UP_P = "note_up-press"; + var NOTE_LEFT_P = "note_left-press"; + var NOTE_RIGHT_P = "note_right-press"; + var NOTE_DOWN_P = "note_down-press"; + var NOTE_UP_R = "note_up-release"; + var NOTE_LEFT_R = "note_left-release"; + var NOTE_RIGHT_R = "note_right-release"; + var NOTE_DOWN_R = "note_down-release"; + var ACCEPT = "accept"; + var BACK = "back"; + var PAUSE = "pause"; + var RESET = "reset"; + #if CAN_CHEAT + var CHEAT = "cheat"; + #end } enum Device { - Keys; - Gamepad(id:Int); + Keys; + Gamepad(id:Int); } enum KeyboardScheme { - Solo; - Duo(first:Bool); - None; - Custom; + Solo; + Duo(first:Bool); + None; + Custom; } /** @@ -102,913 +102,913 @@ enum KeyboardScheme */ class Controls extends FlxActionSet { - var _ui_up = new FlxActionDigital(Action.UI_UP); - var _ui_left = new FlxActionDigital(Action.UI_LEFT); - var _ui_right = new FlxActionDigital(Action.UI_RIGHT); - var _ui_down = new FlxActionDigital(Action.UI_DOWN); - var _ui_upP = new FlxActionDigital(Action.UI_UP_P); - var _ui_leftP = new FlxActionDigital(Action.UI_LEFT_P); - var _ui_rightP = new FlxActionDigital(Action.UI_RIGHT_P); - var _ui_downP = new FlxActionDigital(Action.UI_DOWN_P); - var _ui_upR = new FlxActionDigital(Action.UI_UP_R); - var _ui_leftR = new FlxActionDigital(Action.UI_LEFT_R); - var _ui_rightR = new FlxActionDigital(Action.UI_RIGHT_R); - var _ui_downR = new FlxActionDigital(Action.UI_DOWN_R); - var _note_up = new FlxActionDigital(Action.NOTE_UP); - var _note_left = new FlxActionDigital(Action.NOTE_LEFT); - var _note_right = new FlxActionDigital(Action.NOTE_RIGHT); - var _note_down = new FlxActionDigital(Action.NOTE_DOWN); - var _note_upP = new FlxActionDigital(Action.NOTE_UP_P); - var _note_leftP = new FlxActionDigital(Action.NOTE_LEFT_P); - var _note_rightP = new FlxActionDigital(Action.NOTE_RIGHT_P); - var _note_downP = new FlxActionDigital(Action.NOTE_DOWN_P); - var _note_upR = new FlxActionDigital(Action.NOTE_UP_R); - var _note_leftR = new FlxActionDigital(Action.NOTE_LEFT_R); - var _note_rightR = new FlxActionDigital(Action.NOTE_RIGHT_R); - var _note_downR = new FlxActionDigital(Action.NOTE_DOWN_R); - var _accept = new FlxActionDigital(Action.ACCEPT); - var _back = new FlxActionDigital(Action.BACK); - var _pause = new FlxActionDigital(Action.PAUSE); - var _reset = new FlxActionDigital(Action.RESET); - #if CAN_CHEAT - var _cheat = new FlxActionDigital(Action.CHEAT); - #end + var _ui_up = new FlxActionDigital(Action.UI_UP); + var _ui_left = new FlxActionDigital(Action.UI_LEFT); + var _ui_right = new FlxActionDigital(Action.UI_RIGHT); + var _ui_down = new FlxActionDigital(Action.UI_DOWN); + var _ui_upP = new FlxActionDigital(Action.UI_UP_P); + var _ui_leftP = new FlxActionDigital(Action.UI_LEFT_P); + var _ui_rightP = new FlxActionDigital(Action.UI_RIGHT_P); + var _ui_downP = new FlxActionDigital(Action.UI_DOWN_P); + var _ui_upR = new FlxActionDigital(Action.UI_UP_R); + var _ui_leftR = new FlxActionDigital(Action.UI_LEFT_R); + var _ui_rightR = new FlxActionDigital(Action.UI_RIGHT_R); + var _ui_downR = new FlxActionDigital(Action.UI_DOWN_R); + var _note_up = new FlxActionDigital(Action.NOTE_UP); + var _note_left = new FlxActionDigital(Action.NOTE_LEFT); + var _note_right = new FlxActionDigital(Action.NOTE_RIGHT); + var _note_down = new FlxActionDigital(Action.NOTE_DOWN); + var _note_upP = new FlxActionDigital(Action.NOTE_UP_P); + var _note_leftP = new FlxActionDigital(Action.NOTE_LEFT_P); + var _note_rightP = new FlxActionDigital(Action.NOTE_RIGHT_P); + var _note_downP = new FlxActionDigital(Action.NOTE_DOWN_P); + var _note_upR = new FlxActionDigital(Action.NOTE_UP_R); + var _note_leftR = new FlxActionDigital(Action.NOTE_LEFT_R); + var _note_rightR = new FlxActionDigital(Action.NOTE_RIGHT_R); + var _note_downR = new FlxActionDigital(Action.NOTE_DOWN_R); + var _accept = new FlxActionDigital(Action.ACCEPT); + var _back = new FlxActionDigital(Action.BACK); + var _pause = new FlxActionDigital(Action.PAUSE); + var _reset = new FlxActionDigital(Action.RESET); + #if CAN_CHEAT + var _cheat = new FlxActionDigital(Action.CHEAT); + #end - var byName:Map = new Map(); + var byName:Map = new Map(); - public var gamepadsAdded:Array = []; - public var keyboardScheme = KeyboardScheme.None; + public var gamepadsAdded:Array = []; + public var keyboardScheme = KeyboardScheme.None; - public var UI_UP(get, never):Bool; + public var UI_UP(get, never):Bool; - inline function get_UI_UP() - return _ui_up.check(); + inline function get_UI_UP() + return _ui_up.check(); - public var UI_LEFT(get, never):Bool; + public var UI_LEFT(get, never):Bool; - inline function get_UI_LEFT() - return _ui_left.check(); + inline function get_UI_LEFT() + return _ui_left.check(); - public var UI_RIGHT(get, never):Bool; + public var UI_RIGHT(get, never):Bool; - inline function get_UI_RIGHT() - return _ui_right.check(); + inline function get_UI_RIGHT() + return _ui_right.check(); - public var UI_DOWN(get, never):Bool; + public var UI_DOWN(get, never):Bool; - inline function get_UI_DOWN() - return _ui_down.check(); + inline function get_UI_DOWN() + return _ui_down.check(); - public var UI_UP_P(get, never):Bool; + public var UI_UP_P(get, never):Bool; - inline function get_UI_UP_P() - return _ui_upP.check(); + inline function get_UI_UP_P() + return _ui_upP.check(); - public var UI_LEFT_P(get, never):Bool; + public var UI_LEFT_P(get, never):Bool; - inline function get_UI_LEFT_P() - return _ui_leftP.check(); + inline function get_UI_LEFT_P() + return _ui_leftP.check(); - public var UI_RIGHT_P(get, never):Bool; + public var UI_RIGHT_P(get, never):Bool; - inline function get_UI_RIGHT_P() - return _ui_rightP.check(); + inline function get_UI_RIGHT_P() + return _ui_rightP.check(); - public var UI_DOWN_P(get, never):Bool; + public var UI_DOWN_P(get, never):Bool; - inline function get_UI_DOWN_P() - return _ui_downP.check(); + inline function get_UI_DOWN_P() + return _ui_downP.check(); - public var UI_UP_R(get, never):Bool; + public var UI_UP_R(get, never):Bool; - inline function get_UI_UP_R() - return _ui_upR.check(); + inline function get_UI_UP_R() + return _ui_upR.check(); - public var UI_LEFT_R(get, never):Bool; + public var UI_LEFT_R(get, never):Bool; - inline function get_UI_LEFT_R() - return _ui_leftR.check(); + inline function get_UI_LEFT_R() + return _ui_leftR.check(); - public var UI_RIGHT_R(get, never):Bool; + public var UI_RIGHT_R(get, never):Bool; - inline function get_UI_RIGHT_R() - return _ui_rightR.check(); + inline function get_UI_RIGHT_R() + return _ui_rightR.check(); - public var UI_DOWN_R(get, never):Bool; + public var UI_DOWN_R(get, never):Bool; - inline function get_UI_DOWN_R() - return _ui_downR.check(); + inline function get_UI_DOWN_R() + return _ui_downR.check(); - public var NOTE_UP(get, never):Bool; + public var NOTE_UP(get, never):Bool; - inline function get_NOTE_UP() - return _note_up.check(); + inline function get_NOTE_UP() + return _note_up.check(); - public var NOTE_LEFT(get, never):Bool; + public var NOTE_LEFT(get, never):Bool; - inline function get_NOTE_LEFT() - return _note_left.check(); + inline function get_NOTE_LEFT() + return _note_left.check(); - public var NOTE_RIGHT(get, never):Bool; + public var NOTE_RIGHT(get, never):Bool; - inline function get_NOTE_RIGHT() - return _note_right.check(); + inline function get_NOTE_RIGHT() + return _note_right.check(); - public var NOTE_DOWN(get, never):Bool; + public var NOTE_DOWN(get, never):Bool; - inline function get_NOTE_DOWN() - return _note_down.check(); + inline function get_NOTE_DOWN() + return _note_down.check(); - public var NOTE_UP_P(get, never):Bool; + public var NOTE_UP_P(get, never):Bool; - inline function get_NOTE_UP_P() - return _note_upP.check(); + inline function get_NOTE_UP_P() + return _note_upP.check(); - public var NOTE_LEFT_P(get, never):Bool; + public var NOTE_LEFT_P(get, never):Bool; - inline function get_NOTE_LEFT_P() - return _note_leftP.check(); + inline function get_NOTE_LEFT_P() + return _note_leftP.check(); - public var NOTE_RIGHT_P(get, never):Bool; + public var NOTE_RIGHT_P(get, never):Bool; - inline function get_NOTE_RIGHT_P() - return _note_rightP.check(); + inline function get_NOTE_RIGHT_P() + return _note_rightP.check(); - public var NOTE_DOWN_P(get, never):Bool; + public var NOTE_DOWN_P(get, never):Bool; - inline function get_NOTE_DOWN_P() - return _note_downP.check(); + inline function get_NOTE_DOWN_P() + return _note_downP.check(); - public var NOTE_UP_R(get, never):Bool; + public var NOTE_UP_R(get, never):Bool; - inline function get_NOTE_UP_R() - return _note_upR.check(); + inline function get_NOTE_UP_R() + return _note_upR.check(); - public var NOTE_LEFT_R(get, never):Bool; + public var NOTE_LEFT_R(get, never):Bool; - inline function get_NOTE_LEFT_R() - return _note_leftR.check(); + inline function get_NOTE_LEFT_R() + return _note_leftR.check(); - public var NOTE_RIGHT_R(get, never):Bool; + public var NOTE_RIGHT_R(get, never):Bool; - inline function get_NOTE_RIGHT_R() - return _note_rightR.check(); + inline function get_NOTE_RIGHT_R() + return _note_rightR.check(); - public var NOTE_DOWN_R(get, never):Bool; + public var NOTE_DOWN_R(get, never):Bool; - inline function get_NOTE_DOWN_R() - return _note_downR.check(); + inline function get_NOTE_DOWN_R() + return _note_downR.check(); - public var ACCEPT(get, never):Bool; + public var ACCEPT(get, never):Bool; - inline function get_ACCEPT() - return _accept.check(); + inline function get_ACCEPT() + return _accept.check(); - public var BACK(get, never):Bool; + public var BACK(get, never):Bool; - inline function get_BACK() - return _back.check(); + inline function get_BACK() + return _back.check(); - public var PAUSE(get, never):Bool; + public var PAUSE(get, never):Bool; - inline function get_PAUSE() - return _pause.check(); + inline function get_PAUSE() + return _pause.check(); - public var RESET(get, never):Bool; + public var RESET(get, never):Bool; - inline function get_RESET() - return _reset.check(); + inline function get_RESET() + return _reset.check(); - #if CAN_CHEAT - public var CHEAT(get, never):Bool; + #if CAN_CHEAT + public var CHEAT(get, never):Bool; - inline function get_CHEAT() - return _cheat.check(); - #end + inline function get_CHEAT() + return _cheat.check(); + #end - public function new(name, scheme:KeyboardScheme = null) - { - super(name); - - add(_ui_up); - add(_ui_left); - add(_ui_right); - add(_ui_down); - add(_ui_upP); - add(_ui_leftP); - add(_ui_rightP); - add(_ui_downP); - add(_ui_upR); - add(_ui_leftR); - add(_ui_rightR); - add(_ui_downR); - add(_note_up); - add(_note_left); - add(_note_right); - add(_note_down); - add(_note_upP); - add(_note_leftP); - add(_note_rightP); - add(_note_downP); - add(_note_upR); - add(_note_leftR); - add(_note_rightR); - add(_note_downR); - add(_accept); - add(_back); - add(_pause); - add(_reset); - #if CAN_CHEAT - add(_cheat); - #end - - for (action in digitalActions) - byName[action.name] = action; - - if (scheme == null) - scheme = None; - - setKeyboardScheme(scheme, false); - } - - override function update() - { - super.update(); - } - - // inline - public function checkByName(name:Action):Bool - { - #if debug - if (!byName.exists(name)) - throw 'Invalid name: $name'; - #end - return byName[name].check(); - } - - public function getDialogueName(action:FlxActionDigital):String - { - var input = action.inputs[0]; - return switch input.device - { - case KEYBOARD: return '[${(input.inputID : FlxKey)}]'; - case GAMEPAD: return '(${(input.inputID : FlxGamepadInputID)})'; - case device: throw 'unhandled device: $device'; - } - } - - public function getDialogueNameFromToken(token:String):String - { - return getDialogueName(getActionFromControl(Control.createByName(token.toUpperCase()))); - } - - function getActionFromControl(control:Control):FlxActionDigital - { - return switch (control) - { - case UI_UP: _ui_up; - case UI_DOWN: _ui_down; - case UI_LEFT: _ui_left; - case UI_RIGHT: _ui_right; - case NOTE_UP: _note_up; - case NOTE_DOWN: _note_down; - case NOTE_LEFT: _note_left; - case NOTE_RIGHT: _note_right; - case ACCEPT: _accept; - case BACK: _back; - case PAUSE: _pause; - case RESET: _reset; - #if CAN_CHEAT - case CHEAT: _cheat; - #end - } - } - - static function init():Void - { - var actions = new FlxActionManager(); - FlxG.inputs.add(actions); - } - - /** - * Calls a function passing each action bound by the specified control - * @param control - * @param func - * @return ->Void) - */ - function forEachBound(control:Control, func:FlxActionDigital->FlxInputState->Void) - { - switch (control) - { - case UI_UP: - func(_ui_up, PRESSED); - func(_ui_upP, JUST_PRESSED); - func(_ui_upR, JUST_RELEASED); - case UI_LEFT: - func(_ui_left, PRESSED); - func(_ui_leftP, JUST_PRESSED); - func(_ui_leftR, JUST_RELEASED); - case UI_RIGHT: - func(_ui_right, PRESSED); - func(_ui_rightP, JUST_PRESSED); - func(_ui_rightR, JUST_RELEASED); - case UI_DOWN: - func(_ui_down, PRESSED); - func(_ui_downP, JUST_PRESSED); - func(_ui_downR, JUST_RELEASED); - case NOTE_UP: - func(_note_up, PRESSED); - func(_note_upP, JUST_PRESSED); - func(_note_upR, JUST_RELEASED); - case NOTE_LEFT: - func(_note_left, PRESSED); - func(_note_leftP, JUST_PRESSED); - func(_note_leftR, JUST_RELEASED); - case NOTE_RIGHT: - func(_note_right, PRESSED); - func(_note_rightP, JUST_PRESSED); - func(_note_rightR, JUST_RELEASED); - case NOTE_DOWN: - func(_note_down, PRESSED); - func(_note_downP, JUST_PRESSED); - func(_note_downR, JUST_RELEASED); - case ACCEPT: - func(_accept, JUST_PRESSED); - case BACK: - func(_back, JUST_PRESSED); - case PAUSE: - func(_pause, JUST_PRESSED); - case RESET: - func(_reset, JUST_PRESSED); - #if CAN_CHEAT - case CHEAT: - func(_cheat, JUST_PRESSED); - #end - } - } - - public function replaceBinding(control:Control, device:Device, toAdd:Int, toRemove:Int) - { - if (toAdd == toRemove) - return; - - switch (device) - { - case Keys: - forEachBound(control, function(action, _) replaceKey(action, toAdd, toRemove)); - - case Gamepad(id): - forEachBound(control, function(action, _) replaceButton(action, id, toAdd, toRemove)); - } - } - - function replaceKey(action:FlxActionDigital, toAdd:Int, toRemove:Int) - { - for (i in 0...action.inputs.length) - { - var input = action.inputs[i]; - if (input.device == KEYBOARD && input.inputID == toRemove) - { - @:privateAccess - action.inputs[i].inputID = toAdd; - } - } - } - - function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:Int, toRemove:Int) - { - for (i in 0...action.inputs.length) - { - var input = action.inputs[i]; - if (isGamepad(input, deviceID) && input.inputID == toRemove) - { - @:privateAccess - action.inputs[i].inputID = toAdd; - } - } - } - - public function copyFrom(controls:Controls, ?device:Device) - { - for (name in controls.byName.keys()) - { - var action = controls.byName[name]; - for (input in action.inputs) - { - if (device == null || isDevice(input, device)) - byName[name].add(cast input); - } - } - - switch (device) - { - case null: - // add all - for (gamepad in controls.gamepadsAdded) - if (gamepadsAdded.indexOf(gamepad) == -1) - gamepadsAdded.push(gamepad); - - mergeKeyboardScheme(controls.keyboardScheme); - - case Gamepad(id): - gamepadsAdded.push(id); - case Keys: - mergeKeyboardScheme(controls.keyboardScheme); - } - } - - inline public function copyTo(controls:Controls, ?device:Device) - { - controls.copyFrom(this, device); - } - - function mergeKeyboardScheme(scheme:KeyboardScheme):Void - { - if (scheme != None) - { - switch (keyboardScheme) - { - case None: - keyboardScheme = scheme; - default: - keyboardScheme = Custom; - } - } - } - - /** - * Sets all actions that pertain to the binder to trigger when the supplied keys are used. - * If binder is a literal you can inline this - */ - public function bindKeys(control:Control, keys:Array) - { - forEachBound(control, function(action, state) addKeys(action, keys, state)); - } - - public function bindSwipe(control:Control, swipeDir:Int = FlxDirectionFlags.UP, ?swpLength:Float = 90) - { - forEachBound(control, function(action, press) action.add(new FlxActionInputDigitalMobileSwipeGameplay(swipeDir, press, swpLength))); - } - - /** - * Sets all actions that pertain to the binder to trigger when the supplied keys are used. - * If binder is a literal you can inline this - */ - public function unbindKeys(control:Control, keys:Array) - { - forEachBound(control, function(action, _) removeKeys(action, keys)); - } - - inline static function addKeys(action:FlxActionDigital, keys:Array, state:FlxInputState) - { - for (key in keys) - action.addKey(key, state); - } - - static function removeKeys(action:FlxActionDigital, keys:Array) - { - var i = action.inputs.length; - while (i-- > 0) - { - var input = action.inputs[i]; - if (input.device == KEYBOARD && keys.indexOf(cast input.inputID) != -1) - action.remove(input); - } - } - - public function setKeyboardScheme(scheme:KeyboardScheme, reset = true) - { - if (reset) - removeKeyboard(); - - keyboardScheme = scheme; - - switch (scheme) - { - case Solo: - bindKeys(Control.UI_UP, [W, FlxKey.UP]); - bindKeys(Control.UI_DOWN, [S, FlxKey.DOWN]); - bindKeys(Control.UI_LEFT, [A, FlxKey.LEFT]); - bindKeys(Control.UI_RIGHT, [D, FlxKey.RIGHT]); - bindKeys(Control.NOTE_UP, [W, FlxKey.UP]); - bindKeys(Control.NOTE_DOWN, [S, FlxKey.DOWN]); - bindKeys(Control.NOTE_LEFT, [A, FlxKey.LEFT]); - bindKeys(Control.NOTE_RIGHT, [D, FlxKey.RIGHT]); - bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); - bindKeys(Control.BACK, [X, BACKSPACE, ESCAPE]); - bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); - bindKeys(Control.RESET, [R]); - case Duo(true): - bindKeys(Control.UI_UP, [W]); - bindKeys(Control.UI_DOWN, [S]); - bindKeys(Control.UI_LEFT, [A]); - bindKeys(Control.UI_RIGHT, [D]); - bindKeys(Control.NOTE_UP, [W]); - bindKeys(Control.NOTE_DOWN, [S]); - bindKeys(Control.NOTE_LEFT, [A]); - bindKeys(Control.NOTE_RIGHT, [D]); - bindKeys(Control.ACCEPT, [G, Z]); - bindKeys(Control.BACK, [H, X]); - bindKeys(Control.PAUSE, [ONE]); - bindKeys(Control.RESET, [R]); - case Duo(false): - bindKeys(Control.UI_UP, [FlxKey.UP]); - bindKeys(Control.UI_DOWN, [FlxKey.DOWN]); - bindKeys(Control.UI_LEFT, [FlxKey.LEFT]); - bindKeys(Control.UI_RIGHT, [FlxKey.RIGHT]); - bindKeys(Control.NOTE_UP, [FlxKey.UP]); - bindKeys(Control.NOTE_DOWN, [FlxKey.DOWN]); - bindKeys(Control.NOTE_LEFT, [FlxKey.LEFT]); - bindKeys(Control.NOTE_RIGHT, [FlxKey.RIGHT]); - bindKeys(Control.ACCEPT, [O]); - bindKeys(Control.BACK, [P]); - bindKeys(Control.PAUSE, [ENTER]); - bindKeys(Control.RESET, [BACKSPACE]); - case None: // nothing - case Custom: // nothing - } - - bindMobileLol(); - } - - function bindMobileLol() - { - #if FLX_TOUCH - // MAKE BETTER TOUCH BIND CODE - - bindSwipe(Control.NOTE_UP, FlxDirectionFlags.UP, 40); - bindSwipe(Control.NOTE_DOWN, FlxDirectionFlags.DOWN, 40); - bindSwipe(Control.NOTE_LEFT, FlxDirectionFlags.LEFT, 40); - bindSwipe(Control.NOTE_RIGHT, FlxDirectionFlags.RIGHT, 40); - - // feels more like drag when up/down are inversed - bindSwipe(Control.UI_UP, FlxDirectionFlags.DOWN); - bindSwipe(Control.UI_DOWN, FlxDirectionFlags.UP); - bindSwipe(Control.UI_LEFT, FlxDirectionFlags.LEFT); - bindSwipe(Control.UI_RIGHT, FlxDirectionFlags.RIGHT); - #end - - #if android - forEachBound(Control.BACK, function(action, pres) - { - action.add(new FlxActionInputDigitalAndroid(FlxAndroidKey.BACK, JUST_PRESSED)); - }); - #end - } - - function removeKeyboard() - { - for (action in this.digitalActions) - { - var i = action.inputs.length; - while (i-- > 0) - { - var input = action.inputs[i]; - if (input.device == KEYBOARD) - action.remove(input); - } - } - } - - public function addGamepadWithSaveData(id:Int, ?padData:Dynamic):Void - { - gamepadsAdded.push(id); - - fromSaveData(padData, Gamepad(id)); - } - - inline function addGamepadLiteral(id:Int, ?buttonMap:Map>):Void - { - gamepadsAdded.push(id); - - for (control in buttonMap.keys()) - bindButtons(control, id, buttonMap[control]); - } - - public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void - { - for (action in this.digitalActions) - { - var i = action.inputs.length; - while (i-- > 0) - { - var input = action.inputs[i]; - if (isGamepad(input, deviceID)) - action.remove(input); - } - } - - gamepadsAdded.remove(deviceID); - } - - public function addDefaultGamepad(id):Void - { - addGamepadLiteral(id, [ - - Control.ACCEPT => [#if switch B #else A #end], - Control.BACK => [#if switch A #else B #end, FlxGamepadInputID.BACK], - Control.UI_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP], - Control.UI_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN], - Control.UI_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT], - Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT], - // don't swap A/B or X/Y for switch on these. A is always the bottom face button - Control.NOTE_UP => [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP], - Control.NOTE_DOWN => [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN], - Control.NOTE_LEFT => [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT], - Control.NOTE_RIGHT => [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT], - Control.PAUSE => [START], - Control.RESET => [RIGHT_SHOULDER] - #if CAN_CHEAT, Control.CHEAT => [X] - #end - ]); - } - - /** - * Sets all actions that pertain to the binder to trigger when the supplied keys are used. - * If binder is a literal you can inline this - */ - public function bindButtons(control:Control, id, buttons) - { - forEachBound(control, function(action, state) addButtons(action, buttons, state, id)); - } - - public function touchShit(control:Control, id) - { - forEachBound(control, function(action, state) - { - // action - }); - } - - /** - * Sets all actions that pertain to the binder to trigger when the supplied keys are used. - * If binder is a literal you can inline this - */ - public function unbindButtons(control:Control, gamepadID:Int, buttons) - { - forEachBound(control, function(action, _) removeButtons(action, gamepadID, buttons)); - } - - inline static function addButtons(action:FlxActionDigital, buttons:Array, state, id) - { - for (button in buttons) - action.addGamepad(button, state, id); - } - - static function removeButtons(action:FlxActionDigital, gamepadID:Int, buttons:Array) - { - var i = action.inputs.length; - while (i-- > 0) - { - var input = action.inputs[i]; - if (isGamepad(input, gamepadID) && buttons.indexOf(cast input.inputID) != -1) - action.remove(input); - } - } - - public function getInputsFor(control:Control, device:Device, ?list:Array):Array - { - if (list == null) - list = []; - - switch (device) - { - case Keys: - for (input in getActionFromControl(control).inputs) - { - if (input.device == KEYBOARD) - list.push(input.inputID); - } - case Gamepad(id): - for (input in getActionFromControl(control).inputs) - { - if (isGamepad(input, id)) - list.push(input.inputID); - } - } - return list; - } - - public function removeDevice(device:Device) - { - switch (device) - { - case Keys: - setKeyboardScheme(None); - case Gamepad(id): - removeGamepad(id); - } - } - - public function fromSaveData(data:Dynamic, device:Device) - { - for (control in Control.createAll()) - { - var inputs:Array = Reflect.field(data, control.getName()); - if (inputs != null) - { - switch (device) - { - case Keys: - bindKeys(control, inputs.copy()); - case Gamepad(id): - bindButtons(control, id, inputs.copy()); - } - } - } - } - - public function createSaveData(device:Device):Dynamic - { - var isEmpty = true; - var data = {}; - for (control in Control.createAll()) - { - var inputs = getInputsFor(control, device); - isEmpty = isEmpty && inputs.length == 0; - - Reflect.setField(data, control.getName(), inputs); - } - - return isEmpty ? null : data; - } - - static function isDevice(input:FlxActionInput, device:Device) - { - return switch device - { - case Keys: input.device == KEYBOARD; - case Gamepad(id): isGamepad(input, id); - } - } - - inline static function isGamepad(input:FlxActionInput, deviceID:Int) - { - return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID); - } + public function new(name, scheme:KeyboardScheme = null) + { + super(name); + + add(_ui_up); + add(_ui_left); + add(_ui_right); + add(_ui_down); + add(_ui_upP); + add(_ui_leftP); + add(_ui_rightP); + add(_ui_downP); + add(_ui_upR); + add(_ui_leftR); + add(_ui_rightR); + add(_ui_downR); + add(_note_up); + add(_note_left); + add(_note_right); + add(_note_down); + add(_note_upP); + add(_note_leftP); + add(_note_rightP); + add(_note_downP); + add(_note_upR); + add(_note_leftR); + add(_note_rightR); + add(_note_downR); + add(_accept); + add(_back); + add(_pause); + add(_reset); + #if CAN_CHEAT + add(_cheat); + #end + + for (action in digitalActions) + byName[action.name] = action; + + if (scheme == null) + scheme = None; + + setKeyboardScheme(scheme, false); + } + + override function update() + { + super.update(); + } + + // inline + public function checkByName(name:Action):Bool + { + #if debug + if (!byName.exists(name)) + throw 'Invalid name: $name'; + #end + return byName[name].check(); + } + + public function getDialogueName(action:FlxActionDigital):String + { + var input = action.inputs[0]; + return switch (input.device) + { + case KEYBOARD: return '[${(input.inputID : FlxKey)}]'; + case GAMEPAD: return '(${(input.inputID : FlxGamepadInputID)})'; + case device: throw 'unhandled device: $device'; + } + } + + public function getDialogueNameFromToken(token:String):String + { + return getDialogueName(getActionFromControl(Control.createByName(token.toUpperCase()))); + } + + function getActionFromControl(control:Control):FlxActionDigital + { + return switch(control) + { + case UI_UP: _ui_up; + case UI_DOWN: _ui_down; + case UI_LEFT: _ui_left; + case UI_RIGHT: _ui_right; + case NOTE_UP: _note_up; + case NOTE_DOWN: _note_down; + case NOTE_LEFT: _note_left; + case NOTE_RIGHT: _note_right; + case ACCEPT: _accept; + case BACK: _back; + case PAUSE: _pause; + case RESET: _reset; + #if CAN_CHEAT + case CHEAT: _cheat; + #end + } + } + + static function init():Void + { + var actions = new FlxActionManager(); + FlxG.inputs.add(actions); + } + + /** + * Calls a function passing each action bound by the specified control + * @param control + * @param func + * @return ->Void) + */ + function forEachBound(control:Control, func:FlxActionDigital->FlxInputState->Void) + { + switch(control) + { + case UI_UP: + func(_ui_up, PRESSED); + func(_ui_upP, JUST_PRESSED); + func(_ui_upR, JUST_RELEASED); + case UI_LEFT: + func(_ui_left, PRESSED); + func(_ui_leftP, JUST_PRESSED); + func(_ui_leftR, JUST_RELEASED); + case UI_RIGHT: + func(_ui_right, PRESSED); + func(_ui_rightP, JUST_PRESSED); + func(_ui_rightR, JUST_RELEASED); + case UI_DOWN: + func(_ui_down, PRESSED); + func(_ui_downP, JUST_PRESSED); + func(_ui_downR, JUST_RELEASED); + case NOTE_UP: + func(_note_up, PRESSED); + func(_note_upP, JUST_PRESSED); + func(_note_upR, JUST_RELEASED); + case NOTE_LEFT: + func(_note_left, PRESSED); + func(_note_leftP, JUST_PRESSED); + func(_note_leftR, JUST_RELEASED); + case NOTE_RIGHT: + func(_note_right, PRESSED); + func(_note_rightP, JUST_PRESSED); + func(_note_rightR, JUST_RELEASED); + case NOTE_DOWN: + func(_note_down, PRESSED); + func(_note_downP, JUST_PRESSED); + func(_note_downR, JUST_RELEASED); + case ACCEPT: + func(_accept, JUST_PRESSED); + case BACK: + func(_back, JUST_PRESSED); + case PAUSE: + func(_pause, JUST_PRESSED); + case RESET: + func(_reset, JUST_PRESSED); + #if CAN_CHEAT + case CHEAT: + func(_cheat, JUST_PRESSED); + #end + } + } + + public function replaceBinding(control:Control, device:Device, toAdd:Int, toRemove:Int) + { + if (toAdd == toRemove) + return; + + switch(device) + { + case Keys: + forEachBound(control, function(action, _) replaceKey(action, toAdd, toRemove)); + + case Gamepad(id): + forEachBound(control, function(action, _) replaceButton(action, id, toAdd, toRemove)); + } + } + + function replaceKey(action:FlxActionDigital, toAdd:Int, toRemove:Int) + { + for (i in 0...action.inputs.length) + { + var input = action.inputs[i]; + if (input.device == KEYBOARD && input.inputID == toRemove) + { + @:privateAccess + action.inputs[i].inputID = toAdd; + } + } + } + + function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:Int, toRemove:Int) + { + for (i in 0...action.inputs.length) + { + var input = action.inputs[i]; + if (isGamepad(input, deviceID) && input.inputID == toRemove) + { + @:privateAccess + action.inputs[i].inputID = toAdd; + } + } + } + + public function copyFrom(controls:Controls, ?device:Device) + { + for (name in controls.byName.keys()) + { + var action = controls.byName[name]; + for (input in action.inputs) + { + if (device == null || isDevice(input, device)) + byName[name].add(cast input); + } + } + + switch(device) + { + case null: + // add all + for (gamepad in controls.gamepadsAdded) + if (gamepadsAdded.indexOf(gamepad) == -1) + gamepadsAdded.push(gamepad); + + mergeKeyboardScheme(controls.keyboardScheme); + + case Gamepad(id): + gamepadsAdded.push(id); + case Keys: + mergeKeyboardScheme(controls.keyboardScheme); + } + } + + inline public function copyTo(controls:Controls, ?device:Device) + { + controls.copyFrom(this, device); + } + + function mergeKeyboardScheme(scheme:KeyboardScheme):Void + { + if (scheme != None) + { + switch(keyboardScheme) + { + case None: + keyboardScheme = scheme; + default: + keyboardScheme = Custom; + } + } + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function bindKeys(control:Control, keys:Array) + { + forEachBound(control, function(action, state) addKeys(action, keys, state)); + } + + public function bindSwipe(control:Control, swipeDir:Int = FlxDirectionFlags.UP, ?swpLength:Float = 90) + { + forEachBound(control, function(action, press) action.add(new FlxActionInputDigitalMobileSwipeGameplay(swipeDir, press, swpLength))); + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function unbindKeys(control:Control, keys:Array) + { + forEachBound(control, function(action, _) removeKeys(action, keys)); + } + + inline static function addKeys(action:FlxActionDigital, keys:Array, state:FlxInputState) + { + for (key in keys) + action.addKey(key, state); + } + + static function removeKeys(action:FlxActionDigital, keys:Array) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (input.device == KEYBOARD && keys.indexOf(cast input.inputID) != -1) + action.remove(input); + } + } + + public function setKeyboardScheme(scheme:KeyboardScheme, reset = true) + { + if (reset) + removeKeyboard(); + + keyboardScheme = scheme; + + switch(scheme) + { + case Solo: + bindKeys(Control.UI_UP, [W, FlxKey.UP]); + bindKeys(Control.UI_DOWN, [S, FlxKey.DOWN]); + bindKeys(Control.UI_LEFT, [A, FlxKey.LEFT]); + bindKeys(Control.UI_RIGHT, [D, FlxKey.RIGHT]); + bindKeys(Control.NOTE_UP, [W, FlxKey.UP]); + bindKeys(Control.NOTE_DOWN, [S, FlxKey.DOWN]); + bindKeys(Control.NOTE_LEFT, [A, FlxKey.LEFT]); + bindKeys(Control.NOTE_RIGHT, [D, FlxKey.RIGHT]); + bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); + bindKeys(Control.BACK, [X, BACKSPACE, ESCAPE]); + bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); + bindKeys(Control.RESET, [R]); + case Duo(true): + bindKeys(Control.UI_UP, [W]); + bindKeys(Control.UI_DOWN, [S]); + bindKeys(Control.UI_LEFT, [A]); + bindKeys(Control.UI_RIGHT, [D]); + bindKeys(Control.NOTE_UP, [W]); + bindKeys(Control.NOTE_DOWN, [S]); + bindKeys(Control.NOTE_LEFT, [A]); + bindKeys(Control.NOTE_RIGHT, [D]); + bindKeys(Control.ACCEPT, [G, Z]); + bindKeys(Control.BACK, [H, X]); + bindKeys(Control.PAUSE, [ONE]); + bindKeys(Control.RESET, [R]); + case Duo(false): + bindKeys(Control.UI_UP, [FlxKey.UP]); + bindKeys(Control.UI_DOWN, [FlxKey.DOWN]); + bindKeys(Control.UI_LEFT, [FlxKey.LEFT]); + bindKeys(Control.UI_RIGHT, [FlxKey.RIGHT]); + bindKeys(Control.NOTE_UP, [FlxKey.UP]); + bindKeys(Control.NOTE_DOWN, [FlxKey.DOWN]); + bindKeys(Control.NOTE_LEFT, [FlxKey.LEFT]); + bindKeys(Control.NOTE_RIGHT, [FlxKey.RIGHT]); + bindKeys(Control.ACCEPT, [O]); + bindKeys(Control.BACK, [P]); + bindKeys(Control.PAUSE, [ENTER]); + bindKeys(Control.RESET, [BACKSPACE]); + case None: // nothing + case Custom: // nothing + } + + bindMobileLol(); + } + + function bindMobileLol() + { + #if FLX_TOUCH + // MAKE BETTER TOUCH BIND CODE + + bindSwipe(Control.NOTE_UP, FlxDirectionFlags.UP, 40); + bindSwipe(Control.NOTE_DOWN, FlxDirectionFlags.DOWN, 40); + bindSwipe(Control.NOTE_LEFT, FlxDirectionFlags.LEFT, 40); + bindSwipe(Control.NOTE_RIGHT, FlxDirectionFlags.RIGHT, 40); + + // feels more like drag when up/down are inversed + bindSwipe(Control.UI_UP, FlxDirectionFlags.DOWN); + bindSwipe(Control.UI_DOWN, FlxDirectionFlags.UP); + bindSwipe(Control.UI_LEFT, FlxDirectionFlags.LEFT); + bindSwipe(Control.UI_RIGHT, FlxDirectionFlags.RIGHT); + #end + + #if android + forEachBound(Control.BACK, function(action, pres) + { + action.add(new FlxActionInputDigitalAndroid(FlxAndroidKey.BACK, JUST_PRESSED)); + }); + #end + } + + function removeKeyboard() + { + for (action in this.digitalActions) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (input.device == KEYBOARD) + action.remove(input); + } + } + } + + public function addGamepadWithSaveData(id:Int, ?padData:Dynamic):Void + { + gamepadsAdded.push(id); + + fromSaveData(padData, Gamepad(id)); + } + + inline function addGamepadLiteral(id:Int, ?buttonMap:Map>):Void + { + gamepadsAdded.push(id); + + for (control in buttonMap.keys()) + bindButtons(control, id, buttonMap[control]); + } + + public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void + { + for (action in this.digitalActions) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (isGamepad(input, deviceID)) + action.remove(input); + } + } + + gamepadsAdded.remove(deviceID); + } + + public function addDefaultGamepad(id):Void + { + addGamepadLiteral(id, [ + + Control.ACCEPT => [#if switch B #else A #end], + Control.BACK => [#if switch A #else B #end, FlxGamepadInputID.BACK], + Control.UI_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP], + Control.UI_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN], + Control.UI_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT], + Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT], + // don't swap A/B or X/Y for switch on these. A is always the bottom face button + Control.NOTE_UP => [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP], + Control.NOTE_DOWN => [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN], + Control.NOTE_LEFT => [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT], + Control.NOTE_RIGHT => [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT], + Control.PAUSE => [START], + Control.RESET => [RIGHT_SHOULDER] + #if CAN_CHEAT, Control.CHEAT => [X] #end + ]); + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function bindButtons(control:Control, id, buttons) + { + forEachBound(control, function(action, state) addButtons(action, buttons, state, id)); + } + + public function touchShit(control:Control, id) + { + forEachBound(control, function(action, state) + { + // action + }); + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function unbindButtons(control:Control, gamepadID:Int, buttons) + { + forEachBound(control, function(action, _) removeButtons(action, gamepadID, buttons)); + } + + inline static function addButtons(action:FlxActionDigital, buttons:Array, state, id) + { + for (button in buttons) + action.addGamepad(button, state, id); + } + + static function removeButtons(action:FlxActionDigital, gamepadID:Int, buttons:Array) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (isGamepad(input, gamepadID) && buttons.indexOf(cast input.inputID) != -1) + action.remove(input); + } + } + + public function getInputsFor(control:Control, device:Device, ?list:Array):Array + { + if (list == null) + list = []; + + switch(device) + { + case Keys: + for (input in getActionFromControl(control).inputs) + { + if (input.device == KEYBOARD) + list.push(input.inputID); + } + case Gamepad(id): + for (input in getActionFromControl(control).inputs) + { + if (isGamepad(input, id)) + list.push(input.inputID); + } + } + return list; + } + + public function removeDevice(device:Device) + { + switch(device) + { + case Keys: + setKeyboardScheme(None); + case Gamepad(id): + removeGamepad(id); + } + } + + public function fromSaveData(data:Dynamic, device:Device) + { + for (control in Control.createAll()) + { + var inputs:Array = Reflect.field(data, control.getName()); + if (inputs != null) + { + switch(device) + { + case Keys: + bindKeys(control, inputs.copy()); + case Gamepad(id): + bindButtons(control, id, inputs.copy()); + } + } + } + } + + public function createSaveData(device:Device):Dynamic + { + var isEmpty = true; + var data = {}; + for (control in Control.createAll()) + { + var inputs = getInputsFor(control, device); + isEmpty = isEmpty && inputs.length == 0; + + Reflect.setField(data, control.getName(), inputs); + } + + return isEmpty ? null : data; + } + + static function isDevice(input:FlxActionInput, device:Device) + { + return switch(device) + { + case Keys: input.device == KEYBOARD; + case Gamepad(id): isGamepad(input, id); + } + } + + inline static function isGamepad(input:FlxActionInput, deviceID:Int) + { + return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID); + } } typedef SaveInputLists = { - ?keys:Array, - ?pad:Array + ?keys:Array, + ?pad:Array }; typedef Swipes = { - ?initTouchPos:FlxPoint, - ?touchAngle:Float, - ?touchLength:Float, - ?curTouchPos:FlxPoint + ?initTouchPos:FlxPoint, + ?touchAngle:Float, + ?touchLength:Float, + ?curTouchPos:FlxPoint }; class FlxActionInputDigitalMobileSwipeGameplay extends FlxActionInputDigital { - var touchMap:Map = new Map(); + var touchMap:Map = new Map(); - var vibrationSteps:Int = 5; - var curStep:Int = 5; - var activateLength:Float = 90; - var hapticPressure:Int = 100; + var vibrationSteps:Int = 5; + var curStep:Int = 5; + var activateLength:Float = 90; + var hapticPressure:Int = 100; - public function new(swipeDir:Int = FlxDirectionFlags.ANY, Trigger:FlxInputState, ?swipeLength:Float = 90) - { - super(OTHER, swipeDir, Trigger); + public function new(swipeDir:Int = FlxDirectionFlags.ANY, Trigger:FlxInputState, ?swipeLength:Float = 90) + { + super(OTHER, swipeDir, Trigger); - activateLength = swipeLength; - } + activateLength = swipeLength; + } - // fix right swipe - // make so cant double swipe during gameplay - // hold notes? + // fix right swipe + // make so cant double swipe during gameplay + // hold notes? - override function update():Void - { - super.update(); + override function update():Void + { + super.update(); - #if FLX_TOUCH - for (touch in FlxG.touches.list) - { - if (touch.justPressed) - { - var pos:FlxPoint = new FlxPoint(touch.screenX, touch.screenY); - var pos2:FlxPoint = new FlxPoint(touch.screenX, touch.screenY); + #if FLX_TOUCH + for (touch in FlxG.touches.list) + { + if (touch.justPressed) + { + var pos:FlxPoint = new FlxPoint(touch.screenX, touch.screenY); + var pos2:FlxPoint = new FlxPoint(touch.screenX, touch.screenY); - var swp:Swipes = { - initTouchPos: pos, - curTouchPos: pos2, - touchAngle: 0, - touchLength: 0 - }; - touchMap[touch.touchPointID] = swp; + var swp:Swipes = + { + initTouchPos: pos, + curTouchPos: pos2, + touchAngle: 0, + touchLength: 0 + }; + touchMap[touch.touchPointID] = swp; - curStep = 1; - Haptic.vibrate(40, 70); - } - if (touch.pressed) - { - var daSwipe = touchMap[touch.touchPointID]; + curStep = 1; + Haptic.vibrate(40, 70); + } + if (touch.pressed) + { + var daSwipe = touchMap[touch.touchPointID]; - daSwipe.curTouchPos.set(touch.screenX, touch.screenY); + daSwipe.curTouchPos.set(touch.screenX, touch.screenY); - var dx = daSwipe.initTouchPos.x - touch.screenX; - var dy = daSwipe.initTouchPos.y - touch.screenY; + var dx = daSwipe.initTouchPos.x - touch.screenX; + var dy = daSwipe.initTouchPos.y - touch.screenY; - daSwipe.touchAngle = Math.atan2(dy, dx); - daSwipe.touchLength = Math.sqrt(dx * dx + dy * dy); + daSwipe.touchAngle = Math.atan2(dy, dx); + daSwipe.touchLength = Math.sqrt(dx * dx + dy * dy); - FlxG.watch.addQuick("LENGTH", daSwipe.touchLength); - FlxG.watch.addQuick("ANGLE", FlxAngle.asDegrees(daSwipe.touchAngle)); + FlxG.watch.addQuick("LENGTH", daSwipe.touchLength); + FlxG.watch.addQuick("ANGLE", FlxAngle.asDegrees(daSwipe.touchAngle)); - if (daSwipe.touchLength >= (activateLength / vibrationSteps) * curStep) - { - curStep += 1; - // Haptic.vibrate(Std.int(hapticPressure / (curStep * 1.5)), 50); - } - } + if (daSwipe.touchLength >= (activateLength / vibrationSteps) * curStep) + { + curStep += 1; + // Haptic.vibrate(Std.int(hapticPressure / (curStep * 1.5)), 50); + } + } - if (touch.justReleased) - { - touchMap.remove(touch.touchPointID); - } + if (touch.justReleased) + { + touchMap.remove(touch.touchPointID); + } - /* switch (inputID) - { - case FlxDirectionFlags.UP: - return - case FlxDirectionFlags.DOWN: - } - */ - } - #end - } + /* switch (inputID) + { + case FlxDirectionFlags.UP: + return + case FlxDirectionFlags.DOWN: + } + */ + } + #end + } - override public function check(Action:FlxAction):Bool - { - for (swp in touchMap) - { - var degAngle = FlxAngle.asDegrees(swp.touchAngle); + override public function check(Action:FlxAction):Bool + { + for (swp in touchMap) + { + var degAngle = FlxAngle.asDegrees(swp.touchAngle); - switch (trigger) - { - case JUST_PRESSED: - if (swp.touchLength >= activateLength) - { - switch (inputID) - { - case FlxDirectionFlags.UP: - if (degAngle >= 45 && degAngle <= 90 + 45) return properTouch(swp); - case FlxDirectionFlags.DOWN: - if (-degAngle >= 45 && -degAngle <= 90 + 45) return properTouch(swp); - case FlxDirectionFlags.LEFT: - if (degAngle <= 45 && -degAngle <= 45) return properTouch(swp); - case FlxDirectionFlags.RIGHT: - if (degAngle >= 90 + 45 && degAngle <= -90 + -45) return properTouch(swp); - } - } - default: - } - } + switch(trigger) + { + case JUST_PRESSED: + if (swp.touchLength >= activateLength) + { + switch(inputID) + { + case FlxDirectionFlags.UP: + if (degAngle >= 45 && degAngle <= 90 + 45) return properTouch(swp); + case FlxDirectionFlags.DOWN: + if (-degAngle >= 45 && -degAngle <= 90 + 45) return properTouch(swp); + case FlxDirectionFlags.LEFT: + if (degAngle <= 45 && -degAngle <= 45) return properTouch(swp); + case FlxDirectionFlags.RIGHT: + if (degAngle >= 90 + 45 && degAngle <= -90 + -45) return properTouch(swp); + } + } + default: + } + } - return false; - } + return false; + } - function properTouch(swipe:Swipes):Bool - { - curStep = 1; - Haptic.vibrate(100, 30); - swipe.initTouchPos.set(swipe.curTouchPos.x, swipe.curTouchPos.y); - return true; - } + function properTouch(swipe:Swipes):Bool + { + curStep = 1; + Haptic.vibrate(100, 30); + swipe.initTouchPos.set(swipe.curTouchPos.x, swipe.curTouchPos.y); + return true; + } } // Maybe this can be committed to main HaxeFlixel repo? #if android class FlxActionInputDigitalAndroid extends FlxActionInputDigital { - /** - * Android buttons action input - * @param androidKeyID Key identifier (FlxAndroidKey.BACK, FlxAndroidKey.MENU... those are the only 2 android specific ones) - * @param Trigger What state triggers this action (PRESSED, JUST_PRESSED, RELEASED, JUST_RELEASED) - */ - public function new(androidKeyID:FlxAndroidKey, Trigger:FlxInputState) - { - super(FlxInputDevice.OTHER, androidKeyID, Trigger); - } + /** + * Android buttons action input + * @param androidKeyID Key identifier (FlxAndroidKey.BACK, FlxAndroidKey.MENU... those are the only 2 android specific ones) + * @param Trigger What state triggers this action (PRESSED, JUST_PRESSED, RELEASED, JUST_RELEASED) + */ + public function new(androidKeyID:FlxAndroidKey, Trigger:FlxInputState) + { + super(FlxInputDevice.OTHER, androidKeyID, Trigger); + } - override public function check(Action:FlxAction):Bool - { - return switch (trigger) - { - #if android - case PRESSED: FlxG.android.checkStatus(inputID, PRESSED) || FlxG.android.checkStatus(inputID, PRESSED); - case RELEASED: FlxG.android.checkStatus(inputID, RELEASED) || FlxG.android.checkStatus(inputID, JUST_RELEASED); - case JUST_PRESSED: FlxG.android.checkStatus(inputID, JUST_PRESSED); - case JUST_RELEASED: FlxG.android.checkStatus(inputID, JUST_RELEASED); - #end + override public function check(Action:FlxAction):Bool + { + returnswitch(trigger) + { + #if android + case PRESSED: FlxG.android.checkStatus(inputID, PRESSED) || FlxG.android.checkStatus(inputID, PRESSED); + case RELEASED: FlxG.android.checkStatus(inputID, RELEASED) || FlxG.android.checkStatus(inputID, JUST_RELEASED); + case JUST_PRESSED: FlxG.android.checkStatus(inputID, JUST_PRESSED); + case JUST_RELEASED: FlxG.android.checkStatus(inputID, JUST_RELEASED); + #end - default: false; - } - } + default: false; + } + } } #end diff --git a/source/funkin/CoolUtil.hx b/source/funkin/CoolUtil.hx index fbe703803..c7d3f7dab 100644 --- a/source/funkin/CoolUtil.hx +++ b/source/funkin/CoolUtil.hx @@ -20,148 +20,144 @@ import openfl.filters.ShaderFilter; class CoolUtil { - public static var difficultyArray:Array = ['EASY', "NORMAL", "HARD"]; + public static var difficultyArray:Array = ['EASY', "NORMAL", "HARD"]; - public static function difficultyString():String - { - return difficultyArray[PlayState.storyDifficulty]; - } + public static function difficultyString():String + { + return difficultyArray[PlayState.storyDifficulty]; + } - public static function coolBaseLog(base:Float, fin:Float):Float - { - return Math.log(fin) / Math.log(base); - } + public static function coolBaseLog(base:Float, fin:Float):Float + { + return Math.log(fin) / Math.log(base); + } - public static function coolTextFile(path:String):Array - { - var daList:Array = []; + public static function coolTextFile(path:String):Array + { + var daList:Array = []; - var swagArray:Array = Assets.getText(path).trim().split('\n'); + var swagArray:Array = Assets.getText(path).trim().split('\n'); - for (item in swagArray) - { - // comment support in the quick lil text formats??? using // - if (!item.trim().startsWith('//')) - daList.push(item); - } + for (item in swagArray) + { + // comment support in the quick lil text formats??? using // + if (!item.trim().startsWith('//')) daList.push(item); + } - for (i in 0...daList.length) - { - daList[i] = daList[i].trim(); - } + for (i in 0...daList.length) + { + daList[i] = daList[i].trim(); + } - return daList; - } + return daList; + } - public static function numberArray(max:Int, ?min = 0):Array - { - var dumbArray:Array = []; - for (i in min...max) - { - dumbArray.push(i); - } - return dumbArray; - } + public static function numberArray(max:Int, ?min = 0):Array + { + var dumbArray:Array = []; + for (i in min...max) + { + dumbArray.push(i); + } + return dumbArray; + } - static var oldCamPos:FlxPoint = new FlxPoint(); - static var oldMousePos:FlxPoint = new FlxPoint(); + static var oldCamPos:FlxPoint = new FlxPoint(); + static var oldMousePos:FlxPoint = new FlxPoint(); - /** - * Used to be for general camera middle click dragging, now generalized for any click and drag type shit! - * Listen I don't make the rules here - * @param target what you want to be dragged, defaults to CAMERA SCROLL - * @param jusPres the "justPressed", should be a button of some sort - * @param pressed the "pressed", which should be the same button as `jusPres` - */ - public static function mouseCamDrag(?target:FlxPoint, ?jusPres:Bool, ?pressed:Bool):Void - { - if (target == null) - target = FlxG.camera.scroll; + /** + * Used to be for general camera middle click dragging, now generalized for any click and drag type shit! + * Listen I don't make the rules here + * @param target what you want to be dragged, defaults to CAMERA SCROLL + * @param jusPres the "justPressed", should be a button of some sort + * @param pressed the "pressed", which should be the same button as `jusPres` + */ + public static function mouseCamDrag(?target:FlxPoint, ?jusPres:Bool, ?pressed:Bool):Void + { + if (target == null) target = FlxG.camera.scroll; - if (jusPres == null) - jusPres = FlxG.mouse.justPressedMiddle; + if (jusPres == null) jusPres = FlxG.mouse.justPressedMiddle; - if (pressed == null) - pressed = FlxG.mouse.pressedMiddle; + if (pressed == null) pressed = FlxG.mouse.pressedMiddle; - if (jusPres) - { - oldCamPos.set(target.x, target.y); - oldMousePos.set(FlxG.mouse.screenX, FlxG.mouse.screenY); - } + if (jusPres) + { + oldCamPos.set(target.x, target.y); + oldMousePos.set(FlxG.mouse.screenX, FlxG.mouse.screenY); + } - if (pressed) - { - target.x = oldCamPos.x - (FlxG.mouse.screenX - oldMousePos.x); - target.y = oldCamPos.y - (FlxG.mouse.screenY - oldMousePos.y); - } - } + if (pressed) + { + target.x = oldCamPos.x - (FlxG.mouse.screenX - oldMousePos.x); + target.y = oldCamPos.y - (FlxG.mouse.screenY - oldMousePos.y); + } + } - public static function mouseWheelZoom():Void - { - if (FlxG.mouse.wheel != 0) - FlxG.camera.zoom += FlxG.mouse.wheel * (0.1 * FlxG.camera.zoom); - } + public static function mouseWheelZoom():Void + { + if (FlxG.mouse.wheel != 0) FlxG.camera.zoom += FlxG.mouse.wheel * (0.1 * FlxG.camera.zoom); + } - /** - Lerps camera, but accountsfor framerate shit? - Right now it's simply for use to change the followLerp variable of a camera during update - TODO LATER MAYBE: - Actually make and modify the scroll and lerp shit in it's own function - instead of solely relying on changing the lerp on the fly - */ - public static function camLerpShit(lerp:Float):Float - { - return lerp * (FlxG.elapsed / (1 / 60)); - } + /** + Lerps camera, but accountsfor framerate shit? + Right now it's simply for use to change the followLerp variable of a camera during update + TODO LATER MAYBE: + Actually make and modify the scroll and lerp shit in it's own function + instead of solely relying on changing the lerp on the fly + */ + public static function camLerpShit(lerp:Float):Float + { + return lerp * (FlxG.elapsed / (1 / 60)); + } - public static function coolSwitchState(state:FlxState, transitionTex:String = "shaderTransitionStuff/coolDots", time:Float = 2) - { - var screenShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("shaderTransitionStuff/coolDots")); - var screenWipeShit:ScreenWipeShader = new ScreenWipeShader(); + public static function coolSwitchState(state:FlxState, transitionTex:String = "shaderTransitionStuff/coolDots", time:Float = 2) + { + var screenShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("shaderTransitionStuff/coolDots")); + var screenWipeShit:ScreenWipeShader = new ScreenWipeShader(); - screenWipeShit.funnyShit.input = screenShit.pixels; - FlxTween.tween(screenWipeShit, {daAlphaShit: 1}, time, { - ease: FlxEase.quadInOut, - onComplete: function(twn) - { - screenShit.destroy(); - FlxG.switchState(new MainMenuState()); - } - }); - FlxG.camera.setFilters([new ShaderFilter(screenWipeShit)]); - } + screenWipeShit.funnyShit.input = screenShit.pixels; + FlxTween.tween(screenWipeShit, {daAlphaShit: 1}, time, + { + ease: FlxEase.quadInOut, + onComplete: function(twn) + { + screenShit.destroy(); + FlxG.switchState(new MainMenuState()); + } + }); + FlxG.camera.setFilters([new ShaderFilter(screenWipeShit)]); + } - /** - * Just saves the json with some default values hehe - * @param json - * @return String - */ - public static inline function jsonStringify(data:Dynamic):String - { - return Json.stringify(data, null, "\t"); - } + /** + * Just saves the json with some default values hehe + * @param json + * @return String + */ + public static inline function jsonStringify(data:Dynamic):String + { + return Json.stringify(data, null, "\t"); + } - /** - * Hashlink json encoding fix for some wacky bullshit - * https://github.com/HaxeFoundation/haxe/issues/6930#issuecomment-384570392 - */ - public static function coolJSON(fileData:String) - { - var cont = fileData; - function is(n:Int, what:Int) - return cont.charCodeAt(n) == what; - return JsonParser.parse(cont.substr(if (is(0, 65279)) /// looks like a HL target, skipping only first character here: - 1 else if (is(0, 239) && is(1, 187) && is(2, 191)) /// it seems to be Neko or PHP, start from position 3: - 3 else /// all other targets, that prepare the UTF string correctly - 0)); - } + /** + * Hashlink json encoding fix for some wacky bullshit + * https://github.com/HaxeFoundation/haxe/issues/6930#issuecomment-384570392 + */ + public static function coolJSON(fileData:String) + { + var cont = fileData; + function is(n:Int, what:Int) + return cont.charCodeAt(n) == what; + return JsonParser.parse(cont.substr(if (is(0, 65279)) /// looks like a HL target, skipping only first character here: + 1 else if (is(0, 239) && is(1, 187) && is(2, 191)) /// it seems to be Neko or PHP, start from position 3: + 3 else /// all other targets, that prepare the UTF string correctly + 0)); + } - /* - * frame dependant lerp kinda lol - */ - public static function coolLerp(base:Float, target:Float, ratio:Float):Float - { - return base + camLerpShit(ratio) * (target - base); - } + /* + * frame dependant lerp kinda lol + */ + public static function coolLerp(base:Float, target:Float, ratio:Float):Float + { + return base + camLerpShit(ratio) * (target - base); + } } diff --git a/source/funkin/CutsceneAnimTestState.hx b/source/funkin/CutsceneAnimTestState.hx index ae2a0b80f..7d6369c12 100644 --- a/source/funkin/CutsceneAnimTestState.hx +++ b/source/funkin/CutsceneAnimTestState.hx @@ -16,65 +16,65 @@ import openfl.geom.Rectangle; class CutsceneAnimTestState extends FlxState { - var cutsceneGroup:CutsceneCharacter; + var cutsceneGroup:CutsceneCharacter; - var curSelected:Int = 0; - var debugTxt:FlxText; + var curSelected:Int = 0; + var debugTxt:FlxText; - var funnySprite:FlxSprite = new FlxSprite(); - var clip:MovieClip; + var funnySprite:FlxSprite = new FlxSprite(); + var clip:MovieClip; - public function new() - { - super(); + public function new() + { + super(); - var gridBG:FlxSprite = FlxGridOverlay.create(10, 10); - gridBG.scrollFactor.set(0.5, 0.5); - add(gridBG); + var gridBG:FlxSprite = FlxGridOverlay.create(10, 10); + gridBG.scrollFactor.set(0.5, 0.5); + add(gridBG); - debugTxt = new FlxText(900, 20, 0, "", 20); - debugTxt.color = FlxColor.BLUE; - add(debugTxt); + debugTxt = new FlxText(900, 20, 0, "", 20); + debugTxt.color = FlxColor.BLUE; + add(debugTxt); - clip = Assets.getMovieClip("tanky:"); - // clip.x = FlxG.width/2; - // clip.y = FlxG.height/2; - FlxG.stage.addChild(clip); + clip = Assets.getMovieClip("tanky:"); + // clip.x = FlxG.width/2; + // clip.y = FlxG.height/2; + FlxG.stage.addChild(clip); - var swagShit:MovieClip = Assets.getMovieClip('tankBG:'); - // swagShit.scaleX = 5; + var swagShit:MovieClip = Assets.getMovieClip('tankBG:'); + // swagShit.scaleX = 5; - FlxG.stage.addChild(swagShit); - swagShit.gotoAndStop(13); + FlxG.stage.addChild(swagShit); + swagShit.gotoAndStop(13); - var swfMountain = new BitmapData(FlxG.width, FlxG.height, true, 0x00000000); - swfMountain.draw(swagShit, swagShit.transform.matrix); + var swfMountain = new BitmapData(FlxG.width, FlxG.height, true, 0x00000000); + swfMountain.draw(swagShit, swagShit.transform.matrix); - var mountains:FlxSprite = new FlxSprite().loadGraphic(swfMountain); - // add(mountains); + var mountains:FlxSprite = new FlxSprite().loadGraphic(swfMountain); + // add(mountains); - FlxG.stage.removeChild(swagShit); + FlxG.stage.removeChild(swagShit); - funnySprite.x = FlxG.width / 2; - funnySprite.y = FlxG.height / 2; - add(funnySprite); - } + funnySprite.x = FlxG.width / 2; + funnySprite.y = FlxG.height / 2; + add(funnySprite); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - // jam sprite into top left corner - var drawMatrix:Matrix = clip.transform.matrix; - var bounds:Rectangle = clip.getBounds(null); - drawMatrix.tx = -bounds.x; - drawMatrix.ty = -bounds.y; - // make bitmapdata only as big as it needs to be - var funnyBmp:BitmapData = new BitmapData(Math.ceil(bounds.width), Math.ceil(bounds.height), true, 0x00000000); - funnyBmp.draw(clip, drawMatrix, true); - funnySprite.loadGraphic(funnyBmp); - // jam sprite back into place lol - funnySprite.offset.x = -bounds.x; - funnySprite.offset.y = -bounds.y; - } + // jam sprite into top left corner + var drawMatrix:Matrix = clip.transform.matrix; + var bounds:Rectangle = clip.getBounds(null); + drawMatrix.tx = -bounds.x; + drawMatrix.ty = -bounds.y; + // make bitmapdata only as big as it needs to be + var funnyBmp:BitmapData = new BitmapData(Math.ceil(bounds.width), Math.ceil(bounds.height), true, 0x00000000); + funnyBmp.draw(clip, drawMatrix, true); + funnySprite.loadGraphic(funnyBmp); + // jam sprite back into place lol + funnySprite.offset.x = -bounds.x; + funnySprite.offset.y = -bounds.y; + } } diff --git a/source/funkin/CutsceneCharacter.hx b/source/funkin/CutsceneCharacter.hx index 37fd190af..67810bc30 100644 --- a/source/funkin/CutsceneCharacter.hx +++ b/source/funkin/CutsceneCharacter.hx @@ -6,72 +6,70 @@ import flixel.math.FlxPoint; class CutsceneCharacter extends FlxTypedGroup { - public var coolPos:FlxPoint = FlxPoint.get(); - public var animShit:Map = new Map(); + public var coolPos:FlxPoint = FlxPoint.get(); + public var animShit:Map = new Map(); - private var imageShit:String; + var imageShit:String; - public function new(x:Float, y:Float, imageShit:String) - { - super(); + public function new(x:Float, y:Float, imageShit:String) + { + super(); - coolPos.set(x, y); + coolPos.set(x, y); - this.imageShit = imageShit; - parseOffsets(); - createCutscene(0); - } + this.imageShit = imageShit; + parseOffsets(); + createCutscene(0); + } - // shitshow, oh well - var arrayLMFAOOOO:Array = []; + // shitshow, oh well + var arrayLMFAOOOO:Array = []; - function parseOffsets() - { - var splitShit:Array = CoolUtil.coolTextFile(Paths.file('images/cutsceneStuff/' + imageShit + "CutsceneOffsets.txt")); + function parseOffsets() + { + var splitShit:Array = CoolUtil.coolTextFile(Paths.file('images/cutsceneStuff/' + imageShit + "CutsceneOffsets.txt")); - for (i in splitShit) - { - var xAndY:FlxPoint = FlxPoint.get(); - var dumbSplit:Array = i.split('---')[1].trim().split(' '); - trace('cool split: ' + i.split('---')[1]); - trace(dumbSplit); - xAndY.set(Std.parseFloat(dumbSplit[0]), Std.parseFloat(dumbSplit[1])); + for (i in splitShit) + { + var xAndY:FlxPoint = FlxPoint.get(); + var dumbSplit:Array = i.split('---')[1].trim().split(' '); + trace('cool split: ' + i.split('---')[1]); + trace(dumbSplit); + xAndY.set(Std.parseFloat(dumbSplit[0]), Std.parseFloat(dumbSplit[1])); - animShit.set(i.split('---')[0].trim(), xAndY); - arrayLMFAOOOO.push(i.split('---')[0].trim()); - } + animShit.set(i.split('---')[0].trim(), xAndY); + arrayLMFAOOOO.push(i.split('---')[0].trim()); + } - trace(animShit); - } + trace(animShit); + } - public function createCutscene(daNum:Int = 0) - { - var cutScene:FlxSprite = new FlxSprite(coolPos.x + animShit.get(arrayLMFAOOOO[daNum]).x, coolPos.y + animShit.get(arrayLMFAOOOO[daNum]).y); - cutScene.frames = Paths.getSparrowAtlas('cutsceneStuff/' + imageShit + "-" + daNum); - cutScene.animation.addByPrefix('weed', arrayLMFAOOOO[daNum], 24, false); - cutScene.animation.play('weed'); - cutScene.antialiasing = true; + public function createCutscene(daNum:Int = 0) + { + var cutScene:FlxSprite = new FlxSprite(coolPos.x + animShit.get(arrayLMFAOOOO[daNum]).x, coolPos.y + animShit.get(arrayLMFAOOOO[daNum]).y); + cutScene.frames = Paths.getSparrowAtlas('cutsceneStuff/' + imageShit + "-" + daNum); + cutScene.animation.addByPrefix('weed', arrayLMFAOOOO[daNum], 24, false); + cutScene.animation.play('weed'); + cutScene.antialiasing = true; - cutScene.animation.finishCallback = function(anim:String) - { - cutScene.kill(); - cutScene.destroy(); - cutScene = null; + cutScene.animation.finishCallback = function(anim:String) + { + cutScene.kill(); + cutScene.destroy(); + cutScene = null; - if (daNum + 1 < arrayLMFAOOOO.length) - createCutscene(daNum + 1); - else - ended(); - }; + if (daNum + 1 < arrayLMFAOOOO.length) createCutscene(daNum + 1); + else + ended(); + }; - add(cutScene); - } + add(cutScene); + } - public var onFinish:Void->Void; + public var onFinish:Void->Void; - public function ended():Void - { - if (onFinish != null) - onFinish(); - } + public function ended():Void + { + if (onFinish != null) onFinish(); + } } diff --git a/source/funkin/DialogueBox.hx b/source/funkin/DialogueBox.hx index 663b7fdba..e9c3587ad 100644 --- a/source/funkin/DialogueBox.hx +++ b/source/funkin/DialogueBox.hx @@ -3,271 +3,268 @@ package funkin; import funkin.util.Constants; import flixel.FlxSprite; import flixel.addons.text.FlxTypeText; -import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup; -import flixel.input.FlxKeyManager; import flixel.text.FlxText; import flixel.util.FlxColor; import flixel.util.FlxTimer; import funkin.play.PlayState; +/** + * Handles dialog boxes and text, like the ones in Week 6. + */ class DialogueBox extends FlxSpriteGroup { - var box:FlxSprite; + var box:FlxSprite; - var curCharacter:String = ''; + var curCharacter:String = ''; - var dialogue:Alphabet; - var dialogueList:Array = []; + var dialogue:Alphabet; + var dialogueList:Array = []; - // SECOND DIALOGUE FOR THE PIXEL SHIT INSTEAD??? - var swagDialogue:FlxTypeText; + // SECOND DIALOGUE FOR THE PIXEL SHIT INSTEAD??? + var swagDialogue:FlxTypeText; - var dropText:FlxText; + var dropText:FlxText; - public var finishThing:Void->Void; + public var finishThing:Void->Void; - var portraitLeft:FlxSprite; - var portraitRight:FlxSprite; + var portraitLeft:FlxSprite; + var portraitRight:FlxSprite; - var handSelect:FlxSprite; - var bgFade:FlxSprite; + var handSelect:FlxSprite; + var bgFade:FlxSprite; - public function new(talkingRight:Bool = true, ?dialogueList:Array) - { - super(); + public function new(talkingRight:Bool = true, ?dialogueList:Array) + { + super(); - switch (PlayState.currentSong.song.toLowerCase()) - { - case 'senpai': - FlxG.sound.playMusic(Paths.music('Lunchbox'), 0); - FlxG.sound.music.fadeIn(1, 0, 0.8); - case 'thorns': - FlxG.sound.playMusic(Paths.music('LunchboxScary'), 0); - FlxG.sound.music.fadeIn(1, 0, 0.8); - } + switch (PlayState.currentSong.song.toLowerCase()) + { + case 'senpai': + FlxG.sound.playMusic(Paths.music('Lunchbox'), 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + case 'thorns': + FlxG.sound.playMusic(Paths.music('LunchboxScary'), 0); + FlxG.sound.music.fadeIn(1, 0, 0.8); + } - bgFade = new FlxSprite(-200, -200).makeGraphic(Std.int(FlxG.width * 1.3), Std.int(FlxG.height * 1.3), 0xFFB3DFd8); - bgFade.scrollFactor.set(); - bgFade.alpha = 0; - add(bgFade); + bgFade = new FlxSprite(-200, -200).makeGraphic(Std.int(FlxG.width * 1.3), Std.int(FlxG.height * 1.3), 0xFFB3DFD8); + bgFade.scrollFactor.set(); + bgFade.alpha = 0; + add(bgFade); - new FlxTimer().start(0.83, function(tmr:FlxTimer) - { - bgFade.alpha += (1 / 5) * 0.7; - if (bgFade.alpha > 0.7) - bgFade.alpha = 0.7; - }, 5); + new FlxTimer().start(0.83, function(tmr:FlxTimer) + { + bgFade.alpha += (1 / 5) * 0.7; + if (bgFade.alpha > 0.7) bgFade.alpha = 0.7; + }, 5); - portraitLeft = new FlxSprite(-20, 40); - portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); - portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); - portraitLeft.setGraphicSize(Std.int(portraitLeft.width * Constants.PIXEL_ART_SCALE * 0.9)); - portraitLeft.updateHitbox(); - portraitLeft.scrollFactor.set(); - add(portraitLeft); - portraitLeft.visible = false; + portraitLeft = new FlxSprite(-20, 40); + portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); + portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); + portraitLeft.setGraphicSize(Std.int(portraitLeft.width * Constants.PIXEL_ART_SCALE * 0.9)); + portraitLeft.updateHitbox(); + portraitLeft.scrollFactor.set(); + add(portraitLeft); + portraitLeft.visible = false; - portraitRight = new FlxSprite(0, 40); - portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); - portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); - portraitRight.setGraphicSize(Std.int(portraitRight.width * Constants.PIXEL_ART_SCALE * 0.9)); - portraitRight.updateHitbox(); - portraitRight.scrollFactor.set(); - add(portraitRight); - portraitRight.visible = false; + portraitRight = new FlxSprite(0, 40); + portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); + portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); + portraitRight.setGraphicSize(Std.int(portraitRight.width * Constants.PIXEL_ART_SCALE * 0.9)); + portraitRight.updateHitbox(); + portraitRight.scrollFactor.set(); + add(portraitRight); + portraitRight.visible = false; - box = new FlxSprite(-20, 45); + box = new FlxSprite(-20, 45); - var hasDialog = false; - switch (PlayState.currentSong.song.toLowerCase()) - { - case 'senpai': - hasDialog = true; - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); - box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); - box.animation.addByIndices('normal', 'Text Box Appear', [4], "", 24); - case 'roses': - hasDialog = true; - FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); + var hasDialog:Bool = false; + switch (PlayState.currentSong.song.toLowerCase()) + { + case 'senpai': + hasDialog = true; + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); + box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); + box.animation.addByIndices('normal', 'Text Box Appear', [4], '', 24); + case 'roses': + hasDialog = true; + FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-senpaiMad'); - box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); - box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], "", 24); + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-senpaiMad'); + box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); + box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], '', 24); - case 'thorns': - hasDialog = true; - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-evil'); - box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); - box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], "", 24); + case 'thorns': + hasDialog = true; + box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-evil'); + box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); + box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], '', 24); - var face:FlxSprite = new FlxSprite(320, 170).loadGraphic(Paths.image('weeb/spiritFaceForward')); - face.setGraphicSize(Std.int(face.width * 6)); - add(face); - } + var face:FlxSprite = new FlxSprite(320, 170).loadGraphic(Paths.image('weeb/spiritFaceForward')); + face.setGraphicSize(Std.int(face.width * 6)); + add(face); + } - this.dialogueList = dialogueList; + this.dialogueList = dialogueList; - if (!hasDialog) - return; + if (!hasDialog) return; - box.animation.play('normalOpen'); - box.setGraphicSize(Std.int(box.width * Constants.PIXEL_ART_SCALE * 0.9)); - box.updateHitbox(); - add(box); + box.animation.play('normalOpen'); + box.setGraphicSize(Std.int(box.width * Constants.PIXEL_ART_SCALE * 0.9)); + box.updateHitbox(); + add(box); - box.screenCenter(X); - portraitLeft.screenCenter(X); + box.screenCenter(X); + portraitLeft.screenCenter(X); - handSelect = new FlxSprite(1042, 590).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); - handSelect.setGraphicSize(Std.int(handSelect.width * Constants.PIXEL_ART_SCALE * 0.9)); - handSelect.updateHitbox(); - handSelect.visible = false; - add(handSelect); + handSelect = new FlxSprite(1042, 590).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); + handSelect.setGraphicSize(Std.int(handSelect.width * Constants.PIXEL_ART_SCALE * 0.9)); + handSelect.updateHitbox(); + handSelect.visible = false; + add(handSelect); - if (!talkingRight) - { - // box.flipX = true; - } + if (!talkingRight) + { + // box.flipX = true; + } - dropText = new FlxText(242, 502, Std.int(FlxG.width * 0.6), "", 32); - dropText.font = 'Pixel Arial 11 Bold'; - dropText.color = 0xFFD89494; - add(dropText); + dropText = new FlxText(242, 502, Std.int(FlxG.width * 0.6), '', 32); + dropText.font = 'Pixel Arial 11 Bold'; + dropText.color = 0xFFD89494; + add(dropText); - swagDialogue = new FlxTypeText(240, 500, Std.int(FlxG.width * 0.6), "", 32); - swagDialogue.font = 'Pixel Arial 11 Bold'; - swagDialogue.color = 0xFF3F2021; - swagDialogue.sounds = [FlxG.sound.load(Paths.sound('pixelText'), 0.6)]; - add(swagDialogue); + swagDialogue = new FlxTypeText(240, 500, Std.int(FlxG.width * 0.6), '', 32); + swagDialogue.font = 'Pixel Arial 11 Bold'; + swagDialogue.color = 0xFF3F2021; + swagDialogue.sounds = [FlxG.sound.load(Paths.sound('pixelText'), 0.6)]; + add(swagDialogue); - dialogue = new Alphabet(0, 80, "", false, true); - // dialogue.x = 90; - // add(dialogue); - } + dialogue = new Alphabet(0, 80, '', false, true); + // dialogue.x = 90; + // add(dialogue); + } - var dialogueOpened:Bool = false; - var dialogueStarted:Bool = false; - var dialogueEnded:Bool = false; + var dialogueOpened:Bool = false; + var dialogueStarted:Bool = false; + var dialogueEnded:Bool = false; - override function update(elapsed:Float) - { - // HARD CODING CUZ IM STUPDI - if (PlayState.currentSong.song.toLowerCase() == 'roses') - portraitLeft.visible = false; - if (PlayState.currentSong.song.toLowerCase() == 'thorns') - { - portraitLeft.color = FlxColor.BLACK; - swagDialogue.color = FlxColor.WHITE; - dropText.color = FlxColor.BLACK; - } + override function update(elapsed:Float):Void + { + // HARD CODING CUZ IM STUPDI + if (PlayState.currentSong.song.toLowerCase() == 'roses') portraitLeft.visible = false; + if (PlayState.currentSong.song.toLowerCase() == 'thorns') + { + portraitLeft.color = FlxColor.BLACK; + swagDialogue.color = FlxColor.WHITE; + dropText.color = FlxColor.BLACK; + } - dropText.text = swagDialogue.text; + dropText.text = swagDialogue.text; - if (box.animation.curAnim != null) - { - if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) - { - box.animation.play('normal'); - dialogueOpened = true; - } - } + if (box.animation.curAnim != null) + { + if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) + { + box.animation.play('normal'); + dialogueOpened = true; + } + } - if (dialogueOpened && !dialogueStarted) - { - startDialogue(); - dialogueStarted = true; - } + if (dialogueOpened && !dialogueStarted) + { + startDialogue(); + dialogueStarted = true; + } - if (FlxG.keys.justPressed.ANY && dialogueEnded) - { - remove(dialogue); + if (FlxG.keys.justPressed.ANY && dialogueEnded) + { + remove(dialogue); - FlxG.sound.play(Paths.sound('clickText'), 0.8); + FlxG.sound.play(Paths.sound('clickText'), 0.8); - if (dialogueList[1] == null && dialogueList[0] != null) - { - if (!isEnding) - { - isEnding = true; + if (dialogueList[1] == null && dialogueList[0] != null) + { + if (!isEnding) + { + isEnding = true; - if (PlayState.currentSong.song.toLowerCase() == 'senpai' || PlayState.currentSong.song.toLowerCase() == 'thorns') - FlxG.sound.music.fadeOut(2.2, 0); + if (PlayState.currentSong.song.toLowerCase() == 'senpai' + || PlayState.currentSong.song.toLowerCase() == 'thorns') FlxG.sound.music.fadeOut(2.2, 0); - new FlxTimer().start(0.2, function(tmr:FlxTimer) - { - box.alpha -= 1 / 5; - bgFade.alpha -= 1 / 5 * 0.7; - portraitLeft.visible = false; - portraitRight.visible = false; - swagDialogue.alpha -= 1 / 5; - handSelect.alpha -= 1 / 5; - dropText.alpha = swagDialogue.alpha; - }, 5); + new FlxTimer().start(0.2, function(tmr:FlxTimer) + { + box.alpha -= 1 / 5; + bgFade.alpha -= 1 / 5 * 0.7; + portraitLeft.visible = false; + portraitRight.visible = false; + swagDialogue.alpha -= 1 / 5; + handSelect.alpha -= 1 / 5; + dropText.alpha = swagDialogue.alpha; + }, 5); - new FlxTimer().start(1.2, function(tmr:FlxTimer) - { - finishThing(); - kill(); - }); - } - } - else - { - dialogueList.remove(dialogueList[0]); - startDialogue(); - } - } - else if (FlxG.keys.justPressed.ANY && dialogueStarted) - swagDialogue.skip(); + new FlxTimer().start(1.2, function(tmr:FlxTimer) + { + finishThing(); + kill(); + }); + } + } + else + { + dialogueList.remove(dialogueList[0]); + startDialogue(); + } + } + else if (FlxG.keys.justPressed.ANY && dialogueStarted) swagDialogue.skip(); - super.update(elapsed); - } + super.update(elapsed); + } - var isEnding:Bool = false; + var isEnding:Bool = false; - function startDialogue():Void - { - cleanDialog(); - // var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); - // dialogue = theDialog; - // add(theDialog); + function startDialogue():Void + { + cleanDialog(); + // var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); + // dialogue = theDialog; + // add(theDialog); - // swagDialogue.text = ; - swagDialogue.resetText(dialogueList[0]); - swagDialogue.start(0.04); - swagDialogue.completeCallback = function() - { - trace("dialogue finish"); - handSelect.visible = true; - dialogueEnded = true; - }; - handSelect.visible = false; - dialogueEnded = false; + // swagDialogue.text = ; + swagDialogue.resetText(dialogueList[0]); + swagDialogue.start(0.04); + swagDialogue.completeCallback = function() + { + trace('dialogue finish'); + handSelect.visible = true; + dialogueEnded = true; + }; + handSelect.visible = false; + dialogueEnded = false; - switch (curCharacter) - { - case 'dad': - portraitRight.visible = false; - if (!portraitLeft.visible) - { - portraitLeft.visible = true; - portraitLeft.animation.play('enter'); - } - case 'bf': - portraitLeft.visible = false; - if (!portraitRight.visible) - { - portraitRight.visible = true; - portraitRight.animation.play('enter'); - } - } - } + switch (curCharacter) + { + case 'dad': + portraitRight.visible = false; + if (!portraitLeft.visible) + { + portraitLeft.visible = true; + portraitLeft.animation.play('enter'); + } + case 'bf': + portraitLeft.visible = false; + if (!portraitRight.visible) + { + portraitRight.visible = true; + portraitRight.animation.play('enter'); + } + } + } - function cleanDialog():Void - { - var splitName:Array = dialogueList[0].split(":"); - curCharacter = splitName[1]; - dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); - } + function cleanDialog():Void + { + var splitName:Array = dialogueList[0].split(':'); + curCharacter = splitName[1]; + dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); + } } diff --git a/source/funkin/Discord.hx b/source/funkin/Discord.hx index 3278a148d..26a96ab52 100644 --- a/source/funkin/Discord.hx +++ b/source/funkin/Discord.hx @@ -7,83 +7,86 @@ import discord_rpc.DiscordRpc; class DiscordClient { - #if discord_rpc - public function new() - { - trace("Discord Client starting..."); - DiscordRpc.start({ - clientID: "814588678700924999", - onReady: onReady, - onError: onError, - onDisconnected: onDisconnected - }); - trace("Discord Client started."); + #if discord_rpc + public function new() + { + trace("Discord Client starting..."); + DiscordRpc.start( + { + clientID: "814588678700924999", + onReady: onReady, + onError: onError, + onDisconnected: onDisconnected + }); + trace("Discord Client started."); - while (true) - { - DiscordRpc.process(); - sleep(2); - // trace("Discord Client Update"); - } + while (true) + { + DiscordRpc.process(); + sleep(2); + // trace("Discord Client Update"); + } - DiscordRpc.shutdown(); - } + DiscordRpc.shutdown(); + } - public static function shutdown() - { - DiscordRpc.shutdown(); - } + public static function shutdown() + { + DiscordRpc.shutdown(); + } - static function onReady() - { - DiscordRpc.presence({ - details: "In the Menus", - state: null, - largeImageKey: 'icon', - largeImageText: "Friday Night Funkin'" - }); - } + static function onReady() + { + DiscordRpc.presence( + { + details: "In the Menus", + state: null, + largeImageKey: 'icon', + largeImageText: "Friday Night Funkin'" + }); + } - static function onError(_code:Int, _message:String) - { - trace('Error! $_code : $_message'); - } + static function onError(_code:Int, _message:String) + { + trace('Error! $_code : $_message'); + } - static function onDisconnected(_code:Int, _message:String) - { - trace('Disconnected! $_code : $_message'); - } + static function onDisconnected(_code:Int, _message:String) + { + trace('Disconnected! $_code : $_message'); + } - public static function initialize() - { - var DiscordDaemon = sys.thread.Thread.create(() -> - { - new DiscordClient(); - }); - trace("Discord Client initialized"); - } + public static function initialize() + { + var DiscordDaemon = sys.thread.Thread.create(() -> + { + new DiscordClient(); + }); + trace("Discord Client initialized"); + } - public static function changePresence(details:String, state:Null, ?smallImageKey:String, ?hasStartTimestamp:Bool, ?endTimestamp:Float) - { - var startTimestamp:Float = if (hasStartTimestamp) Date.now().getTime() else 0; + public static function changePresence(details:String, state:Null, ?smallImageKey:String, ?hasStartTimestamp:Bool, ?endTimestamp:Float) + { + var startTimestamp:Float = if (hasStartTimestamp) Date.now().getTime() else 0; - if (endTimestamp > 0) - { - endTimestamp = startTimestamp + endTimestamp; - } + if (endTimestamp > 0) + { + endTimestamp = startTimestamp + endTimestamp; + } - DiscordRpc.presence({ - details: details, - state: state, - largeImageKey: 'icon', - largeImageText: "Friday Night Funkin'", - smallImageKey: smallImageKey, - // Obtained times are in milliseconds so they are divided so Discord can use it - startTimestamp: Std.int(startTimestamp / 1000), - endTimestamp: Std.int(endTimestamp / 1000) - }); + DiscordRpc.presence( + { + details: details, + state: state, + largeImageKey: 'icon', + largeImageText: "Friday Night Funkin'", + smallImageKey: smallImageKey, + // Obtained times are in milliseconds so they are divided so Discord can use it + startTimestamp: Std.int(startTimestamp / 1000), + endTimestamp: Std.int(endTimestamp / 1000) + }); - // trace('Discord RPC Updated. Arguments: $details, $state, $smallImageKey, $hasStartTimestamp, $endTimestamp'); - } - #end + // trace('Discord RPC Updated. Arguments: $details, $state, $smallImageKey, $hasStartTimestamp, $endTimestamp'); + } + #end } diff --git a/source/funkin/FlxSwf.hx b/source/funkin/FlxSwf.hx index 87d106c0e..d37343894 100644 --- a/source/funkin/FlxSwf.hx +++ b/source/funkin/FlxSwf.hx @@ -7,38 +7,37 @@ import openfl.display.MovieClip; class FlxSwf extends FlxSprite { - public var swf:MovieClip; + public var swf:MovieClip; - public function new() - { - super(); - } + public function new() + { + super(); + } - override function draw() - { - for (camera in cameras) - { - if (!camera.visible || !camera.exists) - continue; + override function draw() + { + for (camera in cameras) + { + if (!camera.visible || !camera.exists) continue; - getScreenPosition(_point, camera).subtractPoint(offset); - // assume no render blit for now - // use camera.canvas - // camera.canvas.graphics. - } - } + getScreenPosition(_point, camera).subtractPoint(offset); + // assume no render blit for now + // use camera.canvas + // camera.canvas.graphics. + } + } } class FlxDrawSwfItem extends FlxDrawBaseItem { - public function new() - { - super(); - type = FlxDrawItemType.TILES; - } + public function new() + { + super(); + type = FlxDrawItemType.TILES; + } - override function render(camera:FlxCamera) - { - super.render(camera); - } + override function render(camera:FlxCamera) + { + super.render(camera); + } } diff --git a/source/funkin/FlxVideo.hx b/source/funkin/FlxVideo.hx index 82e7c366c..9349164b2 100644 --- a/source/funkin/FlxVideo.hx +++ b/source/funkin/FlxVideo.hx @@ -9,53 +9,51 @@ import openfl.net.NetStream; class FlxVideo extends FlxBasic { - var video:Video; - var netStream:NetStream; + var video:Video; + var netStream:NetStream; - public var finishCallback:Void->Void; + public var finishCallback:Void->Void; - /** - * Doesn't actually interact with Flixel shit, only just a pleasant to use class - */ - public function new(vidSrc:String) - { - super(); + /** + * Doesn't actually interact with Flixel shit, only just a pleasant to use class + */ + public function new(vidSrc:String) + { + super(); - video = new Video(); - video.x = 0; - video.y = 0; + video = new Video(); + video.x = 0; + video.y = 0; - FlxG.addChildBelowMouse(video); + FlxG.addChildBelowMouse(video); - var netConnection = new NetConnection(); - netConnection.connect(null); + var netConnection = new NetConnection(); + netConnection.connect(null); - netStream = new NetStream(netConnection); - netStream.client = {onMetaData: client_onMetaData}; - netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); - netStream.play(Paths.file(vidSrc)); - } + netStream = new NetStream(netConnection); + netStream.client = {onMetaData: client_onMetaData}; + netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); + netStream.play(Paths.file(vidSrc)); + } - public function finishVideo():Void - { - netStream.dispose(); - FlxG.removeChild(video); + public function finishVideo():Void + { + netStream.dispose(); + FlxG.removeChild(video); - if (finishCallback != null) - finishCallback(); - } + if (finishCallback != null) finishCallback(); + } - public function client_onMetaData(metaData:Dynamic) - { - video.attachNetStream(netStream); + public function client_onMetaData(metaData:Dynamic) + { + video.attachNetStream(netStream); - video.width = FlxG.width; - video.height = FlxG.height; - } + video.width = FlxG.width; + video.height = FlxG.height; + } - private function netConnection_onNetStatus(event:NetStatusEvent):Void - { - if (event.info.code == 'NetStream.Play.Complete') - finishVideo(); - } + function netConnection_onNetStatus(event:NetStatusEvent):Void + { + if (event.info.code == 'NetStream.Play.Complete') finishVideo(); + } } diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx index 87bdc726a..34794b6ed 100644 --- a/source/funkin/FreeplayState.hx +++ b/source/funkin/FreeplayState.hx @@ -64,13 +64,13 @@ class FreeplayState extends MusicBeatSubstate 0xfff6b604 ]; - private var grpSongs:FlxTypedGroup; - private var grpCapsules:FlxTypedGroup; - private var curPlaying:Bool = false; + var grpSongs:FlxTypedGroup; + var grpCapsules:FlxTypedGroup; + var curPlaying:Bool = false; - private var dj:DJBoyfriend; + var dj:DJBoyfriend; - private var iconArray:Array = []; + var iconArray:Array = []; var typing:FlxInputText; @@ -100,30 +100,23 @@ class FreeplayState extends MusicBeatSubstate if (FlxG.sound.music != null) { - if (!FlxG.sound.music.playing) - FlxG.sound.playMusic(Paths.music('freakyMenu')); + if (!FlxG.sound.music.playing) FlxG.sound.playMusic(Paths.music('freakyMenu')); } - if (StoryMenuState.weekUnlocked[2] || isDebug) - addWeek(['Bopeebo', 'Fresh', 'Dadbattle'], 1, ['dad']); + if (StoryMenuState.weekUnlocked[2] || isDebug) addWeek(['Bopeebo', 'Fresh', 'Dadbattle'], 1, ['dad']); - if (StoryMenuState.weekUnlocked[2] || isDebug) - addWeek(['Spookeez', 'South', 'Monster'], 2, ['spooky', 'spooky', 'monster']); + if (StoryMenuState.weekUnlocked[2] || isDebug) addWeek(['Spookeez', 'South', 'Monster'], 2, ['spooky', 'spooky', 'monster']); - if (StoryMenuState.weekUnlocked[3] || isDebug) - addWeek(['Pico', 'Philly', 'Blammed'], 3, ['pico']); + if (StoryMenuState.weekUnlocked[3] || isDebug) addWeek(['Pico', 'Philly', 'Blammed'], 3, ['pico']); - if (StoryMenuState.weekUnlocked[4] || isDebug) - addWeek(['Satin-Panties', 'High', 'Milf'], 4, ['mom']); + if (StoryMenuState.weekUnlocked[4] || isDebug) addWeek(['Satin-Panties', 'High', 'Milf'], 4, ['mom']); - if (StoryMenuState.weekUnlocked[5] || isDebug) - addWeek(['Cocoa', 'Eggnog', 'Winter-Horrorland'], 5, ['parents-christmas', 'parents-christmas', 'monster-christmas']); + if (StoryMenuState.weekUnlocked[5] || isDebug) addWeek(['Cocoa', 'Eggnog', 'Winter-Horrorland'], 5, + ['parents-christmas', 'parents-christmas', 'monster-christmas']); - if (StoryMenuState.weekUnlocked[6] || isDebug) - addWeek(['Senpai', 'Roses', 'Thorns'], 6, ['senpai', 'senpai', 'spirit']); + if (StoryMenuState.weekUnlocked[6] || isDebug) addWeek(['Senpai', 'Roses', 'Thorns'], 6, ['senpai', 'senpai', 'spirit']); - if (StoryMenuState.weekUnlocked[7] || isDebug) - addWeek(['Ugh', 'Guns', 'Stress'], 7, ['tankman']); + if (StoryMenuState.weekUnlocked[7] || isDebug) addWeek(['Ugh', 'Guns', 'Stress'], 7, ['tankman']); addWeek(["Darnell", "lit-up", "2hot", "blazin"], 8, ['darnell']); @@ -469,16 +462,14 @@ class FreeplayState extends MusicBeatSubstate public function addWeek(songs:Array, weekNum:Int, ?songCharacters:Array) { - if (songCharacters == null) - songCharacters = ['bf']; + if (songCharacters == null) songCharacters = ['bf']; var num:Int = 0; for (song in songs) { addSong(song, weekNum, songCharacters[num]); - if (songCharacters.length != 1) - num++; + if (songCharacters.length != 1) num++; } } @@ -506,14 +497,15 @@ class FreeplayState extends MusicBeatSubstate songs[curSelected].isFav = !songs[curSelected].isFav; if (songs[curSelected].isFav) { - FlxTween.tween(grpCapsules.members[realShit], {angle: 360}, 0.4, { - ease: FlxEase.elasticOut, - onComplete: _ -> + FlxTween.tween(grpCapsules.members[realShit], {angle: 360}, 0.4, { - grpCapsules.members[realShit].favIcon.visible = true; - grpCapsules.members[realShit].favIcon.animation.play("fav"); - } - }); + ease: FlxEase.elasticOut, + onComplete: _ -> + { + grpCapsules.members[realShit].favIcon.visible = true; + grpCapsules.members[realShit].favIcon.animation.play("fav"); + } + }); } else { @@ -529,8 +521,7 @@ class FreeplayState extends MusicBeatSubstate } } - if (FlxG.keys.justPressed.T) - typing.hasFocus = true; + if (FlxG.keys.justPressed.T) typing.hasFocus = true; if (FlxG.sound.music != null) { @@ -588,8 +579,7 @@ class FreeplayState extends MusicBeatSubstate if (FlxG.touches.getFirst() != null) { - if (touchTimer >= 1.5) - accepted = true; + if (touchTimer >= 1.5) accepted = true; touchTimer += elapsed; var touch:FlxTouch = FlxG.touches.getFirst(); @@ -612,16 +602,14 @@ class FreeplayState extends MusicBeatSubstate if (Math.abs(dxTouch) >= 100) { touchX = touch.screenX; - if (dxTouch != 0) - dxTouch < 0 ? changeDiff(1) : changeDiff(-1); + if (dxTouch != 0) dxTouch < 0 ? changeDiff(1) : changeDiff(-1); } if (Math.abs(dyTouch) >= 100) { touchY = touch.screenY; - if (dyTouch != 0) - dyTouch < 0 ? changeSelection(1) : changeSelection(-1); + if (dyTouch != 0) dyTouch < 0 ? changeSelection(1) : changeSelection(-1); // changeSelection(1); } } @@ -651,14 +639,12 @@ class FreeplayState extends MusicBeatSubstate { spamTimer = 0; - if (controls.UI_UP) - changeSelection(-1); + if (controls.UI_UP) changeSelection(-1); else changeSelection(1); } } - else if (spamTimer >= 0.9) - spamming = true; + else if (spamTimer >= 0.9) spamming = true; } else { @@ -763,10 +749,8 @@ class FreeplayState extends MusicBeatSubstate curDifficulty += change; - if (curDifficulty < 0) - curDifficulty = 2; - if (curDifficulty > 2) - curDifficulty = 0; + if (curDifficulty < 0) curDifficulty = 2; + if (curDifficulty > 2) curDifficulty = 0; // intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); @@ -826,10 +810,8 @@ class FreeplayState extends MusicBeatSubstate curSelected += change; - if (curSelected < 0) - curSelected = grpCapsules.members.length - 1; - if (curSelected >= grpCapsules.members.length) - curSelected = 0; + if (curSelected < 0) curSelected = grpCapsules.members.length - 1; + if (curSelected >= grpCapsules.members.length) curSelected = 0; // selector.y = (70 * curSelected) + 30; @@ -859,12 +841,10 @@ class FreeplayState extends MusicBeatSubstate capsule.targetPos.x = 270 + (60 * (Math.sin(index - curSelected))); // capsule.targetPos.x = 320 + (40 * (index - curSelected)); - if (index < curSelected) - capsule.targetPos.y -= 100; // another 100 for good measure + if (index < curSelected) capsule.targetPos.y -= 100; // another 100 for good measure } - if (grpCapsules.members.length > 0) - grpCapsules.members[curSelected].selected = true; + if (grpCapsules.members.length > 0) grpCapsules.members[curSelected].selected = true; } } @@ -892,10 +872,8 @@ class DifficultySelector extends FlxSprite override function update(elapsed:Float) { - if (flipX && controls.UI_RIGHT_P) - moveShitDown(); - if (!flipX && controls.UI_LEFT_P) - moveShitDown(); + if (flipX && controls.UI_RIGHT_P) moveShitDown(); + if (!flipX && controls.UI_LEFT_P) moveShitDown(); super.update(elapsed); } diff --git a/source/funkin/GitarooPause.hx b/source/funkin/GitarooPause.hx index d22620a46..fda809548 100644 --- a/source/funkin/GitarooPause.hx +++ b/source/funkin/GitarooPause.hx @@ -6,83 +6,81 @@ import funkin.play.PlayState; class GitarooPause extends MusicBeatState { - var replayButton:FlxSprite; - var cancelButton:FlxSprite; + var replayButton:FlxSprite; + var cancelButton:FlxSprite; - var replaySelect:Bool = false; + var replaySelect:Bool = false; - public function new():Void - { - super(); - } + public function new():Void + { + super(); + } - override function create() - { - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); + override function create() + { + if (FlxG.sound.music != null) FlxG.sound.music.stop(); - var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('pauseAlt/pauseBG')); - add(bg); + var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('pauseAlt/pauseBG')); + add(bg); - var bf:FlxSprite = new FlxSprite(0, 30); - bf.frames = Paths.getSparrowAtlas('pauseAlt/bfLol'); - bf.animation.addByPrefix('lol', "funnyThing", 13); - bf.animation.play('lol'); - add(bf); - bf.screenCenter(X); + var bf:FlxSprite = new FlxSprite(0, 30); + bf.frames = Paths.getSparrowAtlas('pauseAlt/bfLol'); + bf.animation.addByPrefix('lol', "funnyThing", 13); + bf.animation.play('lol'); + add(bf); + bf.screenCenter(X); - replayButton = new FlxSprite(FlxG.width * 0.28, FlxG.height * 0.7); - replayButton.frames = Paths.getSparrowAtlas('pauseAlt/pauseUI'); - replayButton.animation.addByPrefix('selected', 'bluereplay', 0, false); - replayButton.animation.appendByPrefix('selected', 'yellowreplay'); - replayButton.animation.play('selected'); - add(replayButton); + replayButton = new FlxSprite(FlxG.width * 0.28, FlxG.height * 0.7); + replayButton.frames = Paths.getSparrowAtlas('pauseAlt/pauseUI'); + replayButton.animation.addByPrefix('selected', 'bluereplay', 0, false); + replayButton.animation.appendByPrefix('selected', 'yellowreplay'); + replayButton.animation.play('selected'); + add(replayButton); - cancelButton = new FlxSprite(FlxG.width * 0.58, replayButton.y); - cancelButton.frames = Paths.getSparrowAtlas('pauseAlt/pauseUI'); - cancelButton.animation.addByPrefix('selected', 'bluecancel', 0, false); - cancelButton.animation.appendByPrefix('selected', 'cancelyellow'); - cancelButton.animation.play('selected'); - add(cancelButton); + cancelButton = new FlxSprite(FlxG.width * 0.58, replayButton.y); + cancelButton.frames = Paths.getSparrowAtlas('pauseAlt/pauseUI'); + cancelButton.animation.addByPrefix('selected', 'bluecancel', 0, false); + cancelButton.animation.appendByPrefix('selected', 'cancelyellow'); + cancelButton.animation.play('selected'); + add(cancelButton); - changeThing(); + changeThing(); - super.create(); - } + super.create(); + } - override function update(elapsed:Float) - { - if (controls.UI_LEFT_P || controls.UI_RIGHT_P) - changeThing(); + override function update(elapsed:Float) + { + if (controls.UI_LEFT_P || controls.UI_RIGHT_P) changeThing(); - if (controls.ACCEPT) - { - if (replaySelect) - { - FlxG.switchState(new PlayState()); - } - else - { - FlxG.switchState(new MainMenuState()); - } - } + if (controls.ACCEPT) + { + if (replaySelect) + { + FlxG.switchState(new PlayState()); + } + else + { + FlxG.switchState(new MainMenuState()); + } + } - super.update(elapsed); - } + super.update(elapsed); + } - function changeThing():Void - { - replaySelect = !replaySelect; + function changeThing():Void + { + replaySelect = !replaySelect; - if (replaySelect) - { - cancelButton.animation.curAnim.curFrame = 0; - replayButton.animation.curAnim.curFrame = 1; - } - else - { - cancelButton.animation.curAnim.curFrame = 1; - replayButton.animation.curAnim.curFrame = 0; - } - } + if (replaySelect) + { + cancelButton.animation.curAnim.curFrame = 0; + replayButton.animation.curAnim.curFrame = 1; + } + else + { + cancelButton.animation.curAnim.curFrame = 1; + replayButton.animation.curAnim.curFrame = 0; + } + } } diff --git a/source/funkin/Highscore.hx b/source/funkin/Highscore.hx index 9a878bc40..08ad7dcba 100644 --- a/source/funkin/Highscore.hx +++ b/source/funkin/Highscore.hx @@ -2,154 +2,147 @@ package funkin; class Highscore { - #if (haxe >= "4.0.0") - public static var songScores:Map = new Map(); - #else - public static var songScores:Map = new Map(); - #end + #if (haxe >= "4.0.0") + public static var songScores:Map = new Map(); + #else + public static var songScores:Map = new Map(); + #end - #if (haxe >= "4.0.0") - public static var songCompletion:Map = new Map(); - #else - public static var songCompletion:Map = new Map(); - #end + #if (haxe >= "4.0.0") + public static var songCompletion:Map = new Map(); + #else + public static var songCompletion:Map = new Map(); + #end - public static var tallies:Tallies = new Tallies(); + public static var tallies:Tallies = new Tallies(); - public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Bool - { - var formattedSong:String = formatSong(song, diff); + public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Bool + { + var formattedSong:String = formatSong(song, diff); - #if newgrounds - NGio.postScore(score, song); - #end + #if newgrounds + NGio.postScore(score, song); + #end - if (songScores.exists(formattedSong)) - { - if (songScores.get(formattedSong) < score) - { - setScore(formattedSong, score); - return true; - // new highscore - } - } - else - setScore(formattedSong, score); + if (songScores.exists(formattedSong)) + { + if (songScores.get(formattedSong) < score) + { + setScore(formattedSong, score); + return true; + // new highscore + } + } + else + setScore(formattedSong, score); - return false; - } + return false; + } - public static function saveCompletion(song:String, completion:Float, ?diff:Int = 0):Bool - { - var formattedSong:String = formatSong(song, diff); + public static function saveCompletion(song:String, completion:Float, ?diff:Int = 0):Bool + { + var formattedSong:String = formatSong(song, diff); - if (songCompletion.exists(formattedSong)) - { - if (songCompletion.get(formattedSong) < completion) - { - setCompletion(formattedSong, completion); - return true; - } - } - else - setCompletion(formattedSong, completion); + if (songCompletion.exists(formattedSong)) + { + if (songCompletion.get(formattedSong) < completion) + { + setCompletion(formattedSong, completion); + return true; + } + } + else + setCompletion(formattedSong, completion); - return false; - } + return false; + } - public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void - { - #if newgrounds - NGio.postScore(score, "Week " + week); - #end + public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void + { + #if newgrounds + NGio.postScore(score, "Week " + week); + #end - var formattedSong:String = formatSong('week' + week, diff); + var formattedSong:String = formatSong('week' + week, diff); - if (songScores.exists(formattedSong)) - { - if (songScores.get(formattedSong) < score) - setScore(formattedSong, score); - } - else - setScore(formattedSong, score); - } + if (songScores.exists(formattedSong)) + { + if (songScores.get(formattedSong) < score) setScore(formattedSong, score); + } + else + setScore(formattedSong, score); + } - static function setCompletion(formattedSong:String, completion:Float):Void - { - songCompletion.set(formattedSong, completion); - FlxG.save.data.songCompletion = songCompletion; - FlxG.save.flush(); - } + static function setCompletion(formattedSong:String, completion:Float):Void + { + songCompletion.set(formattedSong, completion); + FlxG.save.data.songCompletion = songCompletion; + FlxG.save.flush(); + } - /** - * YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE - */ - static function setScore(formattedSong:String, score:Int):Void - { - /** GeoKureli - * References to Highscore were wrapped in `#if !switch` blocks. I wasn't sure if this - * is because switch doesn't use NGio, or because switch has a different saving method. - * I moved the compiler flag here, rather than using it everywhere else. - */ - #if !switch - // Reminder that I don't need to format this song, it should come formatted! - songScores.set(formattedSong, score); - FlxG.save.data.songScores = songScores; - FlxG.save.flush(); - #end - } + /** + * YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE + */ + static function setScore(formattedSong:String, score:Int):Void + { + /** GeoKureli + * References to Highscore were wrapped in `#if !switch` blocks. I wasn't sure if this + * is because switch doesn't use NGio, or because switch has a different saving method. + * I moved the compiler flag here, rather than using it everywhere else. + */ + #if ! switch + // Reminder that I don't need to format this song, it should come formatted! + songScores.set(formattedSong, score); + FlxG.save.data.songScores = songScores; + FlxG.save.flush(); + #end + } - public static function formatSong(song:String, diff:Int):String - { - var daSong:String = song; + public static function formatSong(song:String, diff:Int):String + { + var daSong:String = song; - if (diff == 0) - daSong += '-easy'; - else if (diff == 2) - daSong += '-hard'; + if (diff == 0) daSong += '-easy'; + else if (diff == 2) daSong += '-hard'; - return daSong; - } + return daSong; + } - public static function getScore(song:String, diff:Int):Int - { - if (!songScores.exists(formatSong(song, diff))) - setScore(formatSong(song, diff), 0); + public static function getScore(song:String, diff:Int):Int + { + if (!songScores.exists(formatSong(song, diff))) setScore(formatSong(song, diff), 0); - return songScores.get(formatSong(song, diff)); - } + return songScores.get(formatSong(song, diff)); + } - public static function getCompletion(song, diff):Float - { - if (!songCompletion.exists(formatSong(song, diff))) - setCompletion(formatSong(song, diff), 0); + public static function getCompletion(song, diff):Float + { + if (!songCompletion.exists(formatSong(song, diff))) setCompletion(formatSong(song, diff), 0); - return songCompletion.get(formatSong(song, diff)); - } + return songCompletion.get(formatSong(song, diff)); + } - public static function getAllScores() - { - trace(songScores.toString()); - } + public static function getAllScores() + { + trace(songScores.toString()); + } - public static function getWeekScore(week:Int, diff:Int):Int - { - if (!songScores.exists(formatSong('week' + week, diff))) - setScore(formatSong('week' + week, diff), 0); + public static function getWeekScore(week:Int, diff:Int):Int + { + if (!songScores.exists(formatSong('week' + week, diff))) setScore(formatSong('week' + week, diff), 0); - return songScores.get(formatSong('week' + week, diff)); - } + return songScores.get(formatSong('week' + week, diff)); + } - public static function load():Void - { - if (FlxG.save.data.songScores != null) - { - songScores = FlxG.save.data.songScores; - } + public static function load():Void + { + if (FlxG.save.data.songScores != null) + { + songScores = FlxG.save.data.songScores; + } - if (FlxG.save.data.songCompletion != null) - songCompletion = FlxG.save.data.songCompletion; - } + if (FlxG.save.data.songCompletion != null) songCompletion = FlxG.save.data.songCompletion; + } } // i only do forward metadata cuz george did! @@ -157,46 +150,47 @@ class Highscore @:forward abstract Tallies(RawTallies) { - public function new() - { - this = { - combo: 0, - missed: 0, - shit: 0, - bad: 0, - good: 0, - sick: 0, - totalNotes: 0, - totalNotesHit: 0, - maxCombo: 0, - isNewHighscore: false - } - } + public function new() + { + this = + { + combo: 0, + missed: 0, + shit: 0, + bad: 0, + good: 0, + sick: 0, + totalNotes: 0, + totalNotesHit: 0, + maxCombo: 0, + isNewHighscore: false + } + } } typedef RawTallies = { - var combo:Int; + var combo:Int; - /** - * How many notes you let scroll by. - */ - var missed:Int; + /** + * How many notes you let scroll by. + */ + var missed:Int; - var shit:Int; - var bad:Int; - var good:Int; - var sick:Int; - var maxCombo:Int; - var isNewHighscore:Bool; + var shit:Int; + var bad:Int; + var good:Int; + var sick:Int; + var maxCombo:Int; + var isNewHighscore:Bool; - /** - * How many notes total that you hit. (NOT how many notes total in the song!) - */ - var totalNotesHit:Int; + /** + * How many notes total that you hit. (NOT how many notes total in the song!) + */ + var totalNotesHit:Int; - /** - * How many notes PASSED BY AND/OR HIT!!! - */ - var totalNotes:Int; + /** + * How many notes PASSED BY AND/OR HIT!!! + */ + var totalNotes:Int; } diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 85bc2bcf0..f7f662b7b 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -1,5 +1,6 @@ package funkin; +import funkin.play.stage.StageData.StageDataParser; import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.TransitionData; @@ -13,15 +14,10 @@ import funkin.play.PlayState; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.play.event.SongEvent.SongEventParser; import funkin.play.song.SongData.SongDataParser; -import funkin.play.stage.StageData; import funkin.ui.PreferencesMenu; import funkin.util.WindowUtil; import funkin.util.macro.MacroUtil; import openfl.display.BitmapData; -#if colyseus -import io.colyseus.Client; -import io.colyseus.Room; -#end #if discord_rpc import Discord.DiscordClient; #end @@ -44,8 +40,7 @@ class InitState extends FlxTransitionableState #if discord_rpc DiscordClient.initialize(); - Application.current.onExit.add(function(exitCode) - { + Application.current.onExit.add(function(exitCode) { DiscordClient.shutdown(); }); #end @@ -54,19 +49,19 @@ class InitState extends FlxTransitionableState // This big obnoxious white button is for MOBILE, so that you can press it // easily with your finger when debug bullshit pops up during testing lol! - FlxG.debugger.addButton(LEFT, new BitmapData(200, 200), function() - { + FlxG.debugger.addButton(LEFT, new BitmapData(200, 200), function() { FlxG.debugger.visible = false; }); - FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFFCC2233), function() - { + FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFFCC2233), function() { if (FlxG.vcr.paused) { FlxG.vcr.resume(); for (snd in FlxG.sound.list) + { snd.resume(); + } FlxG.sound.music.resume(); } @@ -75,14 +70,15 @@ class InitState extends FlxTransitionableState FlxG.vcr.pause(); for (snd in FlxG.sound.list) + { snd.pause(); + } FlxG.sound.music.pause(); } }); - FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFF2222CC), function() - { + FlxG.debugger.addButton(CENTER, new BitmapData(20, 20, true, 0xFF2222CC), function() { FlxG.game.debugger.vcr.onStep(); for (snd in FlxG.sound.list) @@ -118,10 +114,8 @@ class InitState extends FlxTransitionableState // IF/WHEN MY PR GOES THRU AND IT GETS INTO MAIN FLIXEL, DELETE THIS CHUNKOF CODE, AND THEN UNCOMMENT THE LINE BELOW // FlxG.sound.loadSavedPrefs(); - if (FlxG.save.data.volume != null) - FlxG.sound.volume = FlxG.save.data.volume; - if (FlxG.save.data.mute != null) - FlxG.sound.muted = FlxG.save.data.mute; + if (FlxG.save.data.volume != null) FlxG.sound.volume = FlxG.save.data.volume; + if (FlxG.save.data.mute != null) FlxG.sound.muted = FlxG.save.data.mute; // Make errors and warnings less annoying. LogStyle.ERROR.openConsole = false; @@ -144,16 +138,13 @@ class InitState extends FlxTransitionableState // WEEK UNLOCK PROGRESSION!! // StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked; - if (StoryMenuState.weekUnlocked.length < 4) - StoryMenuState.weekUnlocked.insert(0, true); + if (StoryMenuState.weekUnlocked.length < 4) StoryMenuState.weekUnlocked.insert(0, true); // QUICK PATCH OOPS! - if (!StoryMenuState.weekUnlocked[0]) - StoryMenuState.weekUnlocked[0] = true; + if (!StoryMenuState.weekUnlocked[0]) StoryMenuState.weekUnlocked[0] = true; } - if (FlxG.save.data.seenVideo != null) - VideoState.seenVideo = FlxG.save.data.seenVideo; + if (FlxG.save.data.seenVideo != null) VideoState.seenVideo = FlxG.save.data.seenVideo; // ===== fuck outta here ===== // @@ -174,9 +165,9 @@ class InitState extends FlxTransitionableState ModuleHandler.callOnCreate(); #if song - var song = getSong(); + var song:String = getSong(); - var weeks = [ + var weeks:Array> = [ ['bopeebo', 'fresh', 'dadbattle'], ['spookeez', 'south', 'monster'], ['spooky', 'spooky', 'monster'], @@ -187,7 +178,7 @@ class InitState extends FlxTransitionableState ['ugh', 'guns', 'stress'] ]; - var week = 0; + var week:Int = 0; for (i in 0...weeks.length) { if (weeks[i].contains(song)) @@ -197,20 +188,24 @@ class InitState extends FlxTransitionableState } } - if (week == 0) - throw 'Invalid -D song=$song'; + if (week == 0) throw 'Invalid -D song=$song'; startSong(week, song, false); #elseif week - var week = getWeek(); + var week:Int = getWeek(); - var songs = [ - 'bopeebo', 'spookeez', 'spooky', 'pico', - 'satin-panties', 'cocoa', 'senpai', 'ugh' + var songs:Array = [ + 'bopeebo', + 'spookeez', + 'spooky', + 'pico', + 'satin-panties', + 'cocoa', + 'senpai', + 'ugh' ]; - if (week <= 0 || week >= songs.length) - throw "invalid -D week=" + week; + if (week <= 0 || week >= songs.length) throw 'invalid -D week=' + week; startSong(week, songs[week - 1], true); #elseif FREEPLAY @@ -235,9 +230,9 @@ class InitState extends FlxTransitionableState #end } - function startSong(week, song, isStoryMode) + function startSong(week, song, isStoryMode):Void { - var dif = getDif(); + var dif:Int = getDif(); PlayState.currentSong = SongLoad.loadFromJson(song, song); PlayState.currentSong_NEW = SongDataParser.fetchSong(song); @@ -256,11 +251,11 @@ class InitState extends FlxTransitionableState } } -function getWeek() - return Std.parseInt(MacroUtil.getDefine("week")); +function getWeek():Int + return Std.parseInt(MacroUtil.getDefine('week')); -function getSong() - return MacroUtil.getDefine("song"); +function getSong():String + return MacroUtil.getDefine('song'); -function getDif() - return Std.parseInt(MacroUtil.getDefine("dif", "1")); +function getDif():Int + return Std.parseInt(MacroUtil.getDefine('dif', '1')); diff --git a/source/funkin/InputFormatter.hx b/source/funkin/InputFormatter.hx index b2d3f596a..ebcba22fa 100644 --- a/source/funkin/InputFormatter.hx +++ b/source/funkin/InputFormatter.hx @@ -9,192 +9,190 @@ using flixel.util.FlxStringUtil; class InputFormatter { - static public function format(id:Int, device:Device):String - { - return switch (device) - { - case Keys: getKeyName(id); - case Gamepad(gamepadID): getButtonName(id, FlxG.gamepads.getByID(gamepadID)); - } - } + static public function format(id:Int, device:Device):String + { + return switch (device) + { + case Keys: getKeyName(id); + case Gamepad(gamepadID): getButtonName(id, FlxG.gamepads.getByID(gamepadID)); + } + } - static public function getKeyName(id:Int):String - { - return switch (id) - { - case ZERO: "0"; - case ONE: "1"; - case TWO: "2"; - case THREE: "3"; - case FOUR: "4"; - case FIVE: "5"; - case SIX: "6"; - case SEVEN: "7"; - case EIGHT: "8"; - case NINE: "9"; - case PAGEUP: "PgUp"; - case PAGEDOWN: "PgDown"; - // case HOME : "Hm"; - // case END : "End"; - // case INSERT : "Ins"; - // case ESCAPE : "Esc"; - // case MINUS : "-"; - // case PLUS : "+"; - // case DELETE : "Del"; - case BACKSPACE: "BckSpc"; - case LBRACKET: "["; - case RBRACKET: "]"; - case BACKSLASH: "\\"; - case CAPSLOCK: "Caps"; - case SEMICOLON: ";"; - case QUOTE: "'"; - // case ENTER : "Ent"; - // case SHIFT : "Shf"; - case COMMA: ","; - case PERIOD: "."; - case SLASH: "/"; - case GRAVEACCENT: "`"; - case CONTROL: "Ctrl"; - case ALT: "Alt"; - // case SPACE : "Spc"; - // case UP : "Up"; - // case DOWN : "Dn"; - // case LEFT : "Lf"; - // case RIGHT : "Rt"; - // case TAB : "Tab"; - case PRINTSCREEN: "PrtScrn"; - case NUMPADZERO: "#0"; - case NUMPADONE: "#1"; - case NUMPADTWO: "#2"; - case NUMPADTHREE: "#3"; - case NUMPADFOUR: "#4"; - case NUMPADFIVE: "#5"; - case NUMPADSIX: "#6"; - case NUMPADSEVEN: "#7"; - case NUMPADEIGHT: "#8"; - case NUMPADNINE: "#9"; - case NUMPADMINUS: "#-"; - case NUMPADPLUS: "#+"; - case NUMPADPERIOD: "#."; - case NUMPADMULTIPLY: "#*"; - default: titleCase(FlxKey.toStringMap[id]); - } - } + static public function getKeyName(id:Int):String + { + return switch (id) + { + case ZERO: "0"; + case ONE: "1"; + case TWO: "2"; + case THREE: "3"; + case FOUR: "4"; + case FIVE: "5"; + case SIX: "6"; + case SEVEN: "7"; + case EIGHT: "8"; + case NINE: "9"; + case PAGEUP: "PgUp"; + case PAGEDOWN: "PgDown"; + // case HOME : "Hm"; + // case END : "End"; + // case INSERT : "Ins"; + // case ESCAPE : "Esc"; + // case MINUS : "-"; + // case PLUS : "+"; + // case DELETE : "Del"; + case BACKSPACE: "BckSpc"; + case LBRACKET: "["; + case RBRACKET: "]"; + case BACKSLASH: "\\"; + case CAPSLOCK: "Caps"; + case SEMICOLON: ";"; + case QUOTE: "'"; + // case ENTER : "Ent"; + // case SHIFT : "Shf"; + case COMMA: ","; + case PERIOD: "."; + case SLASH: "/"; + case GRAVEACCENT: "`"; + case CONTROL: "Ctrl"; + case ALT: "Alt"; + // case SPACE : "Spc"; + // case UP : "Up"; + // case DOWN : "Dn"; + // case LEFT : "Lf"; + // case RIGHT : "Rt"; + // case TAB : "Tab"; + case PRINTSCREEN: "PrtScrn"; + case NUMPADZERO: "#0"; + case NUMPADONE: "#1"; + case NUMPADTWO: "#2"; + case NUMPADTHREE: "#3"; + case NUMPADFOUR: "#4"; + case NUMPADFIVE: "#5"; + case NUMPADSIX: "#6"; + case NUMPADSEVEN: "#7"; + case NUMPADEIGHT: "#8"; + case NUMPADNINE: "#9"; + case NUMPADMINUS: "#-"; + case NUMPADPLUS: "#+"; + case NUMPADPERIOD: "#."; + case NUMPADMULTIPLY: "#*"; + default: titleCase(FlxKey.toStringMap[id]); + } + } - static var dirReg = ~/^(l|r).?-(left|right|down|up)$/; + static var dirReg = ~/^(l|r).?-(left|right|down|up)$/; - inline static public function getButtonName(id:Int, gamepad:FlxGamepad):String - { - return switch (gamepad.getInputLabel(id)) - { - // case null | "": shortenButtonName(FlxGamepadInputID.toStringMap[id]); - case label: shortenButtonName(label); - } - } + inline static public function getButtonName(id:Int, gamepad:FlxGamepad):String + { + return switch (gamepad.getInputLabel(id)) + { + // case null | "": shortenButtonName(FlxGamepadInputID.toStringMap[id]); + case label: shortenButtonName(label); + } + } - static function shortenButtonName(name:String) - { - return switch (name == null ? "" : name.toLowerCase()) - { - case "": "[?]"; - // case "square" : "[]"; - // case "circle" : "()"; - // case "triangle": "/\\"; - // case "plus" : "+"; - // case "minus" : "-"; - // case "home" : "Hm"; - // case "guide" : "Gd"; - // case "back" : "Bk"; - // case "select" : "Bk"; - // case "start" : "St"; - // case "left" : "Lf"; - // case "right" : "Rt"; - // case "down" : "Dn"; - // case "up" : "Up"; - case dir if (dirReg.match(dir)): - dirReg.matched(1).toUpperCase() + " " + titleCase(dirReg.matched(2)); - case label: titleCase(label); - } - } + static function shortenButtonName(name:String) + { + return switch (name == null ? "" : name.toLowerCase()) + { + case "": "[?]"; + // case "square" : "[]"; + // case "circle" : "()"; + // case "triangle": "/\\"; + // case "plus" : "+"; + // case "minus" : "-"; + // case "home" : "Hm"; + // case "guide" : "Gd"; + // case "back" : "Bk"; + // case "select" : "Bk"; + // case "start" : "St"; + // case "left" : "Lf"; + // case "right" : "Rt"; + // case "down" : "Dn"; + // case "up" : "Up"; + case dir if (dirReg.match(dir)): + dirReg.matched(1).toUpperCase() + " " + titleCase(dirReg.matched(2)); + case label: titleCase(label); + } + } - inline static function titleCaseTrim(str:String, length = 8) - { - return str.charAt(0).toUpperCase() + str.substr(1, length - 1).toLowerCase(); - } + inline static function titleCaseTrim(str:String, length = 8) + { + return str.charAt(0).toUpperCase() + str.substr(1, length - 1).toLowerCase(); + } - inline static function titleCase(str:String) - { - return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); - } + inline static function titleCase(str:String) + { + return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); + } - inline static public function parsePadName(name:String):ControllerName - { - return ControllerName.parseName(name); - } + inline static public function parsePadName(name:String):ControllerName + { + return ControllerName.parseName(name); + } - inline static public function getPadName(gamepad:FlxGamepad):ControllerName - { - return ControllerName.getName(gamepad); - } + inline static public function getPadName(gamepad:FlxGamepad):ControllerName + { + return ControllerName.getName(gamepad); + } - inline static public function getPadNameById(id:Int):ControllerName - { - return ControllerName.getNameById(id); - } + inline static public function getPadNameById(id:Int):ControllerName + { + return ControllerName.getNameById(id); + } } @:forward @:enum abstract ControllerName(String) from String to String { - var OUYA = "Ouya"; - var PS4 = "PS4"; - var LOGI = "Logi"; - var XBOX = "XBox"; - var XINPUT = "XInput"; - var WII = "Wii"; - var PRO_CON = "Pro_Con"; - var JOYCONS = "Joycons"; - var JOYCON_L = "Joycon_L"; - var JOYCON_R = "Joycon_R"; - var MFI = "MFI"; - var PAD = "Pad"; + var OUYA = "Ouya"; + var PS4 = "PS4"; + var LOGI = "Logi"; + var XBOX = "XBox"; + var XINPUT = "XInput"; + var WII = "Wii"; + var PRO_CON = "Pro_Con"; + var JOYCONS = "Joycons"; + var JOYCON_L = "Joycon_L"; + var JOYCON_R = "Joycon_R"; + var MFI = "MFI"; + var PAD = "Pad"; - static public function getAssetByDevice(device:Device):String - { - return switch (device) - { - case Keys: getAsset(null); - case Gamepad(id): getAsset(FlxG.gamepads.getByID(id)); - } - } + static public function getAssetByDevice(device:Device):String + { + return switch (device) + { + case Keys: getAsset(null); + case Gamepad(id): getAsset(FlxG.gamepads.getByID(id)); + } + } - static public function getAsset(gamepad:FlxGamepad):String - { - if (gamepad == null) - return 'assets/images/ui/devices/Keys.png'; + static public function getAsset(gamepad:FlxGamepad):String + { + if (gamepad == null) return 'assets/images/ui/devices/Keys.png'; - final name = parseName(gamepad.name); - var path = 'assets/images/ui/devices/$name.png'; - if (openfl.utils.Assets.exists(path)) - return path; + final name = parseName(gamepad.name); + var path = 'assets/images/ui/devices/$name.png'; + if (openfl.utils.Assets.exists(path)) return path; - return 'assets/images/ui/devices/Pad.png'; - } + return 'assets/images/ui/devices/Pad.png'; + } - inline static public function getNameById(id:Int):ControllerName - return getName(FlxG.gamepads.getByID(id)); + inline static public function getNameById(id:Int):ControllerName + return getName(FlxG.gamepads.getByID(id)); - inline static public function getName(gamepad:FlxGamepad):ControllerName - return parseName(gamepad.name); + inline static public function getName(gamepad:FlxGamepad):ControllerName + return parseName(gamepad.name); - static public function parseName(name:String):ControllerName - { - name = name.toLowerCase().remove("-").remove("_"); - return if (name.contains("ouya")) OUYA; else if (name.contains("wireless controller") - || name.contains("ps4")) PS4; else if (name.contains("logitech")) LOGI; else if (name.contains("xbox")) XBOX else if (name.contains("xinput")) - XINPUT; else if (name.contains("nintendo rvlcnt01tr") - || name.contains("nintendo rvlcnt01")) WII; else if (name.contains("mayflash wiimote pc adapter")) WII; else if (name.contains("pro controller")) - PRO_CON; else if (name.contains("joycon l+r")) JOYCONS; else if (name.contains("joycon (l)")) JOYCON_L; else if (name.contains("joycon (r)")) - JOYCON_R; else if (name.contains("mfi")) MFI; else PAD; - } + static public function parseName(name:String):ControllerName + { + name = name.toLowerCase().remove("-").remove("_"); + return if (name.contains("ouya")) OUYA; else if (name.contains("wireless controller") + || name.contains("ps4")) PS4; else if (name.contains("logitech")) LOGI; else if (name.contains("xbox")) XBOX else if (name.contains("xinput")) + XINPUT; else if (name.contains("nintendo rvlcnt01tr") + || name.contains("nintendo rvlcnt01")) WII; else if (name.contains("mayflash wiimote pc adapter")) WII; else if (name.contains("pro controller")) + PRO_CON; else if (name.contains("joycon l+r")) JOYCONS; else if (name.contains("joycon (l)")) JOYCON_L; else if (name.contains("joycon (r)")) + JOYCON_R; else if (name.contains("mfi")) MFI; else PAD; + } } diff --git a/source/funkin/LatencyState.hx b/source/funkin/LatencyState.hx index 015f7103f..256efde5c 100644 --- a/source/funkin/LatencyState.hx +++ b/source/funkin/LatencyState.hx @@ -16,311 +16,304 @@ import openfl.events.KeyboardEvent; class LatencyState extends MusicBeatSubstate { - var offsetText:FlxText; - var noteGrp:FlxTypedGroup; - var strumLine:FlxSprite; + var offsetText:FlxText; + var noteGrp:FlxTypedGroup; + var strumLine:FlxSprite; - var blocks:FlxTypedGroup; + var blocks:FlxTypedGroup; - var songPosVis:FlxSprite; - var songVisFollowVideo:FlxSprite; - var songVisFollowAudio:FlxSprite; + var songPosVis:FlxSprite; + var songVisFollowVideo:FlxSprite; + var songVisFollowAudio:FlxSprite; - var beatTrail:FlxSprite; - var diffGrp:FlxTypedGroup; - var offsetsPerBeat:Array = []; - var swagSong:HomemadeMusic; + var beatTrail:FlxSprite; + var diffGrp:FlxTypedGroup; + var offsetsPerBeat:Array = []; + var swagSong:HomemadeMusic; - #if debug - var funnyStatsGraph:CoolStatsGraph; - var realStats:CoolStatsGraph; - #end - - override function create() - { - swagSong = new HomemadeMusic(); - swagSong.loadEmbedded(Paths.sound('soundTest'), true); + #if debug + var funnyStatsGraph:CoolStatsGraph; + var realStats:CoolStatsGraph; + #end - FlxG.sound.music = swagSong; - FlxG.sound.music.play(); + override function create() + { + swagSong = new HomemadeMusic(); + swagSong.loadEmbedded(Paths.sound('soundTest'), true); - #if debug - funnyStatsGraph = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.PINK, "time"); - FlxG.addChildBelowMouse(funnyStatsGraph); - - realStats = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.YELLOW, "REAL"); - FlxG.addChildBelowMouse(realStats); - #end - - FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, key -> - { - trace(key.charCode); - - if (key.charCode == 120) - generateBeatStuff(); - - trace("\tEVENT PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); - // trace(FlxG.sound.music.prevTimestamp); - trace(FlxG.sound.music.time); - trace("\tFR FR PRESS: \t" + swagSong.getTimeWithDiff()); - - // trace("\tREDDIT: \t" + swagSong.frfrTime + " " + Timer.stamp()); - @:privateAccess - trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp()); - // trace("EVENT LISTENER: " + key); - }); - - // FlxG.sound.playMusic(Paths.sound('soundTest')); - - // funnyStatsGraph.hi - - Conductor.forceBPM(60); - - noteGrp = new FlxTypedGroup(); - add(noteGrp); - - diffGrp = new FlxTypedGroup(); - add(diffGrp); - - // var musSpec:PolygonSpectogram = new PolygonSpectogram(FlxG.sound.music, FlxColor.RED, FlxG.height, Math.floor(FlxG.height / 2)); - // musSpec.x += 170; - // musSpec.scrollFactor.set(); - // musSpec.waveAmplitude = 100; - // musSpec.realtimeVisLenght = 0.45; - // // musSpec.visType = FREQUENCIES; - // add(musSpec); - - for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.crochet)) - { - var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.crochet), FlxG.height - 15); - beatTick.makeGraphic(2, 15); - beatTick.alpha = 0.3; - add(beatTick); - - var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.crochet), FlxG.height - 26, 0, "swag"); - offsetTxt.alpha = 0.5; - diffGrp.add(offsetTxt); - - offsetsPerBeat.push(0); - } - - songVisFollowAudio = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.YELLOW); - add(songVisFollowAudio); - - songVisFollowVideo = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.BLUE); - add(songVisFollowVideo); - - songPosVis = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.RED); - add(songPosVis); - - beatTrail = new FlxSprite(0, songPosVis.y).makeGraphic(2, 20, FlxColor.PURPLE); - beatTrail.alpha = 0.7; - add(beatTrail); - - blocks = new FlxTypedGroup(); - add(blocks); + FlxG.sound.music = swagSong; + FlxG.sound.music.play(); - for (i in 0...8) - { - var block = new FlxSprite(2, 50 * i).makeGraphic(48, 48); - block.alpha = 0; - blocks.add(block); - } - - for (i in 0...32) - { - var note:Note = new Note(Conductor.crochet * i, 1); - noteGrp.add(note); - } - - offsetText = new FlxText(); - offsetText.screenCenter(); - add(offsetText); - - strumLine = new FlxSprite(FlxG.width / 2, 100).makeGraphic(FlxG.width, 5); - add(strumLine); - - super.create(); - } - - override function stepHit():Bool - { - if (curStep % 4 == 2) - { - blocks.members[((curBeat % 8) + 1) % 8].alpha = 0.5; - } - - return super.stepHit(); - } - - override function beatHit():Bool - { - if (curBeat % 8 == 0) - blocks.forEach(blok -> - { - blok.alpha = 0; - }); - - blocks.members[curBeat % 8].alpha = 1; - // block.visible = !block.visible; - - return super.beatHit(); - } - - override function update(elapsed:Float) - { - /* trace("1: " + swagSong.frfrTime); - @:privateAccess - trace(FlxG.sound.music._channel.position); - */ - - #if debug - funnyStatsGraph.update(FlxG.sound.music.time % 500); - realStats.update(swagSong.getTimeWithDiff() % 500); - #end - - if (FlxG.keys.justPressed.S) - { - trace("\tUPDATE PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); - } - - if (FlxG.keys.justPressed.SPACE) - { - if (FlxG.sound.music.playing) - FlxG.sound.music.pause(); - else - FlxG.sound.music.resume(); - } - - if (FlxG.keys.pressed.D) - FlxG.sound.music.time += 1000 * FlxG.elapsed; - - Conductor.songPosition = swagSong.getTimeWithDiff() - Conductor.offset; - // Conductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; - - songPosVis.x = songPosToX(Conductor.songPosition); - songVisFollowAudio.x = songPosToX(Conductor.songPosition - Conductor.audioOffset); - songVisFollowVideo.x = songPosToX(Conductor.songPosition - Conductor.visualOffset); - - offsetText.text = "AUDIO Offset: " + Conductor.audioOffset + "ms"; - offsetText.text += "\nVIDOE Offset: " + Conductor.visualOffset + "ms"; - offsetText.text += "\ncurStep: " + curStep; - offsetText.text += "\ncurBeat: " + curBeat; - - var avgOffsetInput:Float = 0; - - for (offsetThing in offsetsPerBeat) - avgOffsetInput += offsetThing; - - avgOffsetInput /= offsetsPerBeat.length; - - offsetText.text += "\naverage input offset needed: " + avgOffsetInput; - - var multiply:Float = 10; - - if (FlxG.keys.pressed.SHIFT) - multiply = 1; - - if (FlxG.keys.pressed.CONTROL) - { - if (FlxG.keys.justPressed.RIGHT) - { - Conductor.audioOffset += 1 * multiply; - } - - if (FlxG.keys.justPressed.LEFT) - { - Conductor.audioOffset -= 1 * multiply; - } - } - else - { - if (FlxG.keys.justPressed.RIGHT) - { - Conductor.visualOffset += 1 * multiply; - } - - if (FlxG.keys.justPressed.LEFT) - { - Conductor.visualOffset -= 1 * multiply; - } - } - - /* if (FlxG.keys.justPressed.SPACE) - { - FlxG.sound.music.stop(); - - FlxG.resetState(); - }*/ - - noteGrp.forEach(function(daNote:Note) - { - daNote.y = (strumLine.y - ((Conductor.songPosition - Conductor.audioOffset) - daNote.data.strumTime) * 0.45); - daNote.x = strumLine.x + 30; - - if (daNote.y < strumLine.y) - daNote.alpha = 0.5; - - if (daNote.y < 0 - daNote.height) - { - daNote.alpha = 1; - // daNote.data.strumTime += Conductor.crochet * 8; - } - }); - - super.update(elapsed); - } - - function generateBeatStuff() - { - Conductor.songPosition = swagSong.getTimeWithDiff(); - - var closestBeat:Int = Math.round(Conductor.songPosition / Conductor.crochet) % diffGrp.members.length; - var getDiff:Float = Conductor.songPosition - (closestBeat * Conductor.crochet); - getDiff -= Conductor.visualOffset; - - // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.crochet * 2) - getDiff -= FlxG.sound.music.length; - - trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms"); - trace("\tCLOSEST BEAT: " + closestBeat); - beatTrail.x = songPosVis.x; - - diffGrp.members[closestBeat].text = getDiff + "ms"; - offsetsPerBeat[closestBeat] = Std.int(getDiff); - } - - function songPosToX(pos:Float):Float - { - return FlxMath.remapToRange(pos, 0, FlxG.sound.music.length, 0, FlxG.width); - } + #if debug + funnyStatsGraph = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.PINK, "time"); + FlxG.addChildBelowMouse(funnyStatsGraph); + + realStats = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.YELLOW, "REAL"); + FlxG.addChildBelowMouse(realStats); + #end + + FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, key -> + { + trace(key.charCode); + + if (key.charCode == 120) generateBeatStuff(); + + trace("\tEVENT PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); + // trace(FlxG.sound.music.prevTimestamp); + trace(FlxG.sound.music.time); + trace("\tFR FR PRESS: \t" + swagSong.getTimeWithDiff()); + + // trace("\tREDDIT: \t" + swagSong.frfrTime + " " + Timer.stamp()); + @:privateAccess + trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp()); + // trace("EVENT LISTENER: " + key); + }); + + // FlxG.sound.playMusic(Paths.sound('soundTest')); + + // funnyStatsGraph.hi + + Conductor.forceBPM(60); + + noteGrp = new FlxTypedGroup(); + add(noteGrp); + + diffGrp = new FlxTypedGroup(); + add(diffGrp); + + // var musSpec:PolygonSpectogram = new PolygonSpectogram(FlxG.sound.music, FlxColor.RED, FlxG.height, Math.floor(FlxG.height / 2)); + // musSpec.x += 170; + // musSpec.scrollFactor.set(); + // musSpec.waveAmplitude = 100; + // musSpec.realtimeVisLenght = 0.45; + // // musSpec.visType = FREQUENCIES; + // add(musSpec); + + for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.crochet)) + { + var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.crochet), FlxG.height - 15); + beatTick.makeGraphic(2, 15); + beatTick.alpha = 0.3; + add(beatTick); + + var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.crochet), FlxG.height - 26, 0, "swag"); + offsetTxt.alpha = 0.5; + diffGrp.add(offsetTxt); + + offsetsPerBeat.push(0); + } + + songVisFollowAudio = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.YELLOW); + add(songVisFollowAudio); + + songVisFollowVideo = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.BLUE); + add(songVisFollowVideo); + + songPosVis = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.RED); + add(songPosVis); + + beatTrail = new FlxSprite(0, songPosVis.y).makeGraphic(2, 20, FlxColor.PURPLE); + beatTrail.alpha = 0.7; + add(beatTrail); + + blocks = new FlxTypedGroup(); + add(blocks); + + for (i in 0...8) + { + var block = new FlxSprite(2, 50 * i).makeGraphic(48, 48); + block.alpha = 0; + blocks.add(block); + } + + for (i in 0...32) + { + var note:Note = new Note(Conductor.crochet * i, 1); + noteGrp.add(note); + } + + offsetText = new FlxText(); + offsetText.screenCenter(); + add(offsetText); + + strumLine = new FlxSprite(FlxG.width / 2, 100).makeGraphic(FlxG.width, 5); + add(strumLine); + + super.create(); + } + + override function stepHit():Bool + { + if (curStep % 4 == 2) + { + blocks.members[((curBeat % 8) + 1) % 8].alpha = 0.5; + } + + return super.stepHit(); + } + + override function beatHit():Bool + { + if (curBeat % 8 == 0) blocks.forEach(blok -> + { + blok.alpha = 0; + }); + + blocks.members[curBeat % 8].alpha = 1; + // block.visible = !block.visible; + + return super.beatHit(); + } + + override function update(elapsed:Float) + { + /* trace("1: " + swagSong.frfrTime); + @:privateAccess + trace(FlxG.sound.music._channel.position); + */ + + #if debug + funnyStatsGraph.update(FlxG.sound.music.time % 500); + realStats.update(swagSong.getTimeWithDiff() % 500); + #end + + if (FlxG.keys.justPressed.S) + { + trace("\tUPDATE PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); + } + + if (FlxG.keys.justPressed.SPACE) + { + if (FlxG.sound.music.playing) FlxG.sound.music.pause(); + else + FlxG.sound.music.resume(); + } + + if (FlxG.keys.pressed.D) FlxG.sound.music.time += 1000 * FlxG.elapsed; + + Conductor.songPosition = swagSong.getTimeWithDiff() - Conductor.offset; + // Conductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; + + songPosVis.x = songPosToX(Conductor.songPosition); + songVisFollowAudio.x = songPosToX(Conductor.songPosition - Conductor.audioOffset); + songVisFollowVideo.x = songPosToX(Conductor.songPosition - Conductor.visualOffset); + + offsetText.text = "AUDIO Offset: " + Conductor.audioOffset + "ms"; + offsetText.text += "\nVIDOE Offset: " + Conductor.visualOffset + "ms"; + offsetText.text += "\ncurStep: " + curStep; + offsetText.text += "\ncurBeat: " + curBeat; + + var avgOffsetInput:Float = 0; + + for (offsetThing in offsetsPerBeat) + avgOffsetInput += offsetThing; + + avgOffsetInput /= offsetsPerBeat.length; + + offsetText.text += "\naverage input offset needed: " + avgOffsetInput; + + var multiply:Float = 10; + + if (FlxG.keys.pressed.SHIFT) multiply = 1; + + if (FlxG.keys.pressed.CONTROL) + { + if (FlxG.keys.justPressed.RIGHT) + { + Conductor.audioOffset += 1 * multiply; + } + + if (FlxG.keys.justPressed.LEFT) + { + Conductor.audioOffset -= 1 * multiply; + } + } + else + { + if (FlxG.keys.justPressed.RIGHT) + { + Conductor.visualOffset += 1 * multiply; + } + + if (FlxG.keys.justPressed.LEFT) + { + Conductor.visualOffset -= 1 * multiply; + } + } + + /* if (FlxG.keys.justPressed.SPACE) + { + FlxG.sound.music.stop(); + + FlxG.resetState(); + }*/ + + noteGrp.forEach(function(daNote:Note) + { + daNote.y = (strumLine.y - ((Conductor.songPosition - Conductor.audioOffset) - daNote.data.strumTime) * 0.45); + daNote.x = strumLine.x + 30; + + if (daNote.y < strumLine.y) daNote.alpha = 0.5; + + if (daNote.y < 0 - daNote.height) + { + daNote.alpha = 1; + // daNote.data.strumTime += Conductor.crochet * 8; + } + }); + + super.update(elapsed); + } + + function generateBeatStuff() + { + Conductor.songPosition = swagSong.getTimeWithDiff(); + + var closestBeat:Int = Math.round(Conductor.songPosition / Conductor.crochet) % diffGrp.members.length; + var getDiff:Float = Conductor.songPosition - (closestBeat * Conductor.crochet); + getDiff -= Conductor.visualOffset; + + // lil fix for end of song + if (closestBeat == 0 && getDiff >= Conductor.crochet * 2) getDiff -= FlxG.sound.music.length; + + trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms"); + trace("\tCLOSEST BEAT: " + closestBeat); + beatTrail.x = songPosVis.x; + + diffGrp.members[closestBeat].text = getDiff + "ms"; + offsetsPerBeat[closestBeat] = Std.int(getDiff); + } + + function songPosToX(pos:Float):Float + { + return FlxMath.remapToRange(pos, 0, FlxG.sound.music.length, 0, FlxG.width); + } } class HomemadeMusic extends FlxSound { - public var prevTimestamp:Int = 0; - public var timeWithDiff:Float = 0; + public var prevTimestamp:Int = 0; + public var timeWithDiff:Float = 0; - public function new() - { - super(); - } + public function new() + { + super(); + } - var prevTime:Float = 0; + var prevTime:Float = 0; - override function update(elapsed:Float) - { - super.update(elapsed); - if (prevTime != time) - { - prevTime = time; - prevTimestamp = Std.int(Timer.stamp() * 1000); - } - } + override function update(elapsed:Float) + { + super.update(elapsed); + if (prevTime != time) + { + prevTime = time; + prevTimestamp = Std.int(Timer.stamp() * 1000); + } + } - public function getTimeWithDiff():Float - { - return time + (Std.int(Timer.stamp() * 1000) - prevTimestamp); - } + public function getTimeWithDiff():Float + { + return time + (Std.int(Timer.stamp() * 1000) - prevTimestamp); + } } diff --git a/source/funkin/LoadingState.hx b/source/funkin/LoadingState.hx index 688ea96ea..316041fd4 100644 --- a/source/funkin/LoadingState.hx +++ b/source/funkin/LoadingState.hx @@ -15,344 +15,333 @@ import openfl.utils.Assets; class LoadingState extends MusicBeatState { - inline static var MIN_TIME = 1.0; + inline static var MIN_TIME = 1.0; - var target:FlxState; - var stopMusic = false; - var callbacks:MultiCallback; - var danceLeft = false; + var target:FlxState; + var stopMusic = false; + var callbacks:MultiCallback; + var danceLeft = false; - var loadBar:FlxSprite; - var funkay:FlxSprite; + var loadBar:FlxSprite; + var funkay:FlxSprite; - function new(target:FlxState, stopMusic:Bool) - { - super(); - this.target = target; - this.stopMusic = stopMusic; - } + function new(target:FlxState, stopMusic:Bool) + { + super(); + this.target = target; + this.stopMusic = stopMusic; + } - override function create() - { - var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, 0xFFcaff4d); - add(bg); + override function create() + { + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, 0xFFcaff4d); + add(bg); - funkay = new FlxSprite(); - funkay.loadGraphic(Paths.image('funkay')); - funkay.setGraphicSize(0, FlxG.height); - funkay.updateHitbox(); - funkay.antialiasing = true; - add(funkay); - funkay.scrollFactor.set(); - funkay.screenCenter(); + funkay = new FlxSprite(); + funkay.loadGraphic(Paths.image('funkay')); + funkay.setGraphicSize(0, FlxG.height); + funkay.updateHitbox(); + funkay.antialiasing = true; + add(funkay); + funkay.scrollFactor.set(); + funkay.screenCenter(); - loadBar = new FlxSprite(0, FlxG.height - 20).makeGraphic(FlxG.width, 10, 0xFFff16d2); - loadBar.screenCenter(X); - add(loadBar); + loadBar = new FlxSprite(0, FlxG.height - 20).makeGraphic(FlxG.width, 10, 0xFFff16d2); + loadBar.screenCenter(X); + add(loadBar); - initSongsManifest().onComplete(function(lib) - { - callbacks = new MultiCallback(onLoad); - var introComplete = callbacks.add("introComplete"); - checkLoadSong(getSongPath()); - if (PlayState.currentSong.needsVoices) - { - var files = PlayState.currentSong.voiceList; + initSongsManifest().onComplete(function(lib) + { + callbacks = new MultiCallback(onLoad); + var introComplete = callbacks.add("introComplete"); + checkLoadSong(getSongPath()); + if (PlayState.currentSong.needsVoices) + { + var files = PlayState.currentSong.voiceList; - if (files == null) - files = [""]; // loads with no file name assumption, to load "Voices.ogg" or whatev normally + if (files == null) files = [""]; // loads with no file name assumption, to load "Voices.ogg" or whatev normally - for (sndFile in files) - { - checkLoadSong(getVocalPath(sndFile)); - } - } + for (sndFile in files) + { + checkLoadSong(getVocalPath(sndFile)); + } + } - checkLibrary("shared"); - if (PlayState.storyWeek > 0) - checkLibrary("week" + PlayState.storyWeek); - else - checkLibrary("tutorial"); + checkLibrary("shared"); + if (PlayState.storyWeek > 0) checkLibrary("week" + PlayState.storyWeek); + else + checkLibrary("tutorial"); - var fadeTime = 0.5; - FlxG.camera.fade(FlxG.camera.bgColor, fadeTime, true); - new FlxTimer().start(fadeTime + MIN_TIME, function(_) introComplete()); - }); - } + var fadeTime = 0.5; + FlxG.camera.fade(FlxG.camera.bgColor, fadeTime, true); + new FlxTimer().start(fadeTime + MIN_TIME, function(_) introComplete()); + }); + } - function checkLoadSong(path:String) - { - if (!Assets.cache.hasSound(path)) - { - var library = Assets.getLibrary("songs"); - var symbolPath = path.split(":").pop(); - // @:privateAccess - // library.types.set(symbolPath, SOUND); - // @:privateAccess - // library.pathGroups.set(symbolPath, [library.__cacheBreak(symbolPath)]); - var callback = callbacks.add("song:" + path); - Assets.loadSound(path).onComplete(function(_) - { - callback(); - }); - } - } + function checkLoadSong(path:String) + { + if (!Assets.cache.hasSound(path)) + { + var library = Assets.getLibrary("songs"); + var symbolPath = path.split(":").pop(); + // @:privateAccess + // library.types.set(symbolPath, SOUND); + // @:privateAccess + // library.pathGroups.set(symbolPath, [library.__cacheBreak(symbolPath)]); + var callback = callbacks.add("song:" + path); + Assets.loadSound(path).onComplete(function(_) + { + callback(); + }); + } + } - function checkLibrary(library:String) - { - trace(Assets.hasLibrary(library)); - if (Assets.getLibrary(library) == null) - { - @:privateAccess - if (!LimeAssets.libraryPaths.exists(library)) - throw "Missing library: " + library; + function checkLibrary(library:String) + { + trace(Assets.hasLibrary(library)); + if (Assets.getLibrary(library) == null) + { + @:privateAccess + if (!LimeAssets.libraryPaths.exists(library)) throw "Missing library: " + library; - var callback = callbacks.add("library:" + library); - Assets.loadLibrary(library).onComplete(function(_) - { - callback(); - }); - } - } + var callback = callbacks.add("library:" + library); + Assets.loadLibrary(library).onComplete(function(_) + { + callback(); + }); + } + } - override function beatHit():Bool - { - // super.beatHit() returns false if a module cancelled the event. - if (!super.beatHit()) - return false; + override function beatHit():Bool + { + // super.beatHit() returns false if a module cancelled the event. + if (!super.beatHit()) return false; - danceLeft = !danceLeft; + danceLeft = !danceLeft; - return true; - } + return true; + } - var targetShit:Float = 0; + var targetShit:Float = 0; - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - funkay.setGraphicSize(Std.int(FlxMath.lerp(FlxG.width * 0.88, funkay.width, 0.9))); - funkay.updateHitbox(); - // funkay.updateHitbox(); + funkay.setGraphicSize(Std.int(FlxMath.lerp(FlxG.width * 0.88, funkay.width, 0.9))); + funkay.updateHitbox(); + // funkay.updateHitbox(); - if (controls.ACCEPT) - { - funkay.setGraphicSize(Std.int(funkay.width + 60)); - funkay.updateHitbox(); - // funkay.setGraphicSize(0, Std.int(funkay.height + 50)); - // funkay.updateHitbox(); - // funkay.screenCenter(); - } + if (controls.ACCEPT) + { + funkay.setGraphicSize(Std.int(funkay.width + 60)); + funkay.updateHitbox(); + // funkay.setGraphicSize(0, Std.int(funkay.height + 50)); + // funkay.updateHitbox(); + // funkay.screenCenter(); + } - if (callbacks != null) - { - targetShit = FlxMath.remapToRange(callbacks.numRemaining / callbacks.length, 1, 0, 0, 1); + if (callbacks != null) + { + targetShit = FlxMath.remapToRange(callbacks.numRemaining / callbacks.length, 1, 0, 0, 1); - loadBar.scale.x = FlxMath.lerp(loadBar.scale.x, targetShit, 0.50); - FlxG.watch.addQuick('percentage?', callbacks.numRemaining / callbacks.length); - } + loadBar.scale.x = FlxMath.lerp(loadBar.scale.x, targetShit, 0.50); + FlxG.watch.addQuick('percentage?', callbacks.numRemaining / callbacks.length); + } - #if debug - if (FlxG.keys.justPressed.SPACE) - trace('fired: ' + callbacks.getFired() + " unfired:" + callbacks.getUnfired()); - #end - } + #if debug + if (FlxG.keys.justPressed.SPACE) trace('fired: ' + callbacks.getFired() + " unfired:" + callbacks.getUnfired()); + #end + } - function onLoad() - { - if (stopMusic && FlxG.sound.music != null) - FlxG.sound.music.stop(); + function onLoad() + { + if (stopMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); - FlxG.switchState(target); - } + FlxG.switchState(target); + } - static function getSongPath() - { - return Paths.inst(PlayState.currentSong.song); - } + static function getSongPath() + { + return Paths.inst(PlayState.currentSong.song); + } - static function getVocalPath(?suffix:String) - { - return Paths.voices(PlayState.currentSong.song, suffix); - } + static function getVocalPath(?suffix:String) + { + return Paths.voices(PlayState.currentSong.song, suffix); + } - inline static public function loadAndSwitchState(target:FlxState, stopMusic = false) - { - FlxG.switchState(getNextState(target, stopMusic)); - } + inline static public function loadAndSwitchState(target:FlxState, stopMusic = false) + { + FlxG.switchState(getNextState(target, stopMusic)); + } - static function getNextState(target:FlxState, stopMusic = false):FlxState - { - if (PlayState.storyWeek == 0) - { - Paths.setCurrentLevel('tutorial'); - } - else if (PlayState.storyWeek == 8) - { - // TODO: Refactor this code. - Paths.setCurrentLevel("weekend1"); - } - else - { - Paths.setCurrentLevel("week" + PlayState.storyWeek); - } - #if NO_PRELOAD_ALL - var loaded = isSoundLoaded(getSongPath()) - && (!PlayState.currentSong.needsVoices || isSoundLoaded(getVocalPath())) - && isLibraryLoaded("shared"); + static function getNextState(target:FlxState, stopMusic = false):FlxState + { + if (PlayState.storyWeek == 0) + { + Paths.setCurrentLevel('tutorial'); + } + else if (PlayState.storyWeek == 8) + { + // TODO: Refactor this code. + Paths.setCurrentLevel("weekend1"); + } + else + { + Paths.setCurrentLevel("week" + PlayState.storyWeek); + } + #if NO_PRELOAD_ALL + var loaded = isSoundLoaded(getSongPath()) + && (!PlayState.currentSong.needsVoices || isSoundLoaded(getVocalPath())) + && isLibraryLoaded("shared"); - if (!loaded) - return new LoadingState(target, stopMusic); - #end - if (stopMusic && FlxG.sound.music != null) - FlxG.sound.music.stop(); + if (!loaded) return new LoadingState(target, stopMusic); + #end + if (stopMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); - return target; - } + return target; + } - #if NO_PRELOAD_ALL - static function isSoundLoaded(path:String):Bool - { - return Assets.cache.hasSound(path); - } + #if NO_PRELOAD_ALL + static function isSoundLoaded(path:String):Bool + { + return Assets.cache.hasSound(path); + } - static function isLibraryLoaded(library:String):Bool - { - return Assets.getLibrary(library) != null; - } - #end + static function isLibraryLoaded(library:String):Bool + { + return Assets.getLibrary(library) != null; + } + #end - override function destroy() - { - super.destroy(); + override function destroy() + { + super.destroy(); - callbacks = null; - } + callbacks = null; + } - static function initSongsManifest() - { - var id = "songs"; - var promise = new Promise(); + static function initSongsManifest() + { + var id = "songs"; + var promise = new Promise(); - var library = LimeAssets.getLibrary(id); + var library = LimeAssets.getLibrary(id); - if (library != null) - { - return Future.withValue(library); - } + if (library != null) + { + return Future.withValue(library); + } - var path = id; - var rootPath = null; + var path = id; + var rootPath = null; - @:privateAccess - var libraryPaths = LimeAssets.libraryPaths; - if (libraryPaths.exists(id)) - { - path = libraryPaths[id]; - rootPath = Path.directory(path); - } - else - { - if (path.endsWith(".bundle")) - { - rootPath = path; - path += "/library.json"; - } - else - { - rootPath = Path.directory(path); - } - @:privateAccess - path = LimeAssets.__cacheBreak(path); - } + @:privateAccess + var libraryPaths = LimeAssets.libraryPaths; + if (libraryPaths.exists(id)) + { + path = libraryPaths[id]; + rootPath = Path.directory(path); + } + else + { + if (path.endsWith(".bundle")) + { + rootPath = path; + path += "/library.json"; + } + else + { + rootPath = Path.directory(path); + } + @:privateAccess + path = LimeAssets.__cacheBreak(path); + } - AssetManifest.loadFromFile(path, rootPath).onComplete(function(manifest) - { - if (manifest == null) - { - promise.error("Cannot parse asset manifest for library \"" + id + "\""); - return; - } + AssetManifest.loadFromFile(path, rootPath).onComplete(function(manifest) + { + if (manifest == null) + { + promise.error("Cannot parse asset manifest for library \"" + id + "\""); + return; + } - var library = AssetLibrary.fromManifest(manifest); + var library = AssetLibrary.fromManifest(manifest); - if (library == null) - { - promise.error("Cannot open library \"" + id + "\""); - } - else - { - @:privateAccess - LimeAssets.libraries.set(id, library); - library.onChange.add(LimeAssets.onChange.dispatch); - promise.completeWith(Future.withValue(library)); - } - }).onError(function(_) - { - promise.error("There is no asset library with an ID of \"" + id + "\""); - }); + if (library == null) + { + promise.error("Cannot open library \"" + id + "\""); + } + else + { + @:privateAccess + LimeAssets.libraries.set(id, library); + library.onChange.add(LimeAssets.onChange.dispatch); + promise.completeWith(Future.withValue(library)); + } + }).onError(function(_) + { + promise.error("There is no asset library with an ID of \"" + id + "\""); + }); - return promise.future; - } + return promise.future; + } } class MultiCallback { - public var callback:Void->Void; - public var logId:String = null; - public var length(default, null) = 0; - public var numRemaining(default, null) = 0; + public var callback:Void->Void; + public var logId:String = null; + public var length(default, null) = 0; + public var numRemaining(default, null) = 0; - var unfired = new MapVoid>(); - var fired = new Array(); + var unfired = new MapVoid>(); + var fired = new Array(); - public function new(callback:Void->Void, logId:String = null) - { - this.callback = callback; - this.logId = logId; - } + public function new(callback:Void->Void, logId:String = null) + { + this.callback = callback; + this.logId = logId; + } - public function add(id = "untitled") - { - id = '$length:$id'; - length++; - numRemaining++; - var func:Void->Void = null; - func = function() - { - if (unfired.exists(id)) - { - unfired.remove(id); - fired.push(id); - numRemaining--; + public function add(id = "untitled") + { + id = '$length:$id'; + length++; + numRemaining++; + var func:Void->Void = null; + func = function() + { + if (unfired.exists(id)) + { + unfired.remove(id); + fired.push(id); + numRemaining--; - if (logId != null) - log('fired $id, $numRemaining remaining'); + if (logId != null) log('fired $id, $numRemaining remaining'); - if (numRemaining == 0) - { - if (logId != null) - log('all callbacks fired'); - callback(); - } - } - else - log('already fired $id'); - } - unfired[id] = func; - return func; - } + if (numRemaining == 0) + { + if (logId != null) log('all callbacks fired'); + callback(); + } + } + else + log('already fired $id'); + } + unfired[id] = func; + return func; + } - inline function log(msg):Void - { - if (logId != null) - trace('$logId: $msg'); - } + inline function log(msg):Void + { + if (logId != null) trace('$logId: $msg'); + } - public function getFired() - return fired.copy(); + public function getFired() + return fired.copy(); - public function getUnfired() - return unfired.array(); + public function getUnfired() + return unfired.array(); } diff --git a/source/funkin/MainMenuState.hx b/source/funkin/MainMenuState.hx index d2ca2657e..a99eac686 100644 --- a/source/funkin/MainMenuState.hx +++ b/source/funkin/MainMenuState.hx @@ -38,272 +38,266 @@ import io.newgrounds.NG; class MainMenuState extends MusicBeatState { - var menuItems:MenuTypedList; + var menuItems:MenuTypedList; - var magenta:FlxSprite; - var camFollow:FlxObject; + var magenta:FlxSprite; + var camFollow:FlxObject; - override function create() - { - #if discord_rpc - // Updating Discord Rich Presence - DiscordClient.changePresence("In the Menus", null); - #end + override function create() + { + #if discord_rpc + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end - transIn = FlxTransitionableState.defaultTransIn; - transOut = FlxTransitionableState.defaultTransOut; + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut; - if (!FlxG.sound.music.playing) - { - FlxG.sound.playMusic(Paths.music('freakyMenu')); - } + if (!FlxG.sound.music.playing) + { + FlxG.sound.playMusic(Paths.music('freakyMenu')); + } - persistentUpdate = persistentDraw = true; + persistentUpdate = persistentDraw = true; - var bg:FlxSprite = new FlxSprite(Paths.image('menuBG')); - bg.scrollFactor.x = 0; - bg.scrollFactor.y = 0.17; - bg.setGraphicSize(Std.int(bg.width * 1.2)); - bg.updateHitbox(); - bg.screenCenter(); - bg.antialiasing = true; - add(bg); + var bg:FlxSprite = new FlxSprite(Paths.image('menuBG')); + bg.scrollFactor.x = 0; + bg.scrollFactor.y = 0.17; + bg.setGraphicSize(Std.int(bg.width * 1.2)); + bg.updateHitbox(); + bg.screenCenter(); + bg.antialiasing = true; + add(bg); - camFollow = new FlxObject(0, 0, 1, 1); - add(camFollow); + camFollow = new FlxObject(0, 0, 1, 1); + add(camFollow); - magenta = new FlxSprite(Paths.image('menuDesat')); - magenta.scrollFactor.x = bg.scrollFactor.x; - magenta.scrollFactor.y = bg.scrollFactor.y; - magenta.setGraphicSize(Std.int(bg.width)); - magenta.updateHitbox(); - magenta.x = bg.x; - magenta.y = bg.y; - magenta.visible = false; - magenta.antialiasing = true; - magenta.color = 0xFFfd719b; - if (PreferencesMenu.preferences.get('flashing-menu')) - add(magenta); - // magenta.scrollFactor.set(); + magenta = new FlxSprite(Paths.image('menuDesat')); + magenta.scrollFactor.x = bg.scrollFactor.x; + magenta.scrollFactor.y = bg.scrollFactor.y; + magenta.setGraphicSize(Std.int(bg.width)); + magenta.updateHitbox(); + magenta.x = bg.x; + magenta.y = bg.y; + magenta.visible = false; + magenta.antialiasing = true; + magenta.color = 0xFFfd719b; + if (PreferencesMenu.preferences.get('flashing-menu')) add(magenta); + // magenta.scrollFactor.set(); - menuItems = new MenuTypedList(); - add(menuItems); - menuItems.onChange.add(onMenuItemChange); - menuItems.onAcceptPress.add(function(_) - { - if (_.name == 'freeplay') - { - magenta.visible = true; - } - else - { - FlxFlicker.flicker(magenta, 1.1, 0.15, false, true); - } - }); + menuItems = new MenuTypedList(); + add(menuItems); + menuItems.onChange.add(onMenuItemChange); + menuItems.onAcceptPress.add(function(_) + { + if (_.name == 'freeplay') + { + magenta.visible = true; + } + else + { + FlxFlicker.flicker(magenta, 1.1, 0.15, false, true); + } + }); - menuItems.enabled = true; // can move on intro - createMenuItem('storymode', 'mainmenu/storymode', function() startExitState(new StoryMenuState())); - createMenuItem('freeplay', 'mainmenu/freeplay', function() - { - persistentDraw = true; - persistentUpdate = false; - openSubState(new FreeplayState()); - }); + menuItems.enabled = true; // can move on intro + createMenuItem('storymode', 'mainmenu/storymode', function() startExitState(new StoryMenuState())); + createMenuItem('freeplay', 'mainmenu/freeplay', function() + { + persistentDraw = true; + persistentUpdate = false; + openSubState(new FreeplayState()); + }); - #if CAN_OPEN_LINKS - var hasPopupBlocker = #if web true #else false #end; - createMenuItem('donate', 'mainmenu/donate', selectDonate, hasPopupBlocker); - #end + #if CAN_OPEN_LINKS + var hasPopupBlocker = #if web true #else false #end; + createMenuItem('donate', 'mainmenu/donate', selectDonate, hasPopupBlocker); + #end - createMenuItem('options', 'mainmenu/options', function() - { - startExitState(new OptionsState()); - }); + createMenuItem('options', 'mainmenu/options', function() + { + startExitState(new OptionsState()); + }); - // Reset position of menu items. - var spacing = 160; - var top = (FlxG.height - (spacing * (menuItems.length - 1))) / 2; - for (i in 0...menuItems.length) - { - var menuItem = menuItems.members[i]; - menuItem.x = FlxG.width / 2; - menuItem.y = top + spacing * i; - } + // Reset position of menu items. + var spacing = 160; + var top = (FlxG.height - (spacing * (menuItems.length - 1))) / 2; + for (i in 0...menuItems.length) + { + var menuItem = menuItems.members[i]; + menuItem.x = FlxG.width / 2; + menuItem.y = top + spacing * i; + } - FlxG.cameras.reset(new SwagCamera()); - FlxG.camera.follow(camFollow, null, 0.06); - // FlxG.camera.setScrollBounds(bg.x, bg.x + bg.width, bg.y, bg.y + bg.height * 1.2); + FlxG.cameras.reset(new SwagCamera()); + FlxG.camera.follow(camFollow, null, 0.06); + // FlxG.camera.setScrollBounds(bg.x, bg.x + bg.width, bg.y, bg.y + bg.height * 1.2); - super.create(); + super.create(); - // This has to come AFTER! - this.leftWatermarkText.text = Constants.VERSION; - // this.rightWatermarkText.text = "blablabla test"; + // This has to come AFTER! + this.leftWatermarkText.text = Constants.VERSION; + // this.rightWatermarkText.text = "blablabla test"; - // NG.core.calls.event.logEvent('swag').send(); - } + // NG.core.calls.event.logEvent('swag').send(); + } - function createMenuItem(name:String, atlas:String, callback:Void->Void, fireInstantly:Bool = false):Void - { - var item = new AtlasMenuItem(name, Paths.getSparrowAtlas(atlas), callback); - item.fireInstantly = fireInstantly; - item.ID = menuItems.length; + function createMenuItem(name:String, atlas:String, callback:Void->Void, fireInstantly:Bool = false):Void + { + var item = new AtlasMenuItem(name, Paths.getSparrowAtlas(atlas), callback); + item.fireInstantly = fireInstantly; + item.ID = menuItems.length; - item.scrollFactor.set(); + item.scrollFactor.set(); - // Set the offset of the item so the sprite is centered on the origin. - item.centered = true; - item.changeAnim('idle'); + // Set the offset of the item so the sprite is centered on the origin. + item.centered = true; + item.changeAnim('idle'); - menuItems.addItem(name, item); - } + menuItems.addItem(name, item); + } - override function closeSubState() - { - magenta.visible = false; + override function closeSubState() + { + magenta.visible = false; - super.closeSubState(); - } + super.closeSubState(); + } - override function finishTransIn() - { - super.finishTransIn(); + override function finishTransIn() + { + super.finishTransIn(); - // menuItems.enabled = true; + // menuItems.enabled = true; - // #if newgrounds - // if (NGio.savedSessionFailed) - // showSavedSessionFailed(); - // #end - } + // #if newgrounds + // if (NGio.savedSessionFailed) + // showSavedSessionFailed(); + // #end + } - function onMenuItemChange(selected:MenuItem) - { - camFollow.setPosition(selected.getGraphicMidpoint().x, selected.getGraphicMidpoint().y); - } + function onMenuItemChange(selected:MenuItem) + { + camFollow.setPosition(selected.getGraphicMidpoint().x, selected.getGraphicMidpoint().y); + } - #if CAN_OPEN_LINKS - function selectDonate() - { - WindowUtil.openURL(Constants.URL_ITCH); - } - #end + #if CAN_OPEN_LINKS + function selectDonate() + { + WindowUtil.openURL(Constants.URL_ITCH); + } + #end - #if newgrounds - function selectLogin() - { - openNgPrompt(NgPrompt.showLogin()); - } + #if newgrounds + function selectLogin() + { + openNgPrompt(NgPrompt.showLogin()); + } - function selectLogout() - { - openNgPrompt(NgPrompt.showLogout()); - } + function selectLogout() + { + openNgPrompt(NgPrompt.showLogout()); + } - function showSavedSessionFailed() - { - openNgPrompt(NgPrompt.showSavedSessionFailed()); - } + function showSavedSessionFailed() + { + openNgPrompt(NgPrompt.showSavedSessionFailed()); + } - /** - * Calls openPrompt and redraws the login/logout button - * @param prompt - * @param onClose - */ - public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void) - { - var onPromptClose = checkLoginStatus; - if (onClose != null) - { - onPromptClose = function() - { - checkLoginStatus(); - onClose(); - } - } + /** + * Calls openPrompt and redraws the login/logout button + * @param prompt + * @param onClose + */ + public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void) + { + var onPromptClose = checkLoginStatus; + if (onClose != null) + { + onPromptClose = function() + { + checkLoginStatus(); + onClose(); + } + } - openPrompt(prompt, onPromptClose); - } + openPrompt(prompt, onPromptClose); + } - function checkLoginStatus() - { - var prevLoggedIn = menuItems.has("logout"); - if (prevLoggedIn && !NGio.isLoggedIn) - menuItems.resetItem("login", "logout", selectLogout); - else if (!prevLoggedIn && NGio.isLoggedIn) - menuItems.resetItem("logout", "login", selectLogin); - } - #end + function checkLoginStatus() + { + var prevLoggedIn = menuItems.has("logout"); + if (prevLoggedIn && !NGio.isLoggedIn) menuItems.resetItem("login", "logout", selectLogout); + else if (!prevLoggedIn && NGio.isLoggedIn) menuItems.resetItem("logout", "login", selectLogin); + } + #end - public function openPrompt(prompt:Prompt, onClose:Void->Void) - { - menuItems.enabled = false; - prompt.closeCallback = function() - { - menuItems.enabled = true; - if (onClose != null) - onClose(); - } + public function openPrompt(prompt:Prompt, onClose:Void->Void) + { + menuItems.enabled = false; + prompt.closeCallback = function() + { + menuItems.enabled = true; + if (onClose != null) onClose(); + } - openSubState(prompt); - } + openSubState(prompt); + } - function startExitState(state:FlxState) - { - menuItems.enabled = false; // disable for exit - var duration = 0.4; - menuItems.forEach(function(item) - { - if (menuItems.selectedIndex != item.ID) - { - FlxTween.tween(item, {alpha: 0}, duration, {ease: FlxEase.quadOut}); - } - else - { - item.visible = false; - } - }); + function startExitState(state:FlxState) + { + menuItems.enabled = false; // disable for exit + var duration = 0.4; + menuItems.forEach(function(item) + { + if (menuItems.selectedIndex != item.ID) + { + FlxTween.tween(item, {alpha: 0}, duration, {ease: FlxEase.quadOut}); + } + else + { + item.visible = false; + } + }); - new FlxTimer().start(duration, function(_) FlxG.switchState(state)); - } + new FlxTimer().start(duration, function(_) FlxG.switchState(state)); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (FlxG.onMobile) - { - var touch:FlxTouch = FlxG.touches.getFirst(); + if (FlxG.onMobile) + { + var touch:FlxTouch = FlxG.touches.getFirst(); - if (touch != null) - { - for (item in menuItems) - { - if (touch.overlaps(item)) - { - if (menuItems.selectedIndex == item.ID && touch.justPressed) - menuItems.accept(); - else - menuItems.selectItem(item.ID); - } - } - } - } + if (touch != null) + { + for (item in menuItems) + { + if (touch.overlaps(item)) + { + if (menuItems.selectedIndex == item.ID && touch.justPressed) menuItems.accept(); + else + menuItems.selectItem(item.ID); + } + } + } + } - // FlxG.camera.followLerp = CoolUtil.camLerpShit(0.06); + // FlxG.camera.followLerp = CoolUtil.camLerpShit(0.06); - if (FlxG.sound.music.volume < 0.8) - { - FlxG.sound.music.volume += 0.5 * elapsed; - } + if (FlxG.sound.music.volume < 0.8) + { + FlxG.sound.music.volume += 0.5 * elapsed; + } - if (_exiting) - menuItems.enabled = false; + if (_exiting) menuItems.enabled = false; - if (controls.BACK && menuItems.enabled && !menuItems.busy) - { - FlxG.sound.play(Paths.sound('cancelMenu')); - FlxG.switchState(new TitleState()); - } - } + if (controls.BACK && menuItems.enabled && !menuItems.busy) + { + FlxG.sound.play(Paths.sound('cancelMenu')); + FlxG.switchState(new TitleState()); + } + } } diff --git a/source/funkin/MemoryCounter.hx b/source/funkin/MemoryCounter.hx index 8ce1f47f8..5ef09b332 100644 --- a/source/funkin/MemoryCounter.hx +++ b/source/funkin/MemoryCounter.hx @@ -6,41 +6,40 @@ import openfl.text.TextField; class MemoryCounter extends TextField { - private var memPeak:Float = 0; + var memPeak:Float = 0; - static final BYTES_PER_MEG:Float = 1024 * 1024; - static final ROUND_TO:Float = 1 / 100; + static final BYTES_PER_MEG:Float = 1024 * 1024; + static final ROUND_TO:Float = 1 / 100; - public function new(x:Float = 10, y:Float = 10, color:Int = 0x000000) - { - super(); + public function new(x:Float = 10, y:Float = 10, color:Int = 0x000000) + { + super(); - this.x = x; - this.y = y; - this.width = 500; - this.selectable = false; - this.mouseEnabled = false; - defaultTextFormat = new TextFormat("_sans", 12, color); - text = "RAM: "; + this.x = x; + this.y = y; + this.width = 500; + this.selectable = false; + this.mouseEnabled = false; + defaultTextFormat = new TextFormat("_sans", 12, color); + text = "RAM: "; - #if flash - addEventListener(Event.ENTER_FRAME, function(e) - { - var time = Lib.getTimer(); - __enterFrame(time - currentTime); - }); - #end - } + #if flash + addEventListener(Event.ENTER_FRAME, function(e) + { + var time = Lib.getTimer(); + __enterFrame(time - currentTime); + }); + #end + } - // Event Handlers - @:noCompletion - private #if !flash override #end function __enterFrame(deltaTime:Float):Void - { - var mem:Float = Math.round(System.totalMemory / BYTES_PER_MEG / ROUND_TO) * ROUND_TO; + // Event Handlers + @:noCompletion + #if !flash override #end function __enterFrame(deltaTime:Float):Void + { + var mem:Float = Math.round(System.totalMemory / BYTES_PER_MEG / ROUND_TO) * ROUND_TO; - if (mem > memPeak) - memPeak = mem; + if (mem > memPeak) memPeak = mem; - text = 'RAM: ${mem}mb / ${memPeak}mb'; - } + text = 'RAM: ${mem}mb / ${memPeak}mb'; + } } diff --git a/source/funkin/MenuCharacter.hx b/source/funkin/MenuCharacter.hx index fd678d2de..3e05b9e9f 100644 --- a/source/funkin/MenuCharacter.hx +++ b/source/funkin/MenuCharacter.hx @@ -5,39 +5,38 @@ import flixel.graphics.frames.FlxAtlasFrames; class MenuCharacter extends FlxSprite { - public var character:String; + public var character:String; - public function new(x:Float, character:String = 'bf') - { - super(x); + public function new(x:Float, character:String = 'bf') + { + super(x); - this.character = character; + this.character = character; - var suffix:String = character; + var suffix:String = character; - if (character != "darnell" && character != "nene") - suffix = "characters"; + if (character != "darnell" && character != "nene") suffix = "characters"; - var tex = Paths.getSparrowAtlas('campaign_menu_UI_' + suffix); - frames = tex; + var tex = Paths.getSparrowAtlas('campaign_menu_UI_' + suffix); + frames = tex; - trace(character); + trace(character); - animation.addByPrefix('bf', "BF idle dance white", 24); - animation.addByPrefix('bfConfirm', 'BF HEY!!', 24, false); - animation.addByPrefix('gf', "GF Dancing Beat WHITE", 24); - animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24); - animation.addByPrefix('spooky', "spooky dance idle BLACK LINES", 24); - animation.addByPrefix('pico', "Pico Idle Dance", 24); - animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24); - animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24); - animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24); - animation.addByPrefix('tankman', "Tankman Menu BLACK", 24); - animation.addByPrefix('darnell', "Darnell Black Lines To Scale", 24); - animation.addByPrefix('nene', "Nene Black Lines To Scale", 24); - // Parent Christmas Idle + animation.addByPrefix('bf', "BF idle dance white", 24); + animation.addByPrefix('bfConfirm', 'BF HEY!!', 24, false); + animation.addByPrefix('gf', "GF Dancing Beat WHITE", 24); + animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24); + animation.addByPrefix('spooky', "spooky dance idle BLACK LINES", 24); + animation.addByPrefix('pico', "Pico Idle Dance", 24); + animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24); + animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24); + animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24); + animation.addByPrefix('tankman', "Tankman Menu BLACK", 24); + animation.addByPrefix('darnell', "Darnell Black Lines To Scale", 24); + animation.addByPrefix('nene', "Nene Black Lines To Scale", 24); + // Parent Christmas Idle - animation.play(character); - updateHitbox(); - } + animation.play(character); + updateHitbox(); + } } diff --git a/source/funkin/MenuItem.hx b/source/funkin/MenuItem.hx index 43c927b37..261092a1a 100644 --- a/source/funkin/MenuItem.hx +++ b/source/funkin/MenuItem.hx @@ -8,56 +8,54 @@ import flixel.util.FlxColor; class MenuItem extends FlxSpriteGroup { - public var targetY:Float = 0; - public var week:FlxSprite; - public var flashingInt:Int = 0; + public var targetY:Float = 0; + public var week:FlxSprite; + public var flashingInt:Int = 0; - public function new(x:Float, y:Float, weekNum:Int = 0, weekType:WeekType) - { - super(x, y); + public function new(x:Float, y:Float, weekNum:Int = 0, weekType:WeekType) + { + super(x, y); - var weekStr:String = switch (weekType) - { - case WEEK: - "week"; - case WEEKEND: - "weekend"; - } + var weekStr:String = switch (weekType) + { + case WEEK: + "week"; + case WEEKEND: + "weekend"; + } - week = new FlxSprite().loadGraphic(Paths.image('storymenu/' + weekStr + weekNum)); - add(week); - } + week = new FlxSprite().loadGraphic(Paths.image('storymenu/' + weekStr + weekNum)); + add(week); + } - private var isFlashing:Bool = false; + var isFlashing:Bool = false; - public function startFlashing():Void - { - isFlashing = true; - } + public function startFlashing():Void + { + isFlashing = true; + } - // if it runs at 60fps, fake framerate will be 6 - // if it runs at 144 fps, fake framerate will be like 14, and will update the graphic every 0.016666 * 3 seconds still??? - // so it runs basically every so many seconds, not dependant on framerate?? - // I'm still learning how math works thanks whoever is reading this lol - var fakeFramerate:Int = Math.round((1 / FlxG.elapsed) / 10); + // if it runs at 60fps, fake framerate will be 6 + // if it runs at 144 fps, fake framerate will be like 14, and will update the graphic every 0.016666 * 3 seconds still??? + // so it runs basically every so many seconds, not dependant on framerate?? + // I'm still learning how math works thanks whoever is reading this lol + var fakeFramerate:Int = Math.round((1 / FlxG.elapsed) / 10); - override function update(elapsed:Float) - { - super.update(elapsed); - y = CoolUtil.coolLerp(y, (targetY * 120) + 480, 0.17); + override function update(elapsed:Float) + { + super.update(elapsed); + y = CoolUtil.coolLerp(y, (targetY * 120) + 480, 0.17); - if (isFlashing) - flashingInt += 1; + if (isFlashing) flashingInt += 1; - if (flashingInt % fakeFramerate >= Math.floor(fakeFramerate / 2)) - week.color = 0xFF33ffff; - else - week.color = FlxColor.WHITE; - } + if (flashingInt % fakeFramerate >= Math.floor(fakeFramerate / 2)) week.color = 0xFF33ffff; + else + week.color = FlxColor.WHITE; + } } enum abstract WeekType(String) to String { - var WEEK; - var WEEKEND; + var WEEK; + var WEEKEND; } diff --git a/source/funkin/MusicBeatState.hx b/source/funkin/MusicBeatState.hx index 2caa14aac..5896f6131 100644 --- a/source/funkin/MusicBeatState.hx +++ b/source/funkin/MusicBeatState.hx @@ -18,181 +18,174 @@ import funkin.util.SortUtil; */ class MusicBeatState extends FlxUIState { - private var controls(get, never):Controls; + var controls(get, never):Controls; - inline function get_controls():Controls - return PlayerSettings.player1.controls; + inline function get_controls():Controls + return PlayerSettings.player1.controls; - public var leftWatermarkText:FlxText = null; - public var rightWatermarkText:FlxText = null; + public var leftWatermarkText:FlxText = null; + public var rightWatermarkText:FlxText = null; - public function new() - { - super(); + public function new() + { + super(); - initCallbacks(); - } + initCallbacks(); + } - function initCallbacks() - { - subStateOpened.add(onOpenSubstateComplete); - subStateClosed.add(onCloseSubstateComplete); - } + function initCallbacks() + { + subStateOpened.add(onOpenSubstateComplete); + subStateClosed.add(onCloseSubstateComplete); + } - override function create() - { - super.create(); + override function create() + { + super.create(); - createWatermarkText(); + createWatermarkText(); - Conductor.beatHit.add(this.beatHit); - Conductor.stepHit.add(this.stepHit); - } + Conductor.beatHit.add(this.beatHit); + Conductor.stepHit.add(this.stepHit); + } - public override function destroy():Void - { - super.destroy(); - Conductor.beatHit.remove(this.beatHit); - Conductor.stepHit.remove(this.stepHit); - } + public override function destroy():Void + { + super.destroy(); + Conductor.beatHit.remove(this.beatHit); + Conductor.stepHit.remove(this.stepHit); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - // Emergency exit button. - if (FlxG.keys.justPressed.F4) - FlxG.switchState(new MainMenuState()); + // Emergency exit button. + if (FlxG.keys.justPressed.F4) FlxG.switchState(new MainMenuState()); - // This can now be used in EVERY STATE YAY! - if (FlxG.keys.justPressed.F5) - debug_refreshModules(); + // This can now be used in EVERY STATE YAY! + if (FlxG.keys.justPressed.F5) debug_refreshModules(); - // ` / ~ to open the debug menu. - if (FlxG.keys.justPressed.GRAVEACCENT) - { - // TODO: Does this break anything? - this.persistentUpdate = false; - this.persistentDraw = false; - FlxG.state.openSubState(new DebugMenuSubState()); - } + // ` / ~ to open the debug menu. + if (FlxG.keys.justPressed.GRAVEACCENT) + { + // TODO: Does this break anything? + this.persistentUpdate = false; + this.persistentDraw = false; + FlxG.state.openSubState(new DebugMenuSubState()); + } - // Display Conductor info in the watch window. - FlxG.watch.addQuick("songPos", Conductor.songPosition); - FlxG.watch.addQuick("currentStepTime", Conductor.currentStepTime); - FlxG.watch.addQuick("bpm", Conductor.bpm); + // Display Conductor info in the watch window. + FlxG.watch.addQuick("songPos", Conductor.songPosition); + FlxG.watch.addQuick("currentStepTime", Conductor.currentStepTime); + FlxG.watch.addQuick("bpm", Conductor.bpm); - dispatchEvent(new UpdateScriptEvent(elapsed)); - } + dispatchEvent(new UpdateScriptEvent(elapsed)); + } - function createWatermarkText() - { - // Both have an xPos of 0, but a width equal to the full screen. - // The rightWatermarkText is right aligned, which puts the text in the correct spot. - leftWatermarkText = new FlxText(0, FlxG.height - 18, FlxG.width, '', 12); - rightWatermarkText = new FlxText(0, FlxG.height - 18, FlxG.width, '', 12); + function createWatermarkText() + { + // Both have an xPos of 0, but a width equal to the full screen. + // The rightWatermarkText is right aligned, which puts the text in the correct spot. + leftWatermarkText = new FlxText(0, FlxG.height - 18, FlxG.width, '', 12); + rightWatermarkText = new FlxText(0, FlxG.height - 18, FlxG.width, '', 12); - // 100,000 should be good enough. - leftWatermarkText.zIndex = 100000; - rightWatermarkText.zIndex = 100000; - leftWatermarkText.scrollFactor.set(0, 0); - rightWatermarkText.scrollFactor.set(0, 0); - leftWatermarkText.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - rightWatermarkText.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + // 100,000 should be good enough. + leftWatermarkText.zIndex = 100000; + rightWatermarkText.zIndex = 100000; + leftWatermarkText.scrollFactor.set(0, 0); + rightWatermarkText.scrollFactor.set(0, 0); + leftWatermarkText.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + rightWatermarkText.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - add(leftWatermarkText); - add(rightWatermarkText); - } + add(leftWatermarkText); + add(rightWatermarkText); + } - function dispatchEvent(event:ScriptEvent) - { - ModuleHandler.callEvent(event); - } + function dispatchEvent(event:ScriptEvent) + { + ModuleHandler.callEvent(event); + } - function debug_refreshModules() - { - PolymodHandler.forceReloadAssets(); + function debug_refreshModules() + { + PolymodHandler.forceReloadAssets(); - // Restart the current state, so old data is cleared. - FlxG.resetState(); - } + // Restart the current state, so old data is cleared. + FlxG.resetState(); + } - public function stepHit():Bool - { - var event = new SongTimeScriptEvent(ScriptEvent.SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep); + public function stepHit():Bool + { + var event = new SongTimeScriptEvent(ScriptEvent.SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return false; + if (event.eventCanceled) return false; - return true; - } + return true; + } - public function beatHit():Bool - { - var event = new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep); + public function beatHit():Bool + { + var event = new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return false; + if (event.eventCanceled) return false; - return true; - } + return true; + } - /** - * Refreshes the state, by redoing the render order of all sprites. - * It does this based on the `zIndex` of each prop. - */ - public function refresh() - { - sort(SortUtil.byZIndex, FlxSort.ASCENDING); - } + /** + * Refreshes the state, by redoing the render order of all sprites. + * It does this based on the `zIndex` of each prop. + */ + public function refresh() + { + sort(SortUtil.byZIndex, FlxSort.ASCENDING); + } - override function switchTo(nextState:FlxState):Bool - { - var event = new StateChangeScriptEvent(ScriptEvent.STATE_CHANGE_BEGIN, nextState, true); + override function switchTo(nextState:FlxState):Bool + { + var event = new StateChangeScriptEvent(ScriptEvent.STATE_CHANGE_BEGIN, nextState, true); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return false; + if (event.eventCanceled) return false; - return super.switchTo(nextState); - } + return super.switchTo(nextState); + } - public override function openSubState(targetSubstate:FlxSubState):Void - { - var event = new SubStateScriptEvent(ScriptEvent.SUBSTATE_OPEN_BEGIN, targetSubstate, true); + public override function openSubState(targetSubstate:FlxSubState):Void + { + var event = new SubStateScriptEvent(ScriptEvent.SUBSTATE_OPEN_BEGIN, targetSubstate, true); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return; + if (event.eventCanceled) return; - super.openSubState(targetSubstate); - } + super.openSubState(targetSubstate); + } - function onOpenSubstateComplete(targetState:FlxSubState):Void - { - dispatchEvent(new SubStateScriptEvent(ScriptEvent.SUBSTATE_OPEN_END, targetState, true)); - } + function onOpenSubstateComplete(targetState:FlxSubState):Void + { + dispatchEvent(new SubStateScriptEvent(ScriptEvent.SUBSTATE_OPEN_END, targetState, true)); + } - public override function closeSubState():Void - { - var event = new SubStateScriptEvent(ScriptEvent.SUBSTATE_CLOSE_BEGIN, this.subState, true); + public override function closeSubState():Void + { + var event = new SubStateScriptEvent(ScriptEvent.SUBSTATE_CLOSE_BEGIN, this.subState, true); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return; + if (event.eventCanceled) return; - super.closeSubState(); - } + super.closeSubState(); + } - function onCloseSubstateComplete(targetState:FlxSubState):Void - { - dispatchEvent(new SubStateScriptEvent(ScriptEvent.SUBSTATE_CLOSE_END, targetState, true)); - } + function onCloseSubstateComplete(targetState:FlxSubState):Void + { + dispatchEvent(new SubStateScriptEvent(ScriptEvent.SUBSTATE_CLOSE_END, targetState, true)); + } } diff --git a/source/funkin/MusicBeatSubstate.hx b/source/funkin/MusicBeatSubstate.hx index 7840b9e34..802022a67 100644 --- a/source/funkin/MusicBeatSubstate.hx +++ b/source/funkin/MusicBeatSubstate.hx @@ -11,86 +11,82 @@ import funkin.modding.module.ModuleHandler; */ class MusicBeatSubstate extends FlxSubState { - public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) - { - super(bgColor); - } + public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) + { + super(bgColor); + } - private var curStep:Int = 0; - private var curBeat:Int = 0; - private var controls(get, never):Controls; + var curStep:Int = 0; + var curBeat:Int = 0; + var controls(get, never):Controls; - inline function get_controls():Controls - return PlayerSettings.player1.controls; + inline function get_controls():Controls + return PlayerSettings.player1.controls; - override function update(elapsed:Float) - { - // everyStep(); - var oldStep:Int = curStep; + override function update(elapsed:Float) + { + // everyStep(); + var oldStep:Int = curStep; - updateCurStep(); - curBeat = Math.floor(curStep / 4); + updateCurStep(); + curBeat = Math.floor(curStep / 4); - if (oldStep != curStep && curStep >= 0) - stepHit(); + if (oldStep != curStep && curStep >= 0) stepHit(); - super.update(elapsed); - } + super.update(elapsed); + } - private function updateCurStep():Void - { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } - for (i in 0...Conductor.bpmChangeMap.length) - { - if (Conductor.songPosition > Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; - } + function updateCurStep():Void + { + var lastChange:BPMChangeEvent = + { + stepTime: 0, + songTime: 0, + bpm: 0 + } + for (i in 0...Conductor.bpmChangeMap.length) + { + if (Conductor.songPosition > Conductor.bpmChangeMap[i].songTime) lastChange = Conductor.bpmChangeMap[i]; + } - curStep = lastChange.stepTime + Math.floor(((Conductor.songPosition - Conductor.audioOffset) - lastChange.songTime) / Conductor.stepCrochet); - } + curStep = lastChange.stepTime + Math.floor(((Conductor.songPosition - Conductor.audioOffset) - lastChange.songTime) / Conductor.stepCrochet); + } - public function stepHit():Bool - { - var event = new SongTimeScriptEvent(ScriptEvent.SONG_STEP_HIT, curBeat, curStep); + public function stepHit():Bool + { + var event = new SongTimeScriptEvent(ScriptEvent.SONG_STEP_HIT, curBeat, curStep); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return false; + if (event.eventCanceled) return false; - if (curStep % 4 == 0) - beatHit(); + if (curStep % 4 == 0) beatHit(); - return true; - } + return true; + } - function dispatchEvent(event:ScriptEvent) - { - ModuleHandler.callEvent(event); - } + function dispatchEvent(event:ScriptEvent) + { + ModuleHandler.callEvent(event); + } - /** - * Close this substate and replace it with a different one. - */ - public function switchSubState(substate:FlxSubState):Void - { - this.close(); - this._parentState.openSubState(substate); - } + /** + * Close this substate and replace it with a different one. + */ + public function switchSubState(substate:FlxSubState):Void + { + this.close(); + this._parentState.openSubState(substate); + } - public function beatHit():Bool - { - var event = new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, curBeat, curStep); + public function beatHit():Bool + { + var event = new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, curBeat, curStep); - dispatchEvent(event); + dispatchEvent(event); - if (event.eventCanceled) - return false; + if (event.eventCanceled) return false; - return true; - } + return true; + } } diff --git a/source/funkin/NGio.hx b/source/funkin/NGio.hx index fdab9507d..f538c9656 100644 --- a/source/funkin/NGio.hx +++ b/source/funkin/NGio.hx @@ -22,289 +22,287 @@ import openfl.display.Stage; */ class NGio { - #if newgrounds - /** - * True, if the saved sessionId was used in the initial login, and failed to connect. - * Used in MainMenuState to show a popup to establish a new connection - */ - public static var savedSessionFailed(default, null):Bool = false; + #if newgrounds + /** + * True, if the saved sessionId was used in the initial login, and failed to connect. + * Used in MainMenuState to show a popup to establish a new connection + */ + public static var savedSessionFailed(default, null):Bool = false; - public static var scoreboardsLoaded:Bool = false; - public static var isLoggedIn(get, never):Bool; + public static var scoreboardsLoaded:Bool = false; + public static var isLoggedIn(get, never):Bool; - inline static function get_isLoggedIn() - { - return NG.core != null && NG.core.loggedIn; - } + inline static function get_isLoggedIn() + { + return NG.core != null && NG.core.loggedIn; + } - public static var scoreboardArray:Array = []; + public static var scoreboardArray:Array = []; - public static var ngDataLoaded(default, null):FlxSignal = new FlxSignal(); - public static var ngScoresLoaded(default, null):FlxSignal = new FlxSignal(); + public static var ngDataLoaded(default, null):FlxSignal = new FlxSignal(); + public static var ngScoresLoaded(default, null):FlxSignal = new FlxSignal(); - public static var GAME_VER:String = ""; + public static var GAME_VER:String = ""; - static public function checkVersion(callback:String->Void) - { - trace('checking NG.io version'); - GAME_VER = "v" + Application.current.meta.get('version'); + static public function checkVersion(callback:String->Void) + { + trace('checking NG.io version'); + GAME_VER = "v" + Application.current.meta.get('version'); - NG.core.calls.app.getCurrentVersion(GAME_VER).addDataHandler(function(response) - { - GAME_VER = response.result.data.currentVersion; - trace('CURRENT NG VERSION: ' + GAME_VER); - callback(GAME_VER); - }).send(); - } + NG.core.calls.app.getCurrentVersion(GAME_VER).addDataHandler(function(response) + { + GAME_VER = response.result.data.currentVersion; + trace('CURRENT NG VERSION: ' + GAME_VER); + callback(GAME_VER); + }).send(); + } - static public function init() - { - var api = APIStuff.API; - if (api == null || api.length == 0) - { - trace("Missing Newgrounds API key, aborting connection"); - return; - } - trace("connecting to newgrounds"); + static public function init() + { + var api = APIStuff.API; + if (api == null || api.length == 0) + { + trace("Missing Newgrounds API key, aborting connection"); + return; + } + trace("connecting to newgrounds"); - #if NG_FORCE_EXPIRED_SESSION - var sessionId:String = "fake_session_id"; - function onSessionFail(error:Error) - { - trace("Forcing an expired saved session. " + "To disable, comment out NG_FORCE_EXPIRED_SESSION in Project.xml"); - savedSessionFailed = true; - } - #else - var sessionId:String = NGLite.getSessionId(); - if (sessionId != null) - trace("found web session id"); + #if NG_FORCE_EXPIRED_SESSION + var sessionId:String = "fake_session_id"; + function onSessionFail(error:Error) + { + trace("Forcing an expired saved session. " + "To disable, comment out NG_FORCE_EXPIRED_SESSION in Project.xml"); + savedSessionFailed = true; + } + #else + var sessionId:String = NGLite.getSessionId(); + if (sessionId != null) trace("found web session id"); - #if (debug) - if (sessionId == null && APIStuff.SESSION != null) - { - trace("using debug session id"); - sessionId = APIStuff.SESSION; - } - #end + #if (debug) + if (sessionId == null && APIStuff.SESSION != null) + { + trace("using debug session id"); + sessionId = APIStuff.SESSION; + } + #end - var onSessionFail:Error->Void = null; - if (sessionId == null && FlxG.save.data.sessionId != null) - { - trace("using stored session id"); - sessionId = FlxG.save.data.sessionId; - onSessionFail = function(error) savedSessionFailed = true; - } - #end + var onSessionFail:Error->Void = null; + if (sessionId == null && FlxG.save.data.sessionId != null) + { + trace("using stored session id"); + sessionId = FlxG.save.data.sessionId; + onSessionFail = function(error) savedSessionFailed = true; + } + #end - NG.create(api, sessionId, #if NG_DEBUG true #else false #end, onSessionFail); + NG.create(api, sessionId, #if NG_DEBUG true #else false #end, onSessionFail); - #if NG_VERBOSE - NG.core.verbose = true; - #end - // Set the encryption cipher/format to RC4/Base64. AES128 and Hex are not implemented yet - NG.core.initEncryption(APIStuff.EncKey); // Found in you NG project view + #if NG_VERBOSE + NG.core.verbose = true; + #end + // Set the encryption cipher/format to RC4/Base64. AES128 and Hex are not implemented yet + NG.core.initEncryption(APIStuff.EncKey); // Found in you NG project view - if (NG.core.attemptingLogin) - { - /* a session_id was found in the loadervars, this means the user is playing on newgrounds.com - * and we should login shortly. lets wait for that to happen - */ - trace("attempting login"); - NG.core.onLogin.add(onNGLogin); - } - // GK: taking out auto login, adding a login button to the main menu - // else - // { - // /* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to. - // * Note: This will cause a new browser window to pop up where they can log in to newgrounds - // */ - // NG.core.requestLogin(onNGLogin); - // } - } + if (NG.core.attemptingLogin) + { + /* a session_id was found in the loadervars, this means the user is playing on newgrounds.com + * and we should login shortly. lets wait for that to happen + */ + trace("attempting login"); + NG.core.onLogin.add(onNGLogin); + } + // GK: taking out auto login, adding a login button to the main menu + // else + // { + // /* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to. + // * Note: This will cause a new browser window to pop up where they can log in to newgrounds + // */ + // NG.core.requestLogin(onNGLogin); + // } + } - /** - * Attempts to log in to newgrounds by requesting a new session ID, only call if no session ID was found automatically - * @param popupLauncher The function to call to open the login url, must be inside - * a user input event or the popup blocker will block it. - * @param onComplete A callback with the result of the connection. - */ - static public function login(?popupLauncher:(Void->Void)->Void, onComplete:ConnectionResult->Void) - { - trace("Logging in manually"); - var onPending:Void->Void = null; - if (popupLauncher != null) - { - onPending = function() popupLauncher(NG.core.openPassportUrl); - } + /** + * Attempts to log in to newgrounds by requesting a new session ID, only call if no session ID was found automatically + * @param popupLauncher The function to call to open the login url, must be inside + * a user input event or the popup blocker will block it. + * @param onComplete A callback with the result of the connection. + */ + static public function login(?popupLauncher:(Void->Void)->Void, onComplete:ConnectionResult->Void) + { + trace("Logging in manually"); + var onPending:Void->Void = null; + if (popupLauncher != null) + { + onPending = function() popupLauncher(NG.core.openPassportUrl); + } - var onSuccess:Void->Void = onNGLogin; - var onFail:Error->Void = null; - var onCancel:Void->Void = null; - if (onComplete != null) - { - onSuccess = function() - { - onNGLogin(); - onComplete(Success); - } - onFail = function(e) onComplete(Fail(e.message)); - onCancel = function() onComplete(Cancelled); - } + var onSuccess:Void->Void = onNGLogin; + var onFail:Error->Void = null; + var onCancel:Void->Void = null; + if (onComplete != null) + { + onSuccess = function() + { + onNGLogin(); + onComplete(Success); + } + onFail = function(e) onComplete(Fail(e.message)); + onCancel = function() onComplete(Cancelled); + } - NG.core.requestLogin(onSuccess, onPending, onFail, onCancel); - } + NG.core.requestLogin(onSuccess, onPending, onFail, onCancel); + } - inline static public function cancelLogin():Void - { - NG.core.cancelLoginRequest(); - } + inline static public function cancelLogin():Void + { + NG.core.cancelLoginRequest(); + } - static function onNGLogin():Void - { - trace('logged in! user:${NG.core.user.name}'); - FlxG.save.data.sessionId = NG.core.sessionId; - FlxG.save.flush(); - // Load medals then call onNGMedalFetch() - NG.core.requestMedals(onNGMedalFetch); + static function onNGLogin():Void + { + trace('logged in! user:${NG.core.user.name}'); + FlxG.save.data.sessionId = NG.core.sessionId; + FlxG.save.flush(); + // Load medals then call onNGMedalFetch() + NG.core.requestMedals(onNGMedalFetch); - // Load Scoreboards hten call onNGBoardsFetch() - NG.core.requestScoreBoards(onNGBoardsFetch); + // Load Scoreboards hten call onNGBoardsFetch() + NG.core.requestScoreBoards(onNGBoardsFetch); - ngDataLoaded.dispatch(); - } + ngDataLoaded.dispatch(); + } - static public function logout() - { - NG.core.logOut(); + static public function logout() + { + NG.core.logOut(); - FlxG.save.data.sessionId = null; - FlxG.save.flush(); - } + FlxG.save.data.sessionId = null; + FlxG.save.flush(); + } - // --- MEDALS - static function onNGMedalFetch():Void - { - /* - // Reading medal info - for (id in NG.core.medals.keys()) - { - var medal = NG.core.medals.get(id); - trace('loaded medal id:$id, name:${medal.name}, description:${medal.description}'); - } + // --- MEDALS + static function onNGMedalFetch():Void + { + /* + // Reading medal info + for (id in NG.core.medals.keys()) + { + var medal = NG.core.medals.get(id); + trace('loaded medal id:$id, name:${medal.name}, description:${medal.description}'); + } - // Unlocking medals - var unlockingMedal = NG.core.medals.get(54352);// medal ids are listed in your NG project viewer - if (!unlockingMedal.unlocked) - unlockingMedal.sendUnlock(); - */ - } + // Unlocking medals + var unlockingMedal = NG.core.medals.get(54352);// medal ids are listed in your NG project viewer + if (!unlockingMedal.unlocked) + unlockingMedal.sendUnlock(); + */ + } - // --- SCOREBOARDS - static function onNGBoardsFetch():Void - { - /* - // Reading medal info - for (id in NG.core.scoreBoards.keys()) - { - var board = NG.core.scoreBoards.get(id); - trace('loaded scoreboard id:$id, name:${board.name}'); - } - */ - // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view + // --- SCOREBOARDS + static function onNGBoardsFetch():Void + { + /* + // Reading medal info + for (id in NG.core.scoreBoards.keys()) + { + var board = NG.core.scoreBoards.get(id); + trace('loaded scoreboard id:$id, name:${board.name}'); + } + */ + // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view - // Posting a score thats OVER 9000! - // board.postScore(FlxG.random.int(0, 1000)); + // Posting a score thats OVER 9000! + // board.postScore(FlxG.random.int(0, 1000)); - // --- To view the scores you first need to select the range of scores you want to see --- + // --- To view the scores you first need to select the range of scores you want to see --- - // add an update listener so we know when we get the new scores - // board.onUpdate.add(onNGScoresFetch); - trace("shoulda got score by NOW!"); - // board.requestScores(20);// get the best 10 scores ever logged - // more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores - } + // add an update listener so we know when we get the new scores + // board.onUpdate.add(onNGScoresFetch); + trace("shoulda got score by NOW!"); + // board.requestScores(20);// get the best 10 scores ever logged + // more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores + } - static function onNGScoresFetch():Void - { - scoreboardsLoaded = true; + static function onNGScoresFetch():Void + { + scoreboardsLoaded = true; - ngScoresLoaded.dispatch(); - /* - for (score in NG.core.scoreBoards.get(8737).scores) - { - trace('score loaded user:${score.user.name}, score:${score.formatted_value}'); + ngScoresLoaded.dispatch(); + /* + for (score in NG.core.scoreBoards.get(8737).scores) + { + trace('score loaded user:${score.user.name}, score:${score.formatted_value}'); - } - */ + } + */ - // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view - // board.postScore(HighScore.score); + // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view + // board.postScore(HighScore.score); - // NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores; - } - #end + // NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores; + } + #end - static public function logEvent(event:String) - { - #if newgrounds - NG.core.calls.event.logEvent(event).send(); - trace('should have logged: ' + event); - #else - #if debug - trace('event:$event - not logged, missing NG.io lib'); - #end - #end - } + static public function logEvent(event:String) + { + #if newgrounds + NG.core.calls.event.logEvent(event).send(); + trace('should have logged: ' + event); + #else + #if debug + trace('event:$event - not logged, missing NG.io lib'); + #end + #end + } - static public function unlockMedal(id:Int) - { - #if newgrounds - if (isLoggedIn) - { - var medal = NG.core.medals.get(id); - if (!medal.unlocked) - medal.sendUnlock(); - } - #else - #if debug - trace('medal:$id - not unlocked, missing NG.io lib'); - #end - #end - } + static public function unlockMedal(id:Int) + { + #if newgrounds + if (isLoggedIn) + { + var medal = NG.core.medals.get(id); + if (!medal.unlocked) medal.sendUnlock(); + } + #else + #if debug + trace('medal:$id - not unlocked, missing NG.io lib'); + #end + #end + } - static public function postScore(score:Int = 0, song:String) - { - #if newgrounds - if (isLoggedIn) - { - for (id in NG.core.scoreBoards.keys()) - { - var board = NG.core.scoreBoards.get(id); + static public function postScore(score:Int = 0, song:String) + { + #if newgrounds + if (isLoggedIn) + { + for (id in NG.core.scoreBoards.keys()) + { + var board = NG.core.scoreBoards.get(id); - if (song == board.name) - { - board.postScore(score, "Uhh meow?"); - } + if (song == board.name) + { + board.postScore(score, "Uhh meow?"); + } - // trace('loaded scoreboard id:$id, name:${board.name}'); - } - } - #else - #if debug - trace('Song:$song, Score:$score - not posted, missing NG.io lib'); - #end - #end - } + // trace('loaded scoreboard id:$id, name:${board.name}'); + } + } + #else + #if debug + trace('Song:$song, Score:$score - not posted, missing NG.io lib'); + #end + #end + } } enum ConnectionResult { - /** Log in successful */ - Success; + /** Log in successful */ + Success; - /** Could not login */ - Fail(msg:String); + /** Could not login */ + Fail(msg:String); - /** User cancelled the login */ - Cancelled; + /** User cancelled the login */ + Cancelled; } diff --git a/source/funkin/Note.hx b/source/funkin/Note.hx index 144614757..7fc49717e 100644 --- a/source/funkin/Note.hx +++ b/source/funkin/Note.hx @@ -12,279 +12,271 @@ import funkin.util.Constants; class Note extends FlxSprite { - public var data = new NoteData(); + public var data = new NoteData(); - /** - * code colors for.... code.... - * i think goes in order of left to right - * - * left 0 - * down 1 - * up 2 - * right 3 - */ - public static var codeColors:Array = [0xFFFF22AA, 0xFF00EEFF, 0xFF00CC00, 0xFFCC1111]; + /** + * code colors for.... code.... + * i think goes in order of left to right + * + * left 0 + * down 1 + * up 2 + * right 3 + */ + public static var codeColors:Array = [0xFFFF22AA, 0xFF00EEFF, 0xFF00CC00, 0xFFCC1111]; - public var mustPress:Bool = false; - public var followsTime:Bool = true; // used if you want the note to follow the time shit! - public var canBeHit:Bool = false; - public var tooLate:Bool = false; - public var wasGoodHit:Bool = false; - public var prevNote:Note; + public var mustPress:Bool = false; + public var followsTime:Bool = true; // used if you want the note to follow the time shit! + public var canBeHit:Bool = false; + public var tooLate:Bool = false; + public var wasGoodHit:Bool = false; + public var prevNote:Note; - private var willMiss:Bool = false; + var willMiss:Bool = false; - public var invisNote:Bool = false; + public var invisNote:Bool = false; - public var isSustainNote:Bool = false; + public var isSustainNote:Bool = false; - public var colorSwap:ColorSwap; + public var colorSwap:ColorSwap; - /** the lowercase name of the note, for anim control, i.e. left right up down */ - public var dirName(get, never):String; + /** the lowercase name of the note, for anim control, i.e. left right up down */ + public var dirName(get, never):String; - inline function get_dirName() - return data.dirName; + inline function get_dirName() + return data.dirName; - /** the uppercase name of the note, for anim control, i.e. left right up down */ - public var dirNameUpper(get, never):String; + /** the uppercase name of the note, for anim control, i.e. left right up down */ + public var dirNameUpper(get, never):String; - inline function get_dirNameUpper() - return data.dirNameUpper; + inline function get_dirNameUpper() + return data.dirNameUpper; - /** the lowercase name of the note's color, for anim control, i.e. purple blue green red */ - public var colorName(get, never):String; + /** the lowercase name of the note's color, for anim control, i.e. purple blue green red */ + public var colorName(get, never):String; - inline function get_colorName() - return data.colorName; + inline function get_colorName() + return data.colorName; - /** the lowercase name of the note's color, for anim control, i.e. purple blue green red */ - public var colorNameUpper(get, never):String; + /** the lowercase name of the note's color, for anim control, i.e. purple blue green red */ + public var colorNameUpper(get, never):String; - inline function get_colorNameUpper() - return data.colorNameUpper; + inline function get_colorNameUpper() + return data.colorNameUpper; - public var highStakes(get, never):Bool; + public var highStakes(get, never):Bool; - inline function get_highStakes() - return data.highStakes; + inline function get_highStakes() + return data.highStakes; - public var lowStakes(get, never):Bool; + public var lowStakes(get, never):Bool; - inline function get_lowStakes() - return data.lowStakes; + inline function get_lowStakes() + return data.lowStakes; - public static var swagWidth:Float = 160 * 0.7; - public static var PURP_NOTE:Int = 0; - public static var GREEN_NOTE:Int = 2; - public static var BLUE_NOTE:Int = 1; - public static var RED_NOTE:Int = 3; + public static var swagWidth:Float = 160 * 0.7; + public static var PURP_NOTE:Int = 0; + public static var GREEN_NOTE:Int = 2; + public static var BLUE_NOTE:Int = 1; + public static var RED_NOTE:Int = 3; - // SCORING STUFF - public static var HIT_WINDOW:Float = (10 / 60) * 1000; // 166.67 ms hit window (10 frames at 60fps) - // thresholds are fractions of HIT_WINDOW ^^ - // anything above bad threshold is shit - public static var BAD_THRESHOLD:Float = 0.8; // 125ms , 8 frames - public static var GOOD_THRESHOLD:Float = 0.55; // 91.67ms , 5.5 frames - public static var SICK_THRESHOLD:Float = 0.2; // 33.33ms , 2 frames + // SCORING STUFF + public static var HIT_WINDOW:Float = (10 / 60) * 1000; // 166.67 ms hit window (10 frames at 60fps) + // thresholds are fractions of HIT_WINDOW ^^ + // anything above bad threshold is shit + public static var BAD_THRESHOLD:Float = 0.8; // 125ms , 8 frames + public static var GOOD_THRESHOLD:Float = 0.55; // 91.67ms , 5.5 frames + public static var SICK_THRESHOLD:Float = 0.2; // 33.33ms , 2 frames - public var noteSpeedMulti:Float = 1; - public var pastHalfWay:Bool = false; + public var noteSpeedMulti:Float = 1; + public var pastHalfWay:Bool = false; - // anything below sick threshold is sick - public static var arrowColors:Array = [1, 1, 1, 1]; + // anything below sick threshold is sick + public static var arrowColors:Array = [1, 1, 1, 1]; - // Which note asset to load? - public var style:StrumlineStyle = NORMAL; + // Which note asset to load? + public var style:StrumlineStyle = NORMAL; - public function new(strumTime:Float = 0, noteData:NoteType, ?prevNote:Note, ?sustainNote:Bool = false, ?style:StrumlineStyle = NORMAL) - { - super(); + public function new(strumTime:Float = 0, noteData:NoteType, ?prevNote:Note, ?sustainNote:Bool = false, ?style:StrumlineStyle = NORMAL) + { + super(); - if (prevNote == null) - prevNote = this; + if (prevNote == null) prevNote = this; - this.prevNote = prevNote; - isSustainNote = sustainNote; + this.prevNote = prevNote; + isSustainNote = sustainNote; - x += 50; - // MAKE SURE ITS DEFINITELY OFF SCREEN? - y -= 2000; - data.strumTime = strumTime; + x += 50; + // MAKE SURE ITS DEFINITELY OFF SCREEN? + y -= 2000; + data.strumTime = strumTime; - data.noteData = noteData; + data.noteData = noteData; - this.style = style; + this.style = style; - if (this.style == null) - this.style = StrumlineStyle.NORMAL; + if (this.style == null) this.style = StrumlineStyle.NORMAL; - // TODO: Make this logic more generic - switch (this.style) - { - case PIXEL: - loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); + // TODO: Make this logic more generic + switch (this.style) + { + case PIXEL: + loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); - animation.add('greenScroll', [6]); - animation.add('redScroll', [7]); - animation.add('blueScroll', [5]); - animation.add('purpleScroll', [4]); + animation.add('greenScroll', [6]); + animation.add('redScroll', [7]); + animation.add('blueScroll', [5]); + animation.add('purpleScroll', [4]); - if (isSustainNote) - { - loadGraphic(Paths.image('weeb/pixelUI/arrowEnds'), true, 7, 6); + if (isSustainNote) + { + loadGraphic(Paths.image('weeb/pixelUI/arrowEnds'), true, 7, 6); - animation.add('purpleholdend', [4]); - animation.add('greenholdend', [6]); - animation.add('redholdend', [7]); - animation.add('blueholdend', [5]); + animation.add('purpleholdend', [4]); + animation.add('greenholdend', [6]); + animation.add('redholdend', [7]); + animation.add('blueholdend', [5]); - animation.add('purplehold', [0]); - animation.add('greenhold', [2]); - animation.add('redhold', [3]); - animation.add('bluehold', [1]); - } + animation.add('purplehold', [0]); + animation.add('greenhold', [2]); + animation.add('redhold', [3]); + animation.add('bluehold', [1]); + } - setGraphicSize(Std.int(width * Constants.PIXEL_ART_SCALE)); - updateHitbox(); + setGraphicSize(Std.int(width * Constants.PIXEL_ART_SCALE)); + updateHitbox(); - default: - frames = Paths.getSparrowAtlas('NOTE_assets'); + default: + frames = Paths.getSparrowAtlas('NOTE_assets'); - animation.addByPrefix('purpleScroll', 'purple instance'); - animation.addByPrefix('blueScroll', 'blue instance'); - animation.addByPrefix('greenScroll', 'green instance'); - animation.addByPrefix('redScroll', 'red instance'); + animation.addByPrefix('purpleScroll', 'purple instance'); + animation.addByPrefix('blueScroll', 'blue instance'); + animation.addByPrefix('greenScroll', 'green instance'); + animation.addByPrefix('redScroll', 'red instance'); - animation.addByPrefix('purpleholdend', 'pruple end hold'); - animation.addByPrefix('greenholdend', 'green hold end'); - animation.addByPrefix('redholdend', 'red hold end'); - animation.addByPrefix('blueholdend', 'blue hold end'); + animation.addByPrefix('purpleholdend', 'pruple end hold'); + animation.addByPrefix('greenholdend', 'green hold end'); + animation.addByPrefix('redholdend', 'red hold end'); + animation.addByPrefix('blueholdend', 'blue hold end'); - animation.addByPrefix('purplehold', 'purple hold piece'); - animation.addByPrefix('greenhold', 'green hold piece'); - animation.addByPrefix('redhold', 'red hold piece'); - animation.addByPrefix('bluehold', 'blue hold piece'); + animation.addByPrefix('purplehold', 'purple hold piece'); + animation.addByPrefix('greenhold', 'green hold piece'); + animation.addByPrefix('redhold', 'red hold piece'); + animation.addByPrefix('bluehold', 'blue hold piece'); - setGraphicSize(Std.int(width * 0.7)); - updateHitbox(); - antialiasing = true; + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); + antialiasing = true; - // colorSwap.colorToReplace = 0xFFF9393F; - // colorSwap.newColor = 0xFF00FF00; + // colorSwap.colorToReplace = 0xFFF9393F; + // colorSwap.newColor = 0xFF00FF00; - // color = FlxG.random.color(); - // color.saturation *= 4; - // replaceColor(0xFFC1C1C1, FlxColor.RED); - } + // color = FlxG.random.color(); + // color.saturation *= 4; + // replaceColor(0xFFC1C1C1, FlxColor.RED); + } - colorSwap = new ColorSwap(); - shader = colorSwap.shader; - updateColors(); + colorSwap = new ColorSwap(); + shader = colorSwap.shader; + updateColors(); - x += swagWidth * data.int; - animation.play(data.colorName + 'Scroll'); + x += swagWidth * data.int; + animation.play(data.colorName + 'Scroll'); - // trace(prevNote); + // trace(prevNote); - if (isSustainNote && prevNote != null) - { - alpha = 0.6; + if (isSustainNote && prevNote != null) + { + alpha = 0.6; - if (PreferencesMenu.getPref('downscroll')) - angle = 180; + if (PreferencesMenu.getPref('downscroll')) angle = 180; - x += width / 2; + x += width / 2; - animation.play(data.colorName + 'holdend'); + animation.play(data.colorName + 'holdend'); - updateHitbox(); + updateHitbox(); - x -= width / 2; + x -= width / 2; - if (PlayState.instance.currentStageId.startsWith('school')) - x += 30; + if (PlayState.instance.currentStageId.startsWith('school')) x += 30; - if (prevNote.isSustainNote) - { - prevNote.animation.play(prevNote.colorName + 'hold'); - prevNote.updateHitbox(); + if (prevNote.isSustainNote) + { + prevNote.animation.play(prevNote.colorName + 'hold'); + prevNote.updateHitbox(); - var scaleThing:Float = Math.round((Conductor.stepCrochet) * (0.45 * FlxMath.roundDecimal(SongLoad.getSpeed(), 2))); - // get them a LIL closer together cuz the antialiasing blurs the edges - if (antialiasing) - scaleThing *= 1.0 + (1.0 / prevNote.frameHeight); - prevNote.scale.y = scaleThing / prevNote.frameHeight; - prevNote.updateHitbox(); - } - } - } + var scaleThing:Float = Math.round((Conductor.stepCrochet) * (0.45 * FlxMath.roundDecimal(SongLoad.getSpeed(), 2))); + // get them a LIL closer together cuz the antialiasing blurs the edges + if (antialiasing) scaleThing *= 1.0 + (1.0 / prevNote.frameHeight); + prevNote.scale.y = scaleThing / prevNote.frameHeight; + prevNote.updateHitbox(); + } + } + } - override function destroy() - { - prevNote = null; + override function destroy() + { + prevNote = null; - super.destroy(); - } + super.destroy(); + } - public function updateColors():Void - { - colorSwap.update(arrowColors[data.noteData]); - } + public function updateColors():Void + { + colorSwap.update(arrowColors[data.noteData]); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - // mustPress indicates the player is the one pressing the key - if (mustPress) - { - // miss on the NEXT frame so lag doesnt make u miss notes - if (willMiss && !wasGoodHit) - { - tooLate = true; - canBeHit = false; - } - else - { - if (!pastHalfWay && data.strumTime <= Conductor.songPosition) - { - pastHalfWay = true; - noteSpeedMulti *= 2; - } + // mustPress indicates the player is the one pressing the key + if (mustPress) + { + // miss on the NEXT frame so lag doesnt make u miss notes + if (willMiss && !wasGoodHit) + { + tooLate = true; + canBeHit = false; + } + else + { + if (!pastHalfWay && data.strumTime <= Conductor.songPosition) + { + pastHalfWay = true; + noteSpeedMulti *= 2; + } - if (data.strumTime > Conductor.songPosition - HIT_WINDOW) - { - // * 0.5 if sustain note, so u have to keep holding it closer to all the way thru! - if (data.strumTime < Conductor.songPosition + (HIT_WINDOW * (isSustainNote ? 0.5 : 1))) - canBeHit = true; - } - else - { - canBeHit = true; - willMiss = true; - } - } - } - else - { - canBeHit = false; + if (data.strumTime > Conductor.songPosition - HIT_WINDOW) + { + // * 0.5 if sustain note, so u have to keep holding it closer to all the way thru! + if (data.strumTime < Conductor.songPosition + (HIT_WINDOW * (isSustainNote ? 0.5 : 1))) canBeHit = true; + } + else + { + canBeHit = true; + willMiss = true; + } + } + } + else + { + canBeHit = false; - if (data.strumTime <= Conductor.songPosition) - wasGoodHit = true; - } + if (data.strumTime <= Conductor.songPosition) wasGoodHit = true; + } - if (tooLate) - { - if (alpha > 0.3) - alpha = 0.3; - } - } + if (tooLate) + { + if (alpha > 0.3) alpha = 0.3; + } + } - static public function fromData(data:NoteData, prevNote:Note, isSustainNote = false) - { - var result = new Note(data.strumTime, data.noteData, prevNote, isSustainNote); - result.data = data; - return result; - } + static public function fromData(data:NoteData, prevNote:Note, isSustainNote = false) + { + var result = new Note(data.strumTime, data.noteData, prevNote, isSustainNote); + result.data = data; + return result; + } } diff --git a/source/funkin/NoteSplash.hx b/source/funkin/NoteSplash.hx index 3e4d3a3b5..ea4242679 100644 --- a/source/funkin/NoteSplash.hx +++ b/source/funkin/NoteSplash.hx @@ -5,41 +5,41 @@ import haxe.io.Path; class NoteSplash extends FlxSprite { - public function new(x:Float, y:Float, noteData:Int = 0):Void - { - super(x, y); + public function new(x:Float, y:Float, noteData:Int = 0):Void + { + super(x, y); - frames = Paths.getSparrowAtlas('noteSplashes'); + frames = Paths.getSparrowAtlas('noteSplashes'); - animation.addByPrefix('note1-0', 'note impact 1 blue', 24, false); - animation.addByPrefix('note2-0', 'note impact 1 green', 24, false); - animation.addByPrefix('note0-0', 'note impact 1 purple', 24, false); - animation.addByPrefix('note3-0', 'note impact 1 red', 24, false); - animation.addByPrefix('note1-1', 'note impact 2 blue', 24, false); - animation.addByPrefix('note2-1', 'note impact 2 green', 24, false); - animation.addByPrefix('note0-1', 'note impact 2 purple', 24, false); - animation.addByPrefix('note3-1', 'note impact 2 red', 24, false); + animation.addByPrefix('note1-0', 'note impact 1 blue', 24, false); + animation.addByPrefix('note2-0', 'note impact 1 green', 24, false); + animation.addByPrefix('note0-0', 'note impact 1 purple', 24, false); + animation.addByPrefix('note3-0', 'note impact 1 red', 24, false); + animation.addByPrefix('note1-1', 'note impact 2 blue', 24, false); + animation.addByPrefix('note2-1', 'note impact 2 green', 24, false); + animation.addByPrefix('note0-1', 'note impact 2 purple', 24, false); + animation.addByPrefix('note3-1', 'note impact 2 red', 24, false); - setupNoteSplash(x, y, noteData); + setupNoteSplash(x, y, noteData); - antialiasing = true; + antialiasing = true; - // alpha = 0.75; - } + // alpha = 0.75; + } - public function setupNoteSplash(x:Float, y:Float, noteData:Int = 0) - { - setPosition(x, y); - alpha = 0.6; + public function setupNoteSplash(x:Float, y:Float, noteData:Int = 0) + { + setPosition(x, y); + alpha = 0.6; - animation.play('note' + noteData + '-' + FlxG.random.int(0, 1), true); - animation.curAnim.frameRate = 24 + FlxG.random.int(-2, 2); - animation.finishCallback = function(name) - { - kill(); - }; - updateHitbox(); + animation.play('note' + noteData + '-' + FlxG.random.int(0, 1), true); + animation.curAnim.frameRate = 24 + FlxG.random.int(-2, 2); + animation.finishCallback = function(name) + { + kill(); + }; + updateHitbox(); - offset.set(width * 0.3, height * 0.3); - } + offset.set(width * 0.3, height * 0.3); + } } diff --git a/source/funkin/Options.hx b/source/funkin/Options.hx index 7edaa25af..bc8a98570 100644 --- a/source/funkin/Options.hx +++ b/source/funkin/Options.hx @@ -2,5 +2,5 @@ package funkin; class Options { - public static var masterVolume:Float = 1; + public static var masterVolume:Float = 1; } diff --git a/source/funkin/OutdatedSubState.hx b/source/funkin/OutdatedSubState.hx index 32792032e..7684e5ae4 100644 --- a/source/funkin/OutdatedSubState.hx +++ b/source/funkin/OutdatedSubState.hx @@ -9,38 +9,38 @@ import lime.app.Application; #if newgrounds class OutdatedSubState extends MusicBeatState { - public static var leftState:Bool = false; + public static var leftState:Bool = false; - override function create() - { - super.create(); - var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - add(bg); - var ver = "v" + Application.current.meta.get('version'); - var txt:FlxText = new FlxText(0, 0, FlxG.width, - "HEY! You're running an outdated version of the game!\nCurrent version is " - + ver - + " while the most recent version is " - + NGio.GAME_VER - + "! Press Space to go to itch.io, or ESCAPE to ignore this!!", - 32); - txt.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER); - txt.screenCenter(); - add(txt); - } + override function create() + { + super.create(); + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + add(bg); + var ver = "v" + Application.current.meta.get('version'); + var txt:FlxText = new FlxText(0, 0, FlxG.width, + "HEY! You're running an outdated version of the game!\nCurrent version is " + + ver + + " while the most recent version is " + + NGio.GAME_VER + + "! Press Space to go to itch.io, or ESCAPE to ignore this!!", + 32); + txt.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, CENTER); + txt.screenCenter(); + add(txt); + } - override function update(elapsed:Float) - { - if (controls.ACCEPT) - { - FlxG.openURL("https://ninja-muffin24.itch.io/funkin"); - } - if (controls.BACK) - { - leftState = true; - FlxG.switchState(new MainMenuState()); - } - super.update(elapsed); - } + override function update(elapsed:Float) + { + if (controls.ACCEPT) + { + FlxG.openURL("https://ninja-muffin24.itch.io/funkin"); + } + if (controls.BACK) + { + leftState = true; + FlxG.switchState(new MainMenuState()); + } + super.update(elapsed); + } } #end diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx index e75a46826..f961a049f 100644 --- a/source/funkin/Paths.hx +++ b/source/funkin/Paths.hx @@ -6,129 +6,125 @@ import openfl.utils.Assets as OpenFlAssets; class Paths { - inline public static var SOUND_EXT = #if web "mp3" #else "ogg" #end; + inline public static var SOUND_EXT = #if web "mp3" #else "ogg" #end; - static var currentLevel:String; + static var currentLevel:String; - static public function setCurrentLevel(name:String) - { - currentLevel = name.toLowerCase(); - } + static public function setCurrentLevel(name:String) + { + currentLevel = name.toLowerCase(); + } - static function getPath(file:String, type:AssetType, library:Null) - { - if (library != null) - return getLibraryPath(file, library); + static function getPath(file:String, type:AssetType, library:Null) + { + if (library != null) return getLibraryPath(file, library); - if (currentLevel != null) - { - var levelPath = getLibraryPathForce(file, currentLevel); - if (OpenFlAssets.exists(levelPath, type)) - return levelPath; - } + if (currentLevel != null) + { + var levelPath = getLibraryPathForce(file, currentLevel); + if (OpenFlAssets.exists(levelPath, type)) return levelPath; + } - var levelPath = getLibraryPathForce(file, "shared"); - if (OpenFlAssets.exists(levelPath, type)) - return levelPath; + var levelPath = getLibraryPathForce(file, "shared"); + if (OpenFlAssets.exists(levelPath, type)) return levelPath; - return getPreloadPath(file); - } + return getPreloadPath(file); + } - static public function getLibraryPath(file:String, library = "preload") - { - return if (library == "preload" || library == "default") getPreloadPath(file); else getLibraryPathForce(file, library); - } + static public function getLibraryPath(file:String, library = "preload") + { + return if (library == "preload" || library == "default") getPreloadPath(file); else getLibraryPathForce(file, library); + } - inline static function getLibraryPathForce(file:String, library:String) - { - return '$library:assets/$library/$file'; - } + inline static function getLibraryPathForce(file:String, library:String) + { + return '$library:assets/$library/$file'; + } - inline static function getPreloadPath(file:String) - { - return 'assets/$file'; - } + inline static function getPreloadPath(file:String) + { + return 'assets/$file'; + } - inline static public function file(file:String, type:AssetType = TEXT, ?library:String) - { - return getPath(file, type, library); - } + inline static public function file(file:String, type:AssetType = TEXT, ?library:String) + { + return getPath(file, type, library); + } - inline static public function txt(key:String, ?library:String) - { - return getPath('data/$key.txt', TEXT, library); - } + inline static public function txt(key:String, ?library:String) + { + return getPath('data/$key.txt', TEXT, library); + } - inline static public function frag(key:String, ?library:String) - { - return getPath('shaders/$key.frag', TEXT, library); - } + inline static public function frag(key:String, ?library:String) + { + return getPath('shaders/$key.frag', TEXT, library); + } - inline static public function vert(key:String, ?library:String) - { - return getPath('shaders/$key.vert', TEXT, library); - } + inline static public function vert(key:String, ?library:String) + { + return getPath('shaders/$key.vert', TEXT, library); + } - inline static public function xml(key:String, ?library:String) - { - return getPath('data/$key.xml', TEXT, library); - } + inline static public function xml(key:String, ?library:String) + { + return getPath('data/$key.xml', TEXT, library); + } - inline static public function json(key:String, ?library:String) - { - return getPath('data/$key.json', TEXT, library); - } + inline static public function json(key:String, ?library:String) + { + return getPath('data/$key.json', TEXT, library); + } - static public function sound(key:String, ?library:String) - { - return getPath('sounds/$key.$SOUND_EXT', SOUND, library); - } + static public function sound(key:String, ?library:String) + { + return getPath('sounds/$key.$SOUND_EXT', SOUND, library); + } - inline static public function soundRandom(key:String, min:Int, max:Int, ?library:String) - { - return sound(key + FlxG.random.int(min, max), library); - } + inline static public function soundRandom(key:String, min:Int, max:Int, ?library:String) + { + return sound(key + FlxG.random.int(min, max), library); + } - inline static public function music(key:String, ?library:String) - { - return getPath('music/$key.$SOUND_EXT', MUSIC, library); - } + inline static public function music(key:String, ?library:String) + { + return getPath('music/$key.$SOUND_EXT', MUSIC, library); + } - inline static public function voices(song:String, ?suffix:String) - { - if (suffix == null) - suffix = ""; // no suffix, for a sorta backwards compatibility with older-ish voice files + inline static public function voices(song:String, ?suffix:String) + { + if (suffix == null) suffix = ""; // no suffix, for a sorta backwards compatibility with older-ish voice files - return 'songs:assets/songs/${song.toLowerCase()}/Voices$suffix.$SOUND_EXT'; - } + return 'songs:assets/songs/${song.toLowerCase()}/Voices$suffix.$SOUND_EXT'; + } - inline static public function inst(song:String) - { - return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT'; - } + inline static public function inst(song:String) + { + return 'songs:assets/songs/${song.toLowerCase()}/Inst.$SOUND_EXT'; + } - inline static public function image(key:String, ?library:String) - { - return getPath('images/$key.png', IMAGE, library); - } + inline static public function image(key:String, ?library:String) + { + return getPath('images/$key.png', IMAGE, library); + } - inline static public function font(key:String) - { - return 'assets/fonts/$key'; - } + inline static public function font(key:String) + { + return 'assets/fonts/$key'; + } - inline static public function ui(key:String, ?library:String) - { - return xml('ui/$key', library); - } + inline static public function ui(key:String, ?library:String) + { + return xml('ui/$key', library); + } - static public function getSparrowAtlas(key:String, ?library:String) - { - return FlxAtlasFrames.fromSparrow(image(key, library), file('images/$key.xml', library)); - } + static public function getSparrowAtlas(key:String, ?library:String) + { + return FlxAtlasFrames.fromSparrow(image(key, library), file('images/$key.xml', library)); + } - inline static public function getPackerAtlas(key:String, ?library:String) - { - return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library)); - } + inline static public function getPackerAtlas(key:String, ?library:String) + { + return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library)); + } } diff --git a/source/funkin/PauseSubState.hx b/source/funkin/PauseSubState.hx index 42e33624d..ffba8f0c2 100644 --- a/source/funkin/PauseSubState.hx +++ b/source/funkin/PauseSubState.hx @@ -13,273 +13,269 @@ import funkin.play.song.SongData.SongDataParser; class PauseSubState extends MusicBeatSubstate { - var grpMenuShit:FlxTypedGroup; + var grpMenuShit:FlxTypedGroup; - var pauseOG:Array = [ - 'Resume', - 'Restart Song', - 'Change Difficulty', - 'Toggle Practice Mode', - 'Exit to menu' - ]; - var difficultyChoices:Array = ['EASY', 'NORMAL', 'HARD', 'BACK']; + var pauseOG:Array = [ + 'Resume', + 'Restart Song', + 'Change Difficulty', + 'Toggle Practice Mode', + 'Exit to menu' + ]; + var difficultyChoices:Array = ['EASY', 'NORMAL', 'HARD', 'BACK']; - var menuItems:Array = []; - var curSelected:Int = 0; + var menuItems:Array = []; + var curSelected:Int = 0; - var pauseMusic:FlxSound; + var pauseMusic:FlxSound; - var practiceText:FlxText; + var practiceText:FlxText; - var exitingToMenu:Bool = false; - var bg:FlxSprite; - var metaDataGrp:FlxTypedGroup; + var exitingToMenu:Bool = false; + var bg:FlxSprite; + var metaDataGrp:FlxTypedGroup; - public function new(x:Float, y:Float) - { - super(); + public function new(x:Float, y:Float) + { + super(); - menuItems = pauseOG; + menuItems = pauseOG; - if (PlayState.storyWeek == 6) // consistent with logic that decides asset lib!! - pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast-pixel'), true, true); - else - pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true); - pauseMusic.volume = 0; - pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); + if (PlayState.storyWeek == 6) // consistent with logic that decides asset lib!! + pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast-pixel'), true, true); + else + pauseMusic = new FlxSound().loadEmbedded(Paths.music('breakfast'), true, true); + pauseMusic.volume = 0; + pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); - FlxG.sound.list.add(pauseMusic); + FlxG.sound.list.add(pauseMusic); - bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - bg.alpha = 0; - bg.scrollFactor.set(); - add(bg); + bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + bg.alpha = 0; + bg.scrollFactor.set(); + add(bg); - metaDataGrp = new FlxTypedGroup(); - add(metaDataGrp); + metaDataGrp = new FlxTypedGroup(); + add(metaDataGrp); - var levelInfo:FlxText = new FlxText(20, 15, 0, "", 32); - if (PlayState.instance.currentChart != null) - { - levelInfo.text += '${PlayState.instance.currentChart.songName} - ${PlayState.instance.currentChart.songArtist}'; - } - else - { - levelInfo.text += PlayState.currentSong.song; - } - levelInfo.scrollFactor.set(); - levelInfo.setFormat(Paths.font("vcr.ttf"), 32); - levelInfo.updateHitbox(); - metaDataGrp.add(levelInfo); + var levelInfo:FlxText = new FlxText(20, 15, 0, "", 32); + if (PlayState.instance.currentChart != null) + { + levelInfo.text += '${PlayState.instance.currentChart.songName} - ${PlayState.instance.currentChart.songArtist}'; + } + else + { + levelInfo.text += PlayState.currentSong.song; + } + levelInfo.scrollFactor.set(); + levelInfo.setFormat(Paths.font("vcr.ttf"), 32); + levelInfo.updateHitbox(); + metaDataGrp.add(levelInfo); - var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32); - levelDifficulty.text += CoolUtil.difficultyString(); - levelDifficulty.scrollFactor.set(); - levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32); - levelDifficulty.updateHitbox(); - metaDataGrp.add(levelDifficulty); + var levelDifficulty:FlxText = new FlxText(20, 15 + 32, 0, "", 32); + levelDifficulty.text += CoolUtil.difficultyString(); + levelDifficulty.scrollFactor.set(); + levelDifficulty.setFormat(Paths.font('vcr.ttf'), 32); + levelDifficulty.updateHitbox(); + metaDataGrp.add(levelDifficulty); - var deathCounter:FlxText = new FlxText(20, 15 + 64, 0, "", 32); - deathCounter.text = "Blue balled: " + PlayState.deathCounter; - deathCounter.text += "\n" + Highscore.tallies.totalNotesHit; - deathCounter.text += "\n" + Highscore.tallies.totalNotes; - deathCounter.text += "\n" + Std.string(Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes); - deathCounter.scrollFactor.set(); - deathCounter.setFormat(Paths.font('vcr.ttf'), 32); - deathCounter.updateHitbox(); - metaDataGrp.add(deathCounter); + var deathCounter:FlxText = new FlxText(20, 15 + 64, 0, "", 32); + deathCounter.text = "Blue balled: " + PlayState.deathCounter; + deathCounter.text += "\n" + Highscore.tallies.totalNotesHit; + deathCounter.text += "\n" + Highscore.tallies.totalNotes; + deathCounter.text += "\n" + Std.string(Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes); + deathCounter.scrollFactor.set(); + deathCounter.setFormat(Paths.font('vcr.ttf'), 32); + deathCounter.updateHitbox(); + metaDataGrp.add(deathCounter); - practiceText = new FlxText(20, 15 + 64 + 32, 0, "PRACTICE MODE", 32); - practiceText.scrollFactor.set(); - practiceText.setFormat(Paths.font('vcr.ttf'), 32); - practiceText.updateHitbox(); - practiceText.x = FlxG.width - (practiceText.width + 20); - practiceText.visible = PlayState.isPracticeMode; - metaDataGrp.add(practiceText); + practiceText = new FlxText(20, 15 + 64 + 32, 0, "PRACTICE MODE", 32); + practiceText.scrollFactor.set(); + practiceText.setFormat(Paths.font('vcr.ttf'), 32); + practiceText.updateHitbox(); + practiceText.x = FlxG.width - (practiceText.width + 20); + practiceText.visible = PlayState.isPracticeMode; + metaDataGrp.add(practiceText); - levelDifficulty.alpha = 0; - levelInfo.alpha = 0; - deathCounter.alpha = 0; + levelDifficulty.alpha = 0; + levelInfo.alpha = 0; + deathCounter.alpha = 0; - levelInfo.x = FlxG.width - (levelInfo.width + 20); - levelDifficulty.x = FlxG.width - (levelDifficulty.width + 20); - deathCounter.x = FlxG.width - (deathCounter.width + 20); + levelInfo.x = FlxG.width - (levelInfo.width + 20); + levelDifficulty.x = FlxG.width - (levelDifficulty.width + 20); + deathCounter.x = FlxG.width - (deathCounter.width + 20); - FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartInOut}); - FlxTween.tween(levelInfo, {alpha: 1, y: 20}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.3}); - FlxTween.tween(levelDifficulty, {alpha: 1, y: levelDifficulty.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.5}); - FlxTween.tween(deathCounter, {alpha: 1, y: deathCounter.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.7}); + FlxTween.tween(bg, {alpha: 0.6}, 0.4, {ease: FlxEase.quartInOut}); + FlxTween.tween(levelInfo, {alpha: 1, y: 20}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.3}); + FlxTween.tween(levelDifficulty, {alpha: 1, y: levelDifficulty.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.5}); + FlxTween.tween(deathCounter, {alpha: 1, y: deathCounter.y + 5}, 0.4, {ease: FlxEase.quartInOut, startDelay: 0.7}); - grpMenuShit = new FlxTypedGroup(); - add(grpMenuShit); + grpMenuShit = new FlxTypedGroup(); + add(grpMenuShit); - regenMenu(); + regenMenu(); - // cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; - } + // cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]]; + } - private function regenMenu():Void - { - while (grpMenuShit.members.length > 0) - { - grpMenuShit.remove(grpMenuShit.members[0], true); - } + function regenMenu():Void + { + while (grpMenuShit.members.length > 0) + { + grpMenuShit.remove(grpMenuShit.members[0], true); + } - for (i in 0...menuItems.length) - { - var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); - songText.isMenuItem = true; - songText.targetY = i; - grpMenuShit.add(songText); - } + for (i in 0...menuItems.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpMenuShit.add(songText); + } - curSelected = 0; - changeSelection(); - } + curSelected = 0; + changeSelection(); + } - override function update(elapsed:Float) - { - if (pauseMusic.volume < 0.5) - pauseMusic.volume += 0.01 * elapsed; + override function update(elapsed:Float) + { + if (pauseMusic.volume < 0.5) pauseMusic.volume += 0.01 * elapsed; - super.update(elapsed); + super.update(elapsed); - var upP = controls.UI_UP_P; - var downP = controls.UI_DOWN_P; - var accepted = controls.ACCEPT; + var upP = controls.UI_UP_P; + var downP = controls.UI_DOWN_P; + var accepted = controls.ACCEPT; - #if debug - // to pause the game and get screenshots easy, press H on pause menu! - if (FlxG.keys.justPressed.H) - { - bg.visible = !bg.visible; - grpMenuShit.visible = !grpMenuShit.visible; - metaDataGrp.visible = !metaDataGrp.visible; - } - #end + #if debug + // to pause the game and get screenshots easy, press H on pause menu! + if (FlxG.keys.justPressed.H) + { + bg.visible = !bg.visible; + grpMenuShit.visible = !grpMenuShit.visible; + metaDataGrp.visible = !metaDataGrp.visible; + } + #end - if (!exitingToMenu) - { - if (upP) - { - changeSelection(-1); - } - if (downP) - { - changeSelection(1); - } + if (!exitingToMenu) + { + if (upP) + { + changeSelection(-1); + } + if (downP) + { + changeSelection(1); + } - var androidPause:Bool = false; + var androidPause:Bool = false; - #if android - androidPause = FlxG.android.justPressed.BACK; - #end + #if android + androidPause = FlxG.android.justPressed.BACK; + #end - if (androidPause) - close(); + if (androidPause) close(); - if (accepted) - { - var daSelected:String = menuItems[curSelected]; + if (accepted) + { + var daSelected:String = menuItems[curSelected]; - switch (daSelected) - { - case "Resume": - close(); - case "EASY" | 'NORMAL' | "HARD": - PlayState.currentSong = SongLoad.loadFromJson(PlayState.currentSong.song.toLowerCase(), PlayState.currentSong.song.toLowerCase()); - PlayState.currentSong_NEW = SongDataParser.fetchSong(PlayState.currentSong.song.toLowerCase()); - SongLoad.curDiff = daSelected.toLowerCase(); + switch (daSelected) + { + case "Resume": + close(); + case "EASY" | 'NORMAL' | "HARD": + PlayState.currentSong = SongLoad.loadFromJson(PlayState.currentSong.song.toLowerCase(), PlayState.currentSong.song.toLowerCase()); + PlayState.currentSong_NEW = SongDataParser.fetchSong(PlayState.currentSong.song.toLowerCase()); + SongLoad.curDiff = daSelected.toLowerCase(); - PlayState.storyDifficulty = curSelected; - PlayState.storyDifficulty_NEW = daSelected.toLowerCase(); + PlayState.storyDifficulty = curSelected; + PlayState.storyDifficulty_NEW = daSelected.toLowerCase(); - PlayState.needsReset = true; + PlayState.needsReset = true; - close(); + close(); - case 'Toggle Practice Mode': - PlayState.isPracticeMode = !PlayState.isPracticeMode; - practiceText.visible = PlayState.isPracticeMode; + case 'Toggle Practice Mode': + PlayState.isPracticeMode = !PlayState.isPracticeMode; + practiceText.visible = PlayState.isPracticeMode; - case 'Change Difficulty': - menuItems = difficultyChoices; - regenMenu(); - case 'BACK': - menuItems = pauseOG; - regenMenu(); - case "Restart Song": - PlayState.needsReset = true; + case 'Change Difficulty': + menuItems = difficultyChoices; + regenMenu(); + case 'BACK': + menuItems = pauseOG; + regenMenu(); + case "Restart Song": + PlayState.needsReset = true; - close(); - // FlxG.resetState(); - case "Exit to menu": - exitingToMenu = true; - PlayState.seenCutscene = false; - PlayState.deathCounter = 0; + close(); + // FlxG.resetState(); + case "Exit to menu": + exitingToMenu = true; + PlayState.seenCutscene = false; + PlayState.deathCounter = 0; - for (item in grpMenuShit.members) - { - item.targetY = -3; - item.alpha = 0.6; - } + for (item in grpMenuShit.members) + { + item.targetY = -3; + item.alpha = 0.6; + } - FlxTween.tween(bg, {alpha: 1}, 0.4, { - ease: FlxEase.quartInOut, - onComplete: function(_) - { - FlxTransitionableState.skipNextTransIn = true; - FlxTransitionableState.skipNextTransOut = true; + FlxTween.tween(bg, {alpha: 1}, 0.4, + { + ease: FlxEase.quartInOut, + onComplete: function(_) + { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; - FlxG.cameras.list[1].alpha = 0; // bullshit for the UI camera??? + FlxG.cameras.list[1].alpha = 0; // bullshit for the UI camera??? - if (PlayState.isStoryMode) - FlxG.switchState(new StoryMenuState()); - else - FlxG.switchState(new FreeplayState()); - } - }); - } - } + if (PlayState.isStoryMode) FlxG.switchState(new StoryMenuState()); + else + FlxG.switchState(new FreeplayState()); + } + }); + } + } - if (FlxG.keys.justPressed.J) - { - // for reference later! - // PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); - } - } - } + if (FlxG.keys.justPressed.J) + { + // for reference later! + // PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); + } + } + } - override function destroy() - { - pauseMusic.destroy(); + override function destroy() + { + pauseMusic.destroy(); - super.destroy(); - } + super.destroy(); + } - function changeSelection(change:Int = 0):Void - { - FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + function changeSelection(change:Int = 0):Void + { + FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); - curSelected += change; + curSelected += change; - if (curSelected < 0) - curSelected = menuItems.length - 1; - if (curSelected >= menuItems.length) - curSelected = 0; + if (curSelected < 0) curSelected = menuItems.length - 1; + if (curSelected >= menuItems.length) curSelected = 0; - for (index => item in grpMenuShit.members) - { - item.targetY = index - curSelected; + for (index => item in grpMenuShit.members) + { + item.targetY = index - curSelected; - item.alpha = 0.6; - // item.setGraphicSize(Std.int(item.width * 0.8)); + item.alpha = 0.6; + // item.setGraphicSize(Std.int(item.width * 0.8)); - if (item.targetY == 0) - { - item.alpha = 1; - // item.setGraphicSize(Std.int(item.width)); - } - } - } + if (item.targetY == 0) + { + item.alpha = 1; + // item.setGraphicSize(Std.int(item.width)); + } + } + } } diff --git a/source/funkin/PlayerSettings.hx b/source/funkin/PlayerSettings.hx index ab5d9e689..b9ad87a93 100644 --- a/source/funkin/PlayerSettings.hx +++ b/source/funkin/PlayerSettings.hx @@ -10,240 +10,230 @@ import flixel.util.FlxSignal; // import props.Player; class PlayerSettings { - static public var numPlayers(default, null) = 0; - static public var numAvatars(default, null) = 0; - static public var player1(default, null):PlayerSettings; - static public var player2(default, null):PlayerSettings; + static public var numPlayers(default, null) = 0; + static public var numAvatars(default, null) = 0; + static public var player1(default, null):PlayerSettings; + static public var player2(default, null):PlayerSettings; - static public var onAvatarAdd(default, null) = new FlxTypedSignalVoid>(); - static public var onAvatarRemove(default, null) = new FlxTypedSignalVoid>(); + static public var onAvatarAdd(default, null) = new FlxTypedSignalVoid>(); + static public var onAvatarRemove(default, null) = new FlxTypedSignalVoid>(); - public var id(default, null):Int; + public var id(default, null):Int; - public var controls(default, null):Controls; + public var controls(default, null):Controls; - // public var avatar:Player; - // public var camera(get, never):PlayCamera; + // public var avatar:Player; + // public var camera(get, never):PlayCamera; - function new(id) - { - this.id = id; - this.controls = new Controls('player$id', None); + function new(id) + { + this.id = id; + this.controls = new Controls('player$id', None); - #if CLEAR_INPUT_SAVE - FlxG.save.data.controls = null; - FlxG.save.flush(); - #end + #if CLEAR_INPUT_SAVE + FlxG.save.data.controls = null; + FlxG.save.flush(); + #end - var useDefault = true; - var controlData = FlxG.save.data.controls; - if (controlData != null) - { - var keyData:Dynamic = null; - if (id == 0 && controlData.p1 != null && controlData.p1.keys != null) - keyData = controlData.p1.keys; - else if (id == 1 && controlData.p2 != null && controlData.p2.keys != null) - keyData = controlData.p2.keys; + var useDefault = true; + var controlData = FlxG.save.data.controls; + if (controlData != null) + { + var keyData:Dynamic = null; + if (id == 0 && controlData.p1 != null && controlData.p1.keys != null) keyData = controlData.p1.keys; + else if (id == 1 && controlData.p2 != null && controlData.p2.keys != null) keyData = controlData.p2.keys; - if (keyData != null) - { - useDefault = false; - trace("loaded key data: " + haxe.Json.stringify(keyData)); - controls.fromSaveData(keyData, Keys); - } - } + if (keyData != null) + { + useDefault = false; + trace("loaded key data: " + haxe.Json.stringify(keyData)); + controls.fromSaveData(keyData, Keys); + } + } - if (useDefault) - controls.setKeyboardScheme(Solo); - } + if (useDefault) controls.setKeyboardScheme(Solo); + } - function addGamepad(gamepad:FlxGamepad) - { - var useDefault = true; - var controlData = FlxG.save.data.controls; - if (controlData != null) - { - var padData:Dynamic = null; - if (id == 0 && controlData.p1 != null && controlData.p1.pad != null) - padData = controlData.p1.pad; - else if (id == 1 && controlData.p2 != null && controlData.p2.pad != null) - padData = controlData.p2.pad; + function addGamepad(gamepad:FlxGamepad) + { + var useDefault = true; + var controlData = FlxG.save.data.controls; + if (controlData != null) + { + var padData:Dynamic = null; + if (id == 0 && controlData.p1 != null && controlData.p1.pad != null) padData = controlData.p1.pad; + else if (id == 1 && controlData.p2 != null && controlData.p2.pad != null) padData = controlData.p2.pad; - if (padData != null) - { - useDefault = false; - trace("loaded pad data: " + haxe.Json.stringify(padData)); - controls.addGamepadWithSaveData(gamepad.id, padData); - } - } + if (padData != null) + { + useDefault = false; + trace("loaded pad data: " + haxe.Json.stringify(padData)); + controls.addGamepadWithSaveData(gamepad.id, padData); + } + } - if (useDefault) - controls.addDefaultGamepad(gamepad.id); - } + if (useDefault) controls.addDefaultGamepad(gamepad.id); + } - public function saveControls() - { - if (FlxG.save.data.controls == null) - FlxG.save.data.controls = {}; + public function saveControls() + { + if (FlxG.save.data.controls == null) FlxG.save.data.controls = {}; - var playerData:{?keys:Dynamic, ?pad:Dynamic} - if (id == 0) - { - if (FlxG.save.data.controls.p1 == null) - FlxG.save.data.controls.p1 = {}; - playerData = FlxG.save.data.controls.p1; - } - else - { - if (FlxG.save.data.controls.p2 == null) - FlxG.save.data.controls.p2 = {}; - playerData = FlxG.save.data.controls.p2; - } + var playerData:{?keys:Dynamic, ?pad:Dynamic} + if (id == 0) + { + if (FlxG.save.data.controls.p1 == null) FlxG.save.data.controls.p1 = {}; + playerData = FlxG.save.data.controls.p1; + } + else + { + if (FlxG.save.data.controls.p2 == null) FlxG.save.data.controls.p2 = {}; + playerData = FlxG.save.data.controls.p2; + } - var keyData = controls.createSaveData(Keys); - if (keyData != null) - { - playerData.keys = keyData; - trace("saving key data: " + haxe.Json.stringify(keyData)); - } + var keyData = controls.createSaveData(Keys); + if (keyData != null) + { + playerData.keys = keyData; + trace("saving key data: " + haxe.Json.stringify(keyData)); + } - if (controls.gamepadsAdded.length > 0) - { - var padData = controls.createSaveData(Gamepad(controls.gamepadsAdded[0])); - if (padData != null) - { - trace("saving pad data: " + haxe.Json.stringify(padData)); - playerData.pad = padData; - } - } + if (controls.gamepadsAdded.length > 0) + { + var padData = controls.createSaveData(Gamepad(controls.gamepadsAdded[0])); + if (padData != null) + { + trace("saving pad data: " + haxe.Json.stringify(padData)); + playerData.pad = padData; + } + } - FlxG.save.flush(); - } + FlxG.save.flush(); + } - static public function init():Void - { - if (player1 == null) - { - player1 = new PlayerSettings(0); - ++numPlayers; - } + static public function init():Void + { + if (player1 == null) + { + player1 = new PlayerSettings(0); + ++numPlayers; + } - FlxG.gamepads.deviceConnected.add(onGamepadAdded); + FlxG.gamepads.deviceConnected.add(onGamepadAdded); - var numGamepads = FlxG.gamepads.numActiveGamepads; - for (i in 0...numGamepads) - { - var gamepad = FlxG.gamepads.getByID(i); - if (gamepad != null) - onGamepadAdded(gamepad); - } + var numGamepads = FlxG.gamepads.numActiveGamepads; + for (i in 0...numGamepads) + { + var gamepad = FlxG.gamepads.getByID(i); + if (gamepad != null) onGamepadAdded(gamepad); + } - // player1.controls.addDefaultGamepad(0); - // } + // player1.controls.addDefaultGamepad(0); + // } - // if (numGamepads > 1) - // { - // if (player2 == null) - // { - // player2 = new PlayerSettings(1, None); - // ++numPlayers; - // } + // if (numGamepads > 1) + // { + // if (player2 == null) + // { + // player2 = new PlayerSettings(1, None); + // ++numPlayers; + // } - // var gamepad = FlxG.gamepads.getByID(1); - // if (gamepad == null) - // throw 'Unexpected null gamepad. id:0'; + // var gamepad = FlxG.gamepads.getByID(1); + // if (gamepad == null) + // throw 'Unexpected null gamepad. id:0'; - // player2.controls.addDefaultGamepad(1); - // } + // player2.controls.addDefaultGamepad(1); + // } - // DeviceManager.init(); - } + // DeviceManager.init(); + } - static function onGamepadAdded(gamepad:FlxGamepad) - { - player1.addGamepad(gamepad); - } + static function onGamepadAdded(gamepad:FlxGamepad) + { + player1.addGamepad(gamepad); + } - /* - public function setKeyboardScheme(scheme) - { - controls.setKeyboardScheme(scheme); - } + /* + public function setKeyboardScheme(scheme) + { + controls.setKeyboardScheme(scheme); + } - static public function addAvatar(avatar:Player):PlayerSettings - { - var settings:PlayerSettings; + static public function addAvatar(avatar:Player):PlayerSettings + { + var settings:PlayerSettings; - if (player1 == null) - { - player1 = new PlayerSettings(0, Solo); - ++numPlayers; - } + if (player1 == null) + { + player1 = new PlayerSettings(0, Solo); + ++numPlayers; + } - if (player1.avatar == null) - settings = player1; - else - { - if (player2 == null) - { - if (player1.controls.keyboardScheme.match(Duo(true))) - player2 = new PlayerSettings(1, Duo(false)); - else - player2 = new PlayerSettings(1, None); - ++numPlayers; - } + if (player1.avatar == null) + settings = player1; + else + { + if (player2 == null) + { + if (player1.controls.keyboardScheme.match(Duo(true))) + player2 = new PlayerSettings(1, Duo(false)); + else + player2 = new PlayerSettings(1, None); + ++numPlayers; + } - if (player2.avatar == null) - settings = player2; - else - throw throw 'Invalid number of players: ${numPlayers + 1}'; - } - ++numAvatars; - settings.avatar = avatar; - avatar.settings = settings; + if (player2.avatar == null) + settings = player2; + else + throw throw 'Invalid number of players: ${numPlayers + 1}'; + } + ++numAvatars; + settings.avatar = avatar; + avatar.settings = settings; - splitCameras(); + splitCameras(); - onAvatarAdd.dispatch(settings); + onAvatarAdd.dispatch(settings); - return settings; - } + return settings; + } - static public function removeAvatar(avatar:Player):Void - { - var settings:PlayerSettings; + static public function removeAvatar(avatar:Player):Void + { + var settings:PlayerSettings; - if (player1 != null && player1.avatar == avatar) - settings = player1; - else if (player2 != null && player2.avatar == avatar) - { - settings = player2; - if (player1.controls.keyboardScheme.match(Duo(_))) - player1.setKeyboardScheme(Solo); - } - else - throw "Cannot remove avatar that is not for a player"; + if (player1 != null && player1.avatar == avatar) + settings = player1; + else if (player2 != null && player2.avatar == avatar) + { + settings = player2; + if (player1.controls.keyboardScheme.match(Duo(_))) + player1.setKeyboardScheme(Solo); + } + else + throw "Cannot remove avatar that is not for a player"; - settings.avatar = null; - while (settings.controls.gamepadsAdded.length > 0) - { - final id = settings.controls.gamepadsAdded.shift(); - settings.controls.removeGamepad(id); - DeviceManager.releaseGamepad(FlxG.gamepads.getByID(id)); - } + settings.avatar = null; + while (settings.controls.gamepadsAdded.length > 0) + { + final id = settings.controls.gamepadsAdded.shift(); + settings.controls.removeGamepad(id); + DeviceManager.releaseGamepad(FlxG.gamepads.getByID(id)); + } - --numAvatars; + --numAvatars; - splitCameras(); + splitCameras(); - onAvatarRemove.dispatch(avatar.settings); - } + onAvatarRemove.dispatch(avatar.settings); + } - */ - static public function reset() - { - player1 = null; - player2 = null; - numPlayers = 0; - } + */ + static public function reset() + { + player1 = null; + player2 = null; + numPlayers = 0; + } } diff --git a/source/funkin/Section.hx b/source/funkin/Section.hx index 57fed7d9f..f239baaad 100644 --- a/source/funkin/Section.hx +++ b/source/funkin/Section.hx @@ -4,30 +4,30 @@ import funkin.noteStuff.NoteBasic.NoteData; typedef SwagSection = { - var sectionNotes:Array; - var lengthInSteps:Int; - var typeOfSection:Int; - var mustHitSection:Bool; - var bpm:Float; - var changeBPM:Bool; - var altAnim:Bool; + var sectionNotes:Array; + var lengthInSteps:Int; + var typeOfSection:Int; + var mustHitSection:Bool; + var bpm:Float; + var changeBPM:Bool; + var altAnim:Bool; } class Section { - public var sectionNotes:Array = []; + public var sectionNotes:Array = []; - public var lengthInSteps:Int = 16; - public var typeOfSection:Int = 0; - public var mustHitSection:Bool = true; + public var lengthInSteps:Int = 16; + public var typeOfSection:Int = 0; + public var mustHitSection:Bool = true; - /** - * Copies the first section into the second section! - */ - public static var COPYCAT:Int = 0; + /** + * Copies the first section into the second section! + */ + public static var COPYCAT:Int = 0; - public function new(lengthInSteps:Int = 16) - { - this.lengthInSteps = lengthInSteps; - } + public function new(lengthInSteps:Int = 16) + { + this.lengthInSteps = lengthInSteps; + } } diff --git a/source/funkin/SongLoad.hx b/source/funkin/SongLoad.hx index fc786977f..07c21e22c 100644 --- a/source/funkin/SongLoad.hx +++ b/source/funkin/SongLoad.hx @@ -8,320 +8,313 @@ import lime.utils.Assets; typedef SwagSong = { - var song:String; - var notes:FunnyNotes; - var difficulties:Array; - var noteMap:Map>; - var bpm:Float; - var needsVoices:Bool; - var voiceList:Array; - var speed:FunnySpeed; - var speedMap:Map; + var song:String; + var notes:FunnyNotes; + var difficulties:Array; + var noteMap:Map>; + var bpm:Float; + var needsVoices:Bool; + var voiceList:Array; + var speed:FunnySpeed; + var speedMap:Map; - var player1:String; - var player2:String; - var validScore:Bool; - var extraNotes:Map>; + var player1:String; + var player2:String; + var validScore:Bool; + var extraNotes:Map>; } typedef FunnySpeed = { - var ?easy:Float; - var ?normal:Float; - var ?hard:Float; + var ?easy:Float; + var ?normal:Float; + var ?hard:Float; } typedef FunnyNotes = { - var ?easy:Array; - var ?normal:Array; - var ?hard:Array; + var ?easy:Array; + var ?normal:Array; + var ?hard:Array; } class SongLoad { - public static var curDiff:String = 'normal'; - public static var curNotes:Array; - public static var songData:SwagSong; + public static var curDiff:String = 'normal'; + public static var curNotes:Array; + public static var songData:SwagSong; - public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong - { - var rawJson:String = null; - try - { - rawJson = Assets.getText(Paths.json('songs/${folder.toLowerCase()}/${jsonInput.toLowerCase()}')).trim(); - } - catch (e) - { - trace('Failed to load song data: ${e}'); - rawJson = null; - } + public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong + { + var rawJson:String = null; + try + { + rawJson = Assets.getText(Paths.json('songs/${folder.toLowerCase()}/${jsonInput.toLowerCase()}')).trim(); + } + catch (e) + { + trace('Failed to load song data: ${e}'); + rawJson = null; + } - if (rawJson == null) - { - return null; - } + if (rawJson == null) + { + return null; + } - while (!rawJson.endsWith("}")) - { - rawJson = rawJson.substr(0, rawJson.length - 1); - } + while (!rawJson.endsWith("}")) + { + rawJson = rawJson.substr(0, rawJson.length - 1); + } - return parseJSONshit(rawJson); - } + return parseJSONshit(rawJson); + } - public static function getSong(?diff:String):Array - { - if (diff == null) - diff = SongLoad.curDiff; + public static function getSong(?diff:String):Array + { + if (diff == null) diff = SongLoad.curDiff; - var songShit:Array = []; + var songShit:Array = []; - // THIS IS OVERWRITTEN, WILL BE DEPRECTATED AND REPLACED SOOOOON - if (songData != null) - { - switch (diff) - { - case 'easy': - songShit = songData.notes.easy; - case 'normal': - songShit = songData.notes.normal; - case 'hard': - songShit = songData.notes.hard; - } - } + // THIS IS OVERWRITTEN, WILL BE DEPRECTATED AND REPLACED SOOOOON + if (songData != null) + { + switch (diff) + { + case 'easy': + songShit = songData.notes.easy; + case 'normal': + songShit = songData.notes.normal; + case 'hard': + songShit = songData.notes.hard; + } + } - checkAndCreateNotemap(curDiff); + checkAndCreateNotemap(curDiff); - songShit = songData.noteMap[diff]; + songShit = songData.noteMap[diff]; - return songShit; - } + return songShit; + } - public static function checkAndCreateNotemap(diff:String):Void - { - if (songData == null || songData.noteMap == null) - return; - if (songData.noteMap[diff] == null) - songData.noteMap[diff] = []; - } + public static function checkAndCreateNotemap(diff:String):Void + { + if (songData == null || songData.noteMap == null) return; + if (songData.noteMap[diff] == null) songData.noteMap[diff] = []; + } - public static function getSpeed(?diff:String):Float - { - if (PlayState.instance != null && PlayState.instance.currentChart != null) - { - return getSpeed_NEW(diff); - } + public static function getSpeed(?diff:String):Float + { + if (PlayState.instance != null && PlayState.instance.currentChart != null) + { + return getSpeed_NEW(diff); + } - if (diff == null) - diff = SongLoad.curDiff; + if (diff == null) diff = SongLoad.curDiff; - var speedShit:Float = 1; + var speedShit:Float = 1; - // all this shit is overridden by the thing that loads it from speedMap Map object!!! - // replace and delete later! - switch (diff) - { - case 'easy': - speedShit = songData.speed.easy; - case 'normal': - speedShit = songData.speed.normal; - case 'hard': - speedShit = songData.speed.hard; - } + // all this shit is overridden by the thing that loads it from speedMap Map object!!! + // replace and delete later! + switch (diff) + { + case 'easy': + speedShit = songData.speed.easy; + case 'normal': + speedShit = songData.speed.normal; + case 'hard': + speedShit = songData.speed.hard; + } - if (songData.speedMap[diff] == null) - songData.speedMap[diff] = 1; + if (songData.speedMap[diff] == null) songData.speedMap[diff] = 1; - speedShit = songData.speedMap[diff]; + speedShit = songData.speedMap[diff]; - return speedShit; - } + return speedShit; + } - public static function getSpeed_NEW(?diff:String):Float - { - if (PlayState.instance == null || PlayState.instance.currentChart == null || PlayState.instance.currentChart.scrollSpeed == 0.0) - return 1.0; + public static function getSpeed_NEW(?diff:String):Float + { + if (PlayState.instance == null + || PlayState.instance.currentChart == null + || PlayState.instance.currentChart.scrollSpeed == 0.0) return 1.0; - return PlayState.instance.currentChart.scrollSpeed; - } + return PlayState.instance.currentChart.scrollSpeed; + } - public static function getDefaultSwagSong():SwagSong - { - return { - song: 'Test', - notes: {easy: [], normal: [], hard: []}, - difficulties: ["easy", "normal", "hard"], - noteMap: new Map(), - speedMap: new Map(), - bpm: 150, - needsVoices: true, - player1: 'bf', - player2: 'dad', - speed: { - easy: 1, - normal: 1, - hard: 1 - }, - validScore: false, - voiceList: ["BF", "BF-pixel"], - extraNotes: [] - }; - } + public static function getDefaultSwagSong():SwagSong + { + return { + song: 'Test', + notes: {easy: [], normal: [], hard: []}, + difficulties: ["easy", "normal", "hard"], + noteMap: new Map(), + speedMap: new Map(), + bpm: 150, + needsVoices: true, + player1: 'bf', + player2: 'dad', + speed: + { + easy: 1, + normal: 1, + hard: 1 + }, + validScore: false, + voiceList: ["BF", "BF-pixel"], + extraNotes: [] + }; + } - public static function getDefaultNoteData():NoteData - { - return new NoteData(); - } + public static function getDefaultNoteData():NoteData + { + return new NoteData(); + } - /** - * Casts the an array to NOTE data (for LOADING shit from json usually) - */ - public static function castArrayToNoteData(noteStuff:Array) - { - if (noteStuff == null) - return; + /** + * Casts the an array to NOTE data (for LOADING shit from json usually) + */ + public static function castArrayToNoteData(noteStuff:Array) + { + if (noteStuff == null) return; - for (sectionIndex => section in noteStuff) - { - if (section == null || section.sectionNotes == null) - continue; - for (noteIndex => noteDataArray in section.sectionNotes) - { - var arrayDipshit:Array = cast noteDataArray; // crackhead + for (sectionIndex => section in noteStuff) + { + if (section == null || section.sectionNotes == null) continue; + for (noteIndex => noteDataArray in section.sectionNotes) + { + var arrayDipshit:Array = cast noteDataArray; // crackhead - if (arrayDipshit != null) // array isnt null, that means it loaded it as an array and needs to be manually parsed? - { - // at this point noteStuff[sectionIndex].sectionNotes[noteIndex] is an array because of the cast from the first line in this function - // so this line right here turns it back into the NoteData typedef type because of another bastard cast - noteStuff[sectionIndex].sectionNotes[noteIndex] = cast SongLoad.getDefaultNoteData(); // turn it from an array (because of the cast), back to noteData? yeah that works + if (arrayDipshit != null) // array isnt null, that means it loaded it as an array and needs to be manually parsed? + { + // at this point noteStuff[sectionIndex].sectionNotes[noteIndex] is an array because of the cast from the first line in this function + // so this line right here turns it back into the NoteData typedef type because of another bastard cast + noteStuff[sectionIndex].sectionNotes[noteIndex] = cast SongLoad.getDefaultNoteData(); // turn it from an array (because of the cast), back to noteData? yeah that works - noteStuff[sectionIndex].sectionNotes[noteIndex].strumTime = arrayDipshit[0]; - noteStuff[sectionIndex].sectionNotes[noteIndex].noteData = arrayDipshit[1]; - noteStuff[sectionIndex].sectionNotes[noteIndex].sustainLength = arrayDipshit[2]; - if (arrayDipshit.length > 3) - { - noteStuff[sectionIndex].sectionNotes[noteIndex].noteKind = arrayDipshit[3]; - } - } - else if (noteDataArray != null) - { - // array is NULL, so it checks if noteDataArray (doesnt exactly NEED to be an 'array' is also null or not.) - // At this point it should be an OBJECT that can be easily casted!!! + noteStuff[sectionIndex].sectionNotes[noteIndex].strumTime = arrayDipshit[0]; + noteStuff[sectionIndex].sectionNotes[noteIndex].noteData = arrayDipshit[1]; + noteStuff[sectionIndex].sectionNotes[noteIndex].sustainLength = arrayDipshit[2]; + if (arrayDipshit.length > 3) + { + noteStuff[sectionIndex].sectionNotes[noteIndex].noteKind = arrayDipshit[3]; + } + } + else if (noteDataArray != null) + { + // array is NULL, so it checks if noteDataArray (doesnt exactly NEED to be an 'array' is also null or not.) + // At this point it should be an OBJECT that can be easily casted!!! - noteStuff[sectionIndex].sectionNotes[noteIndex] = cast noteDataArray; - } - else - throw "shit brokey"; // i actually dont know how throw works lol - } - } - } + noteStuff[sectionIndex].sectionNotes[noteIndex] = cast noteDataArray; + } + else + throw "shit brokey"; // i actually dont know how throw works lol + } + } + } - /** - * Cast notedata to ARRAY (usually used for level SAVING) - */ - public static function castNoteDataToArray(noteStuff:Array) - { - if (noteStuff == null) - return; + /** + * Cast notedata to ARRAY (usually used for level SAVING) + */ + public static function castNoteDataToArray(noteStuff:Array) + { + if (noteStuff == null) return; - for (sectionIndex => section in noteStuff) - { - for (noteIndex => noteTypeDefShit in section.sectionNotes) - { - var dipshitArray:Array = [ - noteTypeDefShit.strumTime, - noteTypeDefShit.noteData, - noteTypeDefShit.sustainLength, - noteTypeDefShit.noteKind - ]; + for (sectionIndex => section in noteStuff) + { + for (noteIndex => noteTypeDefShit in section.sectionNotes) + { + var dipshitArray:Array = [ + noteTypeDefShit.strumTime, + noteTypeDefShit.noteData, + noteTypeDefShit.sustainLength, + noteTypeDefShit.noteKind + ]; - noteStuff[sectionIndex].sectionNotes[noteIndex] = cast dipshitArray; - } - } - } + noteStuff[sectionIndex].sectionNotes[noteIndex] = cast dipshitArray; + } + } + } - public static function castNoteDataToNoteData(noteStuff:Array) - { - if (noteStuff == null) - return; + public static function castNoteDataToNoteData(noteStuff:Array) + { + if (noteStuff == null) return; - for (sectionIndex => section in noteStuff) - { - for (noteIndex => noteTypedefShit in section.sectionNotes) - { - trace(noteTypedefShit); - noteStuff[sectionIndex].sectionNotes[noteIndex] = noteTypedefShit; - } - } - } + for (sectionIndex => section in noteStuff) + { + for (noteIndex => noteTypedefShit in section.sectionNotes) + { + trace(noteTypedefShit); + noteStuff[sectionIndex].sectionNotes[noteIndex] = noteTypedefShit; + } + } + } - public static function parseJSONshit(rawJson:String):SwagSong - { - var songParsed:Dynamic; - try - { - songParsed = Json.parse(rawJson); - } - catch (e) - { - FlxG.log.warn("Error parsing JSON: " + e.message); - trace("Error parsing JSON: " + e.message); - return null; - } + public static function parseJSONshit(rawJson:String):SwagSong + { + var songParsed:Dynamic; + try + { + songParsed = Json.parse(rawJson); + } + catch (e) + { + FlxG.log.warn("Error parsing JSON: " + e.message); + trace("Error parsing JSON: " + e.message); + return null; + } - var swagShit:SwagSong = cast songParsed.song; - swagShit.difficulties = []; // reset it to default before load - swagShit.noteMap = new Map(); - swagShit.speedMap = new Map(); - for (diff in Reflect.fields(songParsed.song.notes)) - { - swagShit.difficulties.push(diff); - swagShit.noteMap[diff] = cast Reflect.field(songParsed.song.notes, diff); + var swagShit:SwagSong = cast songParsed.song; + swagShit.difficulties = []; // reset it to default before load + swagShit.noteMap = new Map(); + swagShit.speedMap = new Map(); + for (diff in Reflect.fields(songParsed.song.notes)) + { + swagShit.difficulties.push(diff); + swagShit.noteMap[diff] = cast Reflect.field(songParsed.song.notes, diff); - castArrayToNoteData(swagShit.noteMap[diff]); + castArrayToNoteData(swagShit.noteMap[diff]); - // castNoteDataToNoteData(swagShit.noteMap[diff]); + // castNoteDataToNoteData(swagShit.noteMap[diff]); - /* - switch (diff) - { - case "easy": - castArrayToNoteData(swagShit.notes.hard); + /* + switch (diff) + { + case "easy": + castArrayToNoteData(swagShit.notes.hard); - case "normal": - castArrayToNoteData(swagShit.notes.normal); - case "hard": - castArrayToNoteData(swagShit.notes.hard); - } - */ - } + case "normal": + castArrayToNoteData(swagShit.notes.normal); + case "hard": + castArrayToNoteData(swagShit.notes.hard); + } + */ + } - for (diff in swagShit.difficulties) - { - swagShit.speedMap[diff] = cast Reflect.field(songParsed.song.speed, diff); - } + for (diff in swagShit.difficulties) + { + swagShit.speedMap[diff] = cast Reflect.field(songParsed.song.speed, diff); + } - // trace(swagShit.noteMap.toString()); - // trace(swagShit.speedMap.toString()); - // trace('that was just notemap string lol'); + // trace(swagShit.noteMap.toString()); + // trace(swagShit.speedMap.toString()); + // trace('that was just notemap string lol'); - swagShit.validScore = true; + swagShit.validScore = true; - trace("SONG SHIT ABOUTTA WEEK AGOOO"); - for (field in Reflect.fields(Json.parse(rawJson).song.speed)) - { - // swagShit.speed[field] = Reflect.field(Json.parse(rawJson).song.speed, field); - // swagShit.notes[field] = Reflect.field(Json.parse(rawJson).song.notes, field); - // trace(swagShit.notes[field]); - } + trace("SONG SHIT ABOUTTA WEEK AGOOO"); + for (field in Reflect.fields(Json.parse(rawJson).song.speed)) + { + // swagShit.speed[field] = Reflect.field(Json.parse(rawJson).song.speed, field); + // swagShit.notes[field] = Reflect.field(Json.parse(rawJson).song.notes, field); + // trace(swagShit.notes[field]); + } - // swagShit.notes = cast Json.parse(rawJson).song.notes[SongLoad.curDiff]; // by default uses + // swagShit.notes = cast Json.parse(rawJson).song.notes[SongLoad.curDiff]; // by default uses - trace('THAT SHIT WAS JUST THE NORMAL NOTES!!!'); - songData = swagShit; - // curNotes = songData.notes.get('normal'); + trace('THAT SHIT WAS JUST THE NORMAL NOTES!!!'); + songData = swagShit; + // curNotes = songData.notes.get('normal'); - return swagShit; - } + return swagShit; + } } diff --git a/source/funkin/StoryMenuState.hx b/source/funkin/StoryMenuState.hx index 439501ce8..7e2be322d 100644 --- a/source/funkin/StoryMenuState.hx +++ b/source/funkin/StoryMenuState.hx @@ -21,468 +21,455 @@ import Discord.DiscordClient; class StoryMenuState extends MusicBeatState { - var scoreText:FlxText; - - var weekData:Array> = [ - ['Tutorial'], - ['Bopeebo', 'Fresh', 'Dadbattle'], - ['Spookeez', 'South', "Monster"], - ['Pico', 'Philly', "Blammed"], - ['Satin-Panties', "High", "Milf"], - ['Cocoa', 'Eggnog', 'Winter-Horrorland'], - ['Senpai', 'Roses', 'Thorns'], - ['Ugh', 'Guns', 'Stress'], - ['Darnell', "lit-up", "2hot", "blazin"] - ]; - var curDifficulty:Int = 1; - - // TODO: This info is just hardcoded right now. - // We should probably make it so that weeks must be completed in order to unlock the next week. - public static var weekUnlocked:Array = [true, true, true, true, true, true, true, true, true]; - - var weekCharacters:Array = [ - ['dad', 'bf', 'gf'], - ['dad', 'bf', 'gf'], - ['spooky', 'bf', 'gf'], - ['pico', 'bf', 'gf'], - ['mom', 'bf', 'gf'], - ['parents-christmas', 'bf', 'gf'], - ['senpai', 'bf', 'gf'], - ['tankman', 'bf', 'gf'], - ['darnell', 'pico', 'nene'] - ]; - - var weekNames:Array = [ - "", - "Daddy Dearest", - "Spooky Month", - "PICO", - "MOMMY MUST MURDER", - "RED SNOW", - "hating simulator ft. moawling", - "TANKMAN", - "Due Debts" - ]; - - var weekType:Array = [WEEK, WEEK, WEEK, WEEK, WEEK, WEEK, WEEK, WEEK, WEEKEND]; - var weekTypeInc:Map = new Map(); - - var txtWeekTitle:FlxText; - - var curWeek:Int = 0; - - var txtTracklist:FlxText; - - var grpWeekText:FlxTypedGroup; - var grpWeekCharacters:Array>; - - // var grpWeekCharacters:FlxTypedGroup; - var grpLocks:FlxTypedGroup; - - var difficultySelectors:FlxGroup; - var sprDifficulty:FlxSprite; - var leftArrow:FlxSprite; - var rightArrow:FlxSprite; - var yellowBG:FlxSprite; // not actually, yellow, lol! - var targetColor:Int = 0xFFF9CF51; - - override function create() - { - transIn = FlxTransitionableState.defaultTransIn; - transOut = FlxTransitionableState.defaultTransOut; - - if (FlxG.sound.music != null) - { - if (!FlxG.sound.music.playing) - FlxG.sound.playMusic(Paths.music('freakyMenu')); - } - - persistentUpdate = persistentDraw = true; - - scoreText = new FlxText(10, 10, 0, "SCORE: 49324858", 36); - scoreText.setFormat("VCR OSD Mono", 32); - - txtWeekTitle = new FlxText(FlxG.width * 0.7, 10, 0, "", 32); - txtWeekTitle.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, RIGHT); - txtWeekTitle.alpha = 0.7; - - var rankText:FlxText = new FlxText(0, 10); - rankText.text = 'RANK: GREAT'; - rankText.setFormat(Paths.font("vcr.ttf"), 32); - rankText.size = scoreText.size; - rankText.screenCenter(X); - - var ui_tex = Paths.getSparrowAtlas('campaign_menu_UI_assets'); - yellowBG = new FlxSprite(0, 56).makeGraphic(FlxG.width, 400, FlxColor.WHITE); - yellowBG.color = 0xFFF9CF51; - // 0xFF413CAE blue - // 0xFFF9CF51 yello - - grpWeekText = new FlxTypedGroup(); - add(grpWeekText); - - var blackBarThingie:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, 56, FlxColor.BLACK); - add(blackBarThingie); - - // grpWeekCharacters = new FlxTypedGroup(); - grpWeekCharacters = []; - - grpLocks = new FlxTypedGroup(); - add(grpLocks); - - #if discord_rpc - // Updating Discord Rich Presence - DiscordClient.changePresence("In the Menus", null); - #end - - for (i in 0...weekData.length) - { - if (!weekTypeInc.exists(weekType[i])) - weekTypeInc[weekType[i]] = 1; - - if (i == 0 && weekType[i] == WEEK) - weekTypeInc[weekType[i]] = 0; // set week to 0 by default? - - var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, weekTypeInc[weekType[i]], weekType[i]); - weekThing.y += ((weekThing.height + 20) * i); - weekThing.targetY = i; - grpWeekText.add(weekThing); - - weekTypeInc[weekType[i]] += 1; - - weekThing.screenCenter(X); - weekThing.antialiasing = true; - // weekThing.updateHitbox(); - - // Needs an offset thingie - if (!weekUnlocked[i]) - { - var lock:FlxSprite = new FlxSprite(weekThing.width + 10 + weekThing.x); - lock.frames = ui_tex; - lock.animation.addByPrefix('lock', 'lock'); - lock.animation.play('lock'); - lock.ID = i; - lock.antialiasing = true; - grpLocks.add(lock); - } - } - - var sizeChart:Map> = new Map(); - - var sizeTxt:Array = Assets.getText(Paths.file("data/storychardata.txt")).split("\n"); - - for (item in sizeTxt) - { - var items:Array = item.split(" "); - - var stuf:Array = []; - var name:String = items.shift(); - - for (num in items) - stuf.push(Std.parseFloat(num)); - - sizeChart.set(name, stuf); - } - - for (index => week in weekCharacters) - { - grpWeekCharacters.push(new FlxTypedGroup()); - - for (char in 0...week.length) - { - var weekCharacterThing:MenuCharacter = new MenuCharacter((FlxG.width * 0.25) * (1 + char) - 150, weekCharacters[index][char]); - weekCharacterThing.y += 70; - weekCharacterThing.antialiasing = true; - - var size:Float = 0.9; - - switch (char) - { - case 0 | 2: - size = 0.5; - if (char == 0 && weekCharacterThing.character == "pico") - weekCharacterThing.flipX = true; - case 1: - size = 0.9; - weekCharacterThing.x -= 80; - } - - if (sizeChart.exists(weekCharacterThing.character)) - { - var nums:Array = sizeChart[weekCharacterThing.character]; - size = nums[char]; - - // IDK, this might be busted ass null shit? - if (char != 1) - { - weekCharacterThing.x += nums[3]; - weekCharacterThing.y += nums[4]; - } - } - - weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * size)); - weekCharacterThing.updateHitbox(); - - grpWeekCharacters[index].add(weekCharacterThing); - trace("ADD CHARACTER"); - } - - trace(grpWeekCharacters[index].toString()); - } - - difficultySelectors = new FlxGroup(); - add(difficultySelectors); - - leftArrow = new FlxSprite(grpWeekText.members[0].x + grpWeekText.members[0].width + 10, grpWeekText.members[0].y + 10); - leftArrow.frames = ui_tex; - leftArrow.animation.addByPrefix('idle', "arrow left"); - leftArrow.animation.addByPrefix('press', "arrow push left"); - leftArrow.animation.play('idle'); - difficultySelectors.add(leftArrow); - - sprDifficulty = new FlxSprite(leftArrow.x + 130, leftArrow.y); - sprDifficulty.frames = ui_tex; - sprDifficulty.animation.addByPrefix('easy', 'EASY'); - sprDifficulty.animation.addByPrefix('normal', 'NORMAL'); - sprDifficulty.animation.addByPrefix('hard', 'HARD'); - sprDifficulty.animation.play('easy'); - changeDifficulty(); - - difficultySelectors.add(sprDifficulty); - - rightArrow = new FlxSprite(sprDifficulty.x + sprDifficulty.width + 50, leftArrow.y); - rightArrow.frames = ui_tex; - rightArrow.animation.addByPrefix('idle', 'arrow right'); - rightArrow.animation.addByPrefix('press', "arrow push right", 24, false); - rightArrow.animation.play('idle'); - difficultySelectors.add(rightArrow); - - add(yellowBG); - for (grp in grpWeekCharacters) - { - add(grp); - // trace("ADDED GRP"); - } - - // add(grpWeekCharacters); - - txtTracklist = new FlxText(FlxG.width * 0.05, yellowBG.x + yellowBG.height + 100, 0, "Tracks", 32); - txtTracklist.alignment = CENTER; - txtTracklist.font = rankText.font; - txtTracklist.color = 0xFFe55777; - add(txtTracklist); - // add(rankText); - add(scoreText); - add(txtWeekTitle); - - updateText(); - - super.create(); - } - - override function update(elapsed:Float) - { - // scoreText.setFormat('VCR OSD Mono', 32); - - yellowBG.color = FlxColor.interpolate(yellowBG.color, targetColor, 0.06); - - lerpScore = CoolUtil.coolLerp(lerpScore, intendedScore, 0.5); - - scoreText.text = "WEEK SCORE:" + Math.round(lerpScore); - - txtWeekTitle.text = weekNames[curWeek].toUpperCase(); - txtWeekTitle.x = FlxG.width - (txtWeekTitle.width + 10); - - // FlxG.watch.addQuick('font', scoreText.font); - - difficultySelectors.visible = weekUnlocked[curWeek]; - - grpLocks.forEach(function(lock:FlxSprite) - { - lock.y = grpWeekText.members[lock.ID].y; - }); - - if (!movedBack) - { - if (!selectedWeek) - { - if (controls.UI_UP_P) - { - changeWeek(-1); - } - - if (controls.UI_DOWN_P) - { - changeWeek(1); - } - - if (controls.UI_RIGHT) - rightArrow.animation.play('press') - else - rightArrow.animation.play('idle'); - - if (controls.UI_LEFT) - leftArrow.animation.play('press'); - else - leftArrow.animation.play('idle'); - - if (controls.UI_RIGHT_P) - changeDifficulty(1); - if (controls.UI_LEFT_P) - changeDifficulty(-1); - } - - if (controls.ACCEPT) - { - selectWeek(); - } - } - - if (controls.BACK && !movedBack && !selectedWeek) - { - FlxG.sound.play(Paths.sound('cancelMenu')); - movedBack = true; - FlxG.switchState(new MainMenuState()); - } - - super.update(elapsed); - } - - var movedBack:Bool = false; - var selectedWeek:Bool = false; - var stopspamming:Bool = false; - - function selectWeek() - { - if (weekUnlocked[curWeek]) - { - if (stopspamming == false) - { - FlxG.sound.play(Paths.sound('confirmMenu')); - - grpWeekText.members[curWeek].startFlashing(); - grpWeekCharacters[curWeek].members[1].animation.play('bfConfirm'); - stopspamming = true; - } - - PlayState.storyPlaylist = weekData[curWeek]; - PlayState.isStoryMode = true; - selectedWeek = true; - - PlayState.currentSong = SongLoad.loadFromJson(PlayState.storyPlaylist[0].toLowerCase(), PlayState.storyPlaylist[0].toLowerCase()); - PlayState.currentSong_NEW = SongDataParser.fetchSong(PlayState.storyPlaylist[0].toLowerCase()); - PlayState.storyWeek = curWeek; - PlayState.campaignScore = 0; - - PlayState.storyDifficulty = curDifficulty; - PlayState.storyDifficulty_NEW = switch (curDifficulty) - { - case 0: - 'easy'; - case 1: - 'normal'; - case 2: - 'hard'; - default: - 'normal'; - }; - SongLoad.curDiff = PlayState.storyDifficulty_NEW; - - new FlxTimer().start(1, function(tmr:FlxTimer) - { - LoadingState.loadAndSwitchState(new PlayState(), true); - }); - } - } - - function changeDifficulty(change:Int = 0):Void - { - curDifficulty += change; - - if (curDifficulty < 0) - curDifficulty = 2; - if (curDifficulty > 2) - curDifficulty = 0; - - sprDifficulty.offset.x = 0; - - switch (curDifficulty) - { - case 0: - sprDifficulty.animation.play('easy'); - sprDifficulty.offset.x = 20; - case 1: - sprDifficulty.animation.play('normal'); - sprDifficulty.offset.x = 70; - case 2: - sprDifficulty.animation.play('hard'); - sprDifficulty.offset.x = 20; - } - - sprDifficulty.alpha = 0; - - // USING THESE WEIRD VALUES SO THAT IT DOESNT FLOAT UP - sprDifficulty.y = leftArrow.y - 15; - intendedScore = Highscore.getWeekScore(curWeek, curDifficulty); - - FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07); - } - - var lerpScore:Float = 0; - var intendedScore:Int = 0; - - function changeWeek(change:Int = 0):Void - { - curWeek += change; - - if (curWeek >= weekData.length) - curWeek = 0; - if (curWeek < 0) - curWeek = weekData.length - 1; - - var bullShit:Int = 0; - - for (item in grpWeekText.members) - { - item.targetY = bullShit - curWeek; - if (item.targetY == Std.int(0) && weekUnlocked[curWeek]) - item.alpha = 1; - else - item.alpha = 0.6; - bullShit++; - } - - FlxG.sound.play(Paths.sound('scrollMenu')); - - updateText(); - } - - function updateText() - { - switch (weekType[curWeek]) - { - case WEEK: - targetColor = 0xFFF9CF51; - case WEEKEND: - targetColor = 0xFF413CAE; - } - - for (ind => grp in grpWeekCharacters) - grp.visible = ind == curWeek; - - txtTracklist.text = "Tracks\n"; - - var trackNames:Array = weekData[curWeek]; - for (i in trackNames) - { - txtTracklist.text += '\n${i}'; - } - - txtTracklist.text = txtTracklist.text.toUpperCase(); - - txtTracklist.screenCenter(X); - txtTracklist.x -= FlxG.width * 0.35; - - intendedScore = Highscore.getWeekScore(curWeek, curDifficulty); - } + var scoreText:FlxText; + + var weekData:Array> = [ + ['Tutorial'], + ['Bopeebo', 'Fresh', 'Dadbattle'], + ['Spookeez', 'South', "Monster"], + ['Pico', 'Philly', "Blammed"], + ['Satin-Panties', "High", "Milf"], + ['Cocoa', 'Eggnog', 'Winter-Horrorland'], + ['Senpai', 'Roses', 'Thorns'], + ['Ugh', 'Guns', 'Stress'], + ['Darnell', "lit-up", "2hot", "blazin"] + ]; + var curDifficulty:Int = 1; + + // TODO: This info is just hardcoded right now. + // We should probably make it so that weeks must be completed in order to unlock the next week. + public static var weekUnlocked:Array = [true, true, true, true, true, true, true, true, true]; + + var weekCharacters:Array = [ + ['dad', 'bf', 'gf'], + ['dad', 'bf', 'gf'], + ['spooky', 'bf', 'gf'], + ['pico', 'bf', 'gf'], + ['mom', 'bf', 'gf'], + ['parents-christmas', 'bf', 'gf'], + ['senpai', 'bf', 'gf'], + ['tankman', 'bf', 'gf'], + ['darnell', 'pico', 'nene'] + ]; + + var weekNames:Array = [ + "", + "Daddy Dearest", + "Spooky Month", + "PICO", + "MOMMY MUST MURDER", + "RED SNOW", + "hating simulator ft. moawling", + "TANKMAN", + "Due Debts" + ]; + + var weekType:Array = [WEEK, WEEK, WEEK, WEEK, WEEK, WEEK, WEEK, WEEK, WEEKEND]; + var weekTypeInc:Map = new Map(); + + var txtWeekTitle:FlxText; + + var curWeek:Int = 0; + + var txtTracklist:FlxText; + + var grpWeekText:FlxTypedGroup; + var grpWeekCharacters:Array>; + + // var grpWeekCharacters:FlxTypedGroup; + var grpLocks:FlxTypedGroup; + + var difficultySelectors:FlxGroup; + var sprDifficulty:FlxSprite; + var leftArrow:FlxSprite; + var rightArrow:FlxSprite; + var yellowBG:FlxSprite; // not actually, yellow, lol! + var targetColor:Int = 0xFFF9CF51; + + override function create() + { + transIn = FlxTransitionableState.defaultTransIn; + transOut = FlxTransitionableState.defaultTransOut; + + if (FlxG.sound.music != null) + { + if (!FlxG.sound.music.playing) FlxG.sound.playMusic(Paths.music('freakyMenu')); + } + + persistentUpdate = persistentDraw = true; + + scoreText = new FlxText(10, 10, 0, "SCORE: 49324858", 36); + scoreText.setFormat("VCR OSD Mono", 32); + + txtWeekTitle = new FlxText(FlxG.width * 0.7, 10, 0, "", 32); + txtWeekTitle.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, RIGHT); + txtWeekTitle.alpha = 0.7; + + var rankText:FlxText = new FlxText(0, 10); + rankText.text = 'RANK: GREAT'; + rankText.setFormat(Paths.font("vcr.ttf"), 32); + rankText.size = scoreText.size; + rankText.screenCenter(X); + + var ui_tex = Paths.getSparrowAtlas('campaign_menu_UI_assets'); + yellowBG = new FlxSprite(0, 56).makeGraphic(FlxG.width, 400, FlxColor.WHITE); + yellowBG.color = 0xFFF9CF51; + // 0xFF413CAE blue + // 0xFFF9CF51 yello + + grpWeekText = new FlxTypedGroup(); + add(grpWeekText); + + var blackBarThingie:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, 56, FlxColor.BLACK); + add(blackBarThingie); + + // grpWeekCharacters = new FlxTypedGroup(); + grpWeekCharacters = []; + + grpLocks = new FlxTypedGroup(); + add(grpLocks); + + #if discord_rpc + // Updating Discord Rich Presence + DiscordClient.changePresence("In the Menus", null); + #end + + for (i in 0...weekData.length) + { + if (!weekTypeInc.exists(weekType[i])) weekTypeInc[weekType[i]] = 1; + + if (i == 0 && weekType[i] == WEEK) weekTypeInc[weekType[i]] = 0; // set week to 0 by default? + + var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, weekTypeInc[weekType[i]], weekType[i]); + weekThing.y += ((weekThing.height + 20) * i); + weekThing.targetY = i; + grpWeekText.add(weekThing); + + weekTypeInc[weekType[i]] += 1; + + weekThing.screenCenter(X); + weekThing.antialiasing = true; + // weekThing.updateHitbox(); + + // Needs an offset thingie + if (!weekUnlocked[i]) + { + var lock:FlxSprite = new FlxSprite(weekThing.width + 10 + weekThing.x); + lock.frames = ui_tex; + lock.animation.addByPrefix('lock', 'lock'); + lock.animation.play('lock'); + lock.ID = i; + lock.antialiasing = true; + grpLocks.add(lock); + } + } + + var sizeChart:Map> = new Map(); + + var sizeTxt:Array = Assets.getText(Paths.file("data/storychardata.txt")).split("\n"); + + for (item in sizeTxt) + { + var items:Array = item.split(" "); + + var stuf:Array = []; + var name:String = items.shift(); + + for (num in items) + stuf.push(Std.parseFloat(num)); + + sizeChart.set(name, stuf); + } + + for (index => week in weekCharacters) + { + grpWeekCharacters.push(new FlxTypedGroup()); + + for (char in 0...week.length) + { + var weekCharacterThing:MenuCharacter = new MenuCharacter((FlxG.width * 0.25) * (1 + char) - 150, weekCharacters[index][char]); + weekCharacterThing.y += 70; + weekCharacterThing.antialiasing = true; + + var size:Float = 0.9; + + switch (char) + { + case 0 | 2: + size = 0.5; + if (char == 0 && weekCharacterThing.character == "pico") weekCharacterThing.flipX = true; + case 1: + size = 0.9; + weekCharacterThing.x -= 80; + } + + if (sizeChart.exists(weekCharacterThing.character)) + { + var nums:Array = sizeChart[weekCharacterThing.character]; + size = nums[char]; + + // IDK, this might be busted ass null shit? + if (char != 1) + { + weekCharacterThing.x += nums[3]; + weekCharacterThing.y += nums[4]; + } + } + + weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * size)); + weekCharacterThing.updateHitbox(); + + grpWeekCharacters[index].add(weekCharacterThing); + trace("ADD CHARACTER"); + } + + trace(grpWeekCharacters[index].toString()); + } + + difficultySelectors = new FlxGroup(); + add(difficultySelectors); + + leftArrow = new FlxSprite(grpWeekText.members[0].x + grpWeekText.members[0].width + 10, grpWeekText.members[0].y + 10); + leftArrow.frames = ui_tex; + leftArrow.animation.addByPrefix('idle', "arrow left"); + leftArrow.animation.addByPrefix('press', "arrow push left"); + leftArrow.animation.play('idle'); + difficultySelectors.add(leftArrow); + + sprDifficulty = new FlxSprite(leftArrow.x + 130, leftArrow.y); + sprDifficulty.frames = ui_tex; + sprDifficulty.animation.addByPrefix('easy', 'EASY'); + sprDifficulty.animation.addByPrefix('normal', 'NORMAL'); + sprDifficulty.animation.addByPrefix('hard', 'HARD'); + sprDifficulty.animation.play('easy'); + changeDifficulty(); + + difficultySelectors.add(sprDifficulty); + + rightArrow = new FlxSprite(sprDifficulty.x + sprDifficulty.width + 50, leftArrow.y); + rightArrow.frames = ui_tex; + rightArrow.animation.addByPrefix('idle', 'arrow right'); + rightArrow.animation.addByPrefix('press', "arrow push right", 24, false); + rightArrow.animation.play('idle'); + difficultySelectors.add(rightArrow); + + add(yellowBG); + for (grp in grpWeekCharacters) + { + add(grp); + // trace("ADDED GRP"); + } + + // add(grpWeekCharacters); + + txtTracklist = new FlxText(FlxG.width * 0.05, yellowBG.x + yellowBG.height + 100, 0, "Tracks", 32); + txtTracklist.alignment = CENTER; + txtTracklist.font = rankText.font; + txtTracklist.color = 0xFFe55777; + add(txtTracklist); + // add(rankText); + add(scoreText); + add(txtWeekTitle); + + updateText(); + + super.create(); + } + + override function update(elapsed:Float) + { + // scoreText.setFormat('VCR OSD Mono', 32); + + yellowBG.color = FlxColor.interpolate(yellowBG.color, targetColor, 0.06); + + lerpScore = CoolUtil.coolLerp(lerpScore, intendedScore, 0.5); + + scoreText.text = "WEEK SCORE:" + Math.round(lerpScore); + + txtWeekTitle.text = weekNames[curWeek].toUpperCase(); + txtWeekTitle.x = FlxG.width - (txtWeekTitle.width + 10); + + // FlxG.watch.addQuick('font', scoreText.font); + + difficultySelectors.visible = weekUnlocked[curWeek]; + + grpLocks.forEach(function(lock:FlxSprite) + { + lock.y = grpWeekText.members[lock.ID].y; + }); + + if (!movedBack) + { + if (!selectedWeek) + { + if (controls.UI_UP_P) + { + changeWeek(-1); + } + + if (controls.UI_DOWN_P) + { + changeWeek(1); + } + + if (controls.UI_RIGHT) rightArrow.animation.play('press') + else + rightArrow.animation.play('idle'); + + if (controls.UI_LEFT) leftArrow.animation.play('press'); + else + leftArrow.animation.play('idle'); + + if (controls.UI_RIGHT_P) changeDifficulty(1); + if (controls.UI_LEFT_P) changeDifficulty(-1); + } + + if (controls.ACCEPT) + { + selectWeek(); + } + } + + if (controls.BACK && !movedBack && !selectedWeek) + { + FlxG.sound.play(Paths.sound('cancelMenu')); + movedBack = true; + FlxG.switchState(new MainMenuState()); + } + + super.update(elapsed); + } + + var movedBack:Bool = false; + var selectedWeek:Bool = false; + var stopspamming:Bool = false; + + function selectWeek() + { + if (weekUnlocked[curWeek]) + { + if (stopspamming == false) + { + FlxG.sound.play(Paths.sound('confirmMenu')); + + grpWeekText.members[curWeek].startFlashing(); + grpWeekCharacters[curWeek].members[1].animation.play('bfConfirm'); + stopspamming = true; + } + + PlayState.storyPlaylist = weekData[curWeek]; + PlayState.isStoryMode = true; + selectedWeek = true; + + PlayState.currentSong = SongLoad.loadFromJson(PlayState.storyPlaylist[0].toLowerCase(), PlayState.storyPlaylist[0].toLowerCase()); + PlayState.currentSong_NEW = SongDataParser.fetchSong(PlayState.storyPlaylist[0].toLowerCase()); + PlayState.storyWeek = curWeek; + PlayState.campaignScore = 0; + + PlayState.storyDifficulty = curDifficulty; + PlayState.storyDifficulty_NEW = switch (curDifficulty) + { + case 0: + 'easy'; + case 1: + 'normal'; + case 2: + 'hard'; + default: + 'normal'; + }; + SongLoad.curDiff = PlayState.storyDifficulty_NEW; + + new FlxTimer().start(1, function(tmr:FlxTimer) + { + LoadingState.loadAndSwitchState(new PlayState(), true); + }); + } + } + + function changeDifficulty(change:Int = 0):Void + { + curDifficulty += change; + + if (curDifficulty < 0) curDifficulty = 2; + if (curDifficulty > 2) curDifficulty = 0; + + sprDifficulty.offset.x = 0; + + switch (curDifficulty) + { + case 0: + sprDifficulty.animation.play('easy'); + sprDifficulty.offset.x = 20; + case 1: + sprDifficulty.animation.play('normal'); + sprDifficulty.offset.x = 70; + case 2: + sprDifficulty.animation.play('hard'); + sprDifficulty.offset.x = 20; + } + + sprDifficulty.alpha = 0; + + // USING THESE WEIRD VALUES SO THAT IT DOESNT FLOAT UP + sprDifficulty.y = leftArrow.y - 15; + intendedScore = Highscore.getWeekScore(curWeek, curDifficulty); + + FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07); + } + + var lerpScore:Float = 0; + var intendedScore:Int = 0; + + function changeWeek(change:Int = 0):Void + { + curWeek += change; + + if (curWeek >= weekData.length) curWeek = 0; + if (curWeek < 0) curWeek = weekData.length - 1; + + var bullShit:Int = 0; + + for (item in grpWeekText.members) + { + item.targetY = bullShit - curWeek; + if (item.targetY == Std.int(0) && weekUnlocked[curWeek]) item.alpha = 1; + else + item.alpha = 0.6; + bullShit++; + } + + FlxG.sound.play(Paths.sound('scrollMenu')); + + updateText(); + } + + function updateText() + { + switch (weekType[curWeek]) + { + case WEEK: + targetColor = 0xFFF9CF51; + case WEEKEND: + targetColor = 0xFF413CAE; + } + + for (ind => grp in grpWeekCharacters) + grp.visible = ind == curWeek; + + txtTracklist.text = "Tracks\n"; + + var trackNames:Array = weekData[curWeek]; + for (i in trackNames) + { + txtTracklist.text += '\n${i}'; + } + + txtTracklist.text = txtTracklist.text.toUpperCase(); + + txtTracklist.screenCenter(X); + txtTracklist.x -= FlxG.width * 0.35; + + intendedScore = Highscore.getWeekScore(curWeek, curDifficulty); + } } diff --git a/source/funkin/SwagCamera.hx b/source/funkin/SwagCamera.hx index 7184601b9..386eaea62 100644 --- a/source/funkin/SwagCamera.hx +++ b/source/funkin/SwagCamera.hx @@ -6,97 +6,97 @@ import flixel.math.FlxPoint; class SwagCamera extends FlxCamera { - /** - * properly follow framerate - * most of this just copied from FlxCamera, - * only lines 96 and 97 are changed - */ - override public function updateFollow():Void - { - // Either follow the object closely, - // or double check our deadzone and update accordingly. - if (deadzone == null) - { - target.getMidpoint(_point); - _point.addPoint(targetOffset); - focusOn(_point); - } - else - { - var edge:Float; - var targetX:Float = target.x + targetOffset.x; - var targetY:Float = target.y + targetOffset.y; + /** + * properly follow framerate + * most of this just copied from FlxCamera, + * only lines 96 and 97 are changed + */ + override public function updateFollow():Void + { + // Either follow the object closely, + // or double check our deadzone and update accordingly. + if (deadzone == null) + { + target.getMidpoint(_point); + _point.addPoint(targetOffset); + focusOn(_point); + } + else + { + var edge:Float; + var targetX:Float = target.x + targetOffset.x; + var targetY:Float = target.y + targetOffset.y; - if (style == SCREEN_BY_SCREEN) - { - if (targetX >= (scroll.x + width)) - { - _scrollTarget.x += width; - } - else if (targetX < scroll.x) - { - _scrollTarget.x -= width; - } + if (style == SCREEN_BY_SCREEN) + { + if (targetX >= (scroll.x + width)) + { + _scrollTarget.x += width; + } + else if (targetX < scroll.x) + { + _scrollTarget.x -= width; + } - if (targetY >= (scroll.y + height)) - { - _scrollTarget.y += height; - } - else if (targetY < scroll.y) - { - _scrollTarget.y -= height; - } - } - else - { - edge = targetX - deadzone.x; - if (_scrollTarget.x > edge) - { - _scrollTarget.x = edge; - } - edge = targetX + target.width - deadzone.x - deadzone.width; - if (_scrollTarget.x < edge) - { - _scrollTarget.x = edge; - } + if (targetY >= (scroll.y + height)) + { + _scrollTarget.y += height; + } + else if (targetY < scroll.y) + { + _scrollTarget.y -= height; + } + } + else + { + edge = targetX - deadzone.x; + if (_scrollTarget.x > edge) + { + _scrollTarget.x = edge; + } + edge = targetX + target.width - deadzone.x - deadzone.width; + if (_scrollTarget.x < edge) + { + _scrollTarget.x = edge; + } - edge = targetY - deadzone.y; - if (_scrollTarget.y > edge) - { - _scrollTarget.y = edge; - } - edge = targetY + target.height - deadzone.y - deadzone.height; - if (_scrollTarget.y < edge) - { - _scrollTarget.y = edge; - } - } + edge = targetY - deadzone.y; + if (_scrollTarget.y > edge) + { + _scrollTarget.y = edge; + } + edge = targetY + target.height - deadzone.y - deadzone.height; + if (_scrollTarget.y < edge) + { + _scrollTarget.y = edge; + } + } - if ((target is FlxSprite)) - { - if (_lastTargetPosition == null) - { - _lastTargetPosition = FlxPoint.get(target.x, target.y); // Creates this point. - } - _scrollTarget.x += (target.x - _lastTargetPosition.x) * followLead.x; - _scrollTarget.y += (target.y - _lastTargetPosition.y) * followLead.y; + if ((target is FlxSprite)) + { + if (_lastTargetPosition == null) + { + _lastTargetPosition = FlxPoint.get(target.x, target.y); // Creates this point. + } + _scrollTarget.x += (target.x - _lastTargetPosition.x) * followLead.x; + _scrollTarget.y += (target.y - _lastTargetPosition.y) * followLead.y; - _lastTargetPosition.x = target.x; - _lastTargetPosition.y = target.y; - } + _lastTargetPosition.x = target.x; + _lastTargetPosition.y = target.y; + } - if (followLerp >= 60 / FlxG.updateFramerate) - { - scroll.copyFrom(_scrollTarget); // no easing - } - else - { - // THIS THE PART THAT ACTUALLY MATTERS LOL - scroll.x = CoolUtil.coolLerp(scroll.x, _scrollTarget.x, followLerp); - scroll.y = CoolUtil.coolLerp(scroll.y, _scrollTarget.y, followLerp); - // scroll.x += (_scrollTarget.x - scroll.x) * CoolUtil.camLerpShit(followLerp); - // scroll.y += (_scrollTarget.y - scroll.y) * CoolUtil.camLerpShit(followLerp); - } - } - } + if (followLerp >= 60 / FlxG.updateFramerate) + { + scroll.copyFrom(_scrollTarget); // no easing + } + else + { + // THIS THE PART THAT ACTUALLY MATTERS LOL + scroll.x = CoolUtil.coolLerp(scroll.x, _scrollTarget.x, followLerp); + scroll.y = CoolUtil.coolLerp(scroll.y, _scrollTarget.y, followLerp); + // scroll.x += (_scrollTarget.x - scroll.x) * CoolUtil.camLerpShit(followLerp); + // scroll.y += (_scrollTarget.y - scroll.y) * CoolUtil.camLerpShit(followLerp); + } + } + } } diff --git a/source/funkin/TankCutscene.hx b/source/funkin/TankCutscene.hx index a144b16fe..9b1078eae 100644 --- a/source/funkin/TankCutscene.hx +++ b/source/funkin/TankCutscene.hx @@ -5,23 +5,23 @@ import flixel.system.FlxSound; class TankCutscene extends FlxSprite { - public var startSyncAudio:FlxSound; + public var startSyncAudio:FlxSound; - public function new(x:Float, y:Float) - { - super(x, y); - } + public function new(x:Float, y:Float) + { + super(x, y); + } - var startedPlayingSound:Bool = false; + var startedPlayingSound:Bool = false; - override function update(elapsed:Float) - { - if (animation.curAnim.curFrame >= 1 && !startedPlayingSound) - { - startSyncAudio.play(); - startedPlayingSound = true; - } + override function update(elapsed:Float) + { + if (animation.curAnim.curFrame >= 1 && !startedPlayingSound) + { + startSyncAudio.play(); + startedPlayingSound = true; + } - super.update(elapsed); - } + super.update(elapsed); + } } diff --git a/source/funkin/TitleState.hx b/source/funkin/TitleState.hx index 6db3434cb..e8e96e54d 100644 --- a/source/funkin/TitleState.hx +++ b/source/funkin/TitleState.hx @@ -27,603 +27,573 @@ import openfl.net.NetStream; #end class TitleState extends MusicBeatState { - public static var initialized:Bool = false; + public static var initialized:Bool = false; - var blackScreen:FlxSprite; - var credGroup:FlxGroup; - var textGroup:FlxGroup; - var ngSpr:FlxSprite; + var blackScreen:FlxSprite; + var credGroup:FlxGroup; + var textGroup:FlxGroup; + var ngSpr:FlxSprite; - var curWacky:Array = []; - var lastBeat:Int = 0; - var swagShader:ColorSwap; + var curWacky:Array = []; + var lastBeat:Int = 0; + var swagShader:ColorSwap; - var video:Video; - var netStream:NetStream; - private var overlay:Sprite; + var video:Video; + var netStream:NetStream; + var overlay:Sprite; - override public function create():Void - { - swagShader = new ColorSwap(); + override public function create():Void + { + swagShader = new ColorSwap(); - curWacky = FlxG.random.getObject(getIntroTextShit()); - FlxG.sound.cache(Paths.music('freakyMenu')); + curWacky = FlxG.random.getObject(getIntroTextShit()); + FlxG.sound.cache(Paths.music('freakyMenu')); - // DEBUG BULLSHIT + // DEBUG BULLSHIT - super.create(); + super.create(); - /* - #elseif web + /* + #elseif web - if (!initialized) - { + if (!initialized) + { - video = new Video(); - FlxG.stage.addChild(video); + video = new Video(); + FlxG.stage.addChild(video); - var netConnection = new NetConnection(); - netConnection.connect(null); + var netConnection = new NetConnection(); + netConnection.connect(null); - netStream = new NetStream(netConnection); - netStream.client = {onMetaData: client_onMetaData}; - netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError); - netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); - // netStream.addEventListener(NetStatusEvent.NET_STATUS) // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); + netStream = new NetStream(netConnection); + netStream.client = {onMetaData: client_onMetaData}; + netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError); + netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); + // netStream.addEventListener(NetStatusEvent.NET_STATUS) // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - overlay = new Sprite(); - overlay.graphics.beginFill(0, 0.5); - overlay.graphics.drawRect(0, 0, 1280, 720); - overlay.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); + overlay = new Sprite(); + overlay.graphics.beginFill(0, 0.5); + overlay.graphics.drawRect(0, 0, 1280, 720); + overlay.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); - overlay.buttonMode = true; - // FlxG.stage.addChild(overlay); + overlay.buttonMode = true; + // FlxG.stage.addChild(overlay); - } - */ + } + */ - // netConnection.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); - new FlxTimer().start(1, function(tmr:FlxTimer) - { - startIntro(); - }); - } + // netConnection.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); + new FlxTimer().start(1, function(tmr:FlxTimer) + { + startIntro(); + }); + } - private function client_onMetaData(metaData:Dynamic) - { - video.attachNetStream(netStream); + function client_onMetaData(metaData:Dynamic) + { + video.attachNetStream(netStream); - video.width = video.videoWidth; - video.height = video.videoHeight; - // video. - } + video.width = video.videoWidth; + video.height = video.videoHeight; + // video. + } - private function netStream_onAsyncError(event:AsyncErrorEvent):Void - { - trace("Error loading video"); - } + function netStream_onAsyncError(event:AsyncErrorEvent):Void + { + trace("Error loading video"); + } - private function netConnection_onNetStatus(event:NetStatusEvent):Void - { - if (event.info.code == 'NetStream.Play.Complete') - { - // netStream.dispose(); - // FlxG.stage.removeChild(video); + function netConnection_onNetStatus(event:NetStatusEvent):Void + { + if (event.info.code == 'NetStream.Play.Complete') + { + // netStream.dispose(); + // FlxG.stage.removeChild(video); - startIntro(); - } + startIntro(); + } - trace(event.toString()); - } - - private function overlay_onMouseDown(event:MouseEvent):Void - { - netStream.soundTransform.volume = 0.2; - netStream.soundTransform.pan = -1; - // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - - FlxG.stage.removeChild(overlay); - } + trace(event.toString()); + } + + function overlay_onMouseDown(event:MouseEvent):Void + { + netStream.soundTransform.volume = 0.2; + netStream.soundTransform.pan = -1; + // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); + + FlxG.stage.removeChild(overlay); + } - var logoBl:FlxSprite; - var outlineShaderShit:TitleOutline; + var logoBl:FlxSprite; + var outlineShaderShit:TitleOutline; - var gfDance:FlxSprite; - var danceLeft:Bool = false; - var titleText:FlxSprite; - var maskShader = new LeftMaskShader(); + var gfDance:FlxSprite; + var danceLeft:Bool = false; + var titleText:FlxSprite; + var maskShader = new LeftMaskShader(); - function startIntro() - { - if (FlxG.sound.music == null || !FlxG.sound.music.playing) - { - FlxG.sound.playMusic(Paths.music('freakyMenu'), 0); - FlxG.sound.music.fadeIn(4, 0, 0.7); - Conductor.forceBPM(Constants.FREAKY_MENU_BPM); - } - - persistentUpdate = true; + function startIntro() + { + if (FlxG.sound.music == null || !FlxG.sound.music.playing) + { + FlxG.sound.playMusic(Paths.music('freakyMenu'), 0); + FlxG.sound.music.fadeIn(4, 0, 0.7); + Conductor.forceBPM(Constants.FREAKY_MENU_BPM); + } - var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - add(bg); - - logoBl = new FlxSprite(-150, -100); - logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); - logoBl.antialiasing = true; - logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); - logoBl.animation.play('bump'); - - logoBl.updateHitbox(); - - outlineShaderShit = new TitleOutline(); - - gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); - gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); - gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); - gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); - gfDance.antialiasing = true; - - add(gfDance); - - // maskShader.swagSprX = gfDance.x; - // maskShader.swagMaskX = gfDance.x + 200; - // maskShader.frameUV = gfDance.frame.uv; - // gfDance.shader = maskShader; - - // gfDance.shader = swagShader.shader; - - // gfDance.shader = new TitleOutline(); - - add(logoBl); - - titleText = new FlxSprite(100, FlxG.height * 0.8); - titleText.frames = Paths.getSparrowAtlas('titleEnter'); - titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); - titleText.animation.addByPrefix('press', "ENTER PRESSED", 24); - titleText.antialiasing = true; - titleText.animation.play('idle'); - titleText.updateHitbox(); - // titleText.screenCenter(X); - add(titleText); - - credGroup = new FlxGroup(); - add(credGroup); - - textGroup = new FlxGroup(); - - blackScreen = bg.clone(); - credGroup.add(blackScreen); - credGroup.add(textGroup); - - // var atlasBullShit:FlxSprite = new FlxSprite(); - // atlasBullShit.frames = CoolUtil.fromAnimate(Paths.image('money'), Paths.file('images/money.json')); - // credGroup.add(atlasBullShit); - - ngSpr = new FlxSprite(0, FlxG.height * 0.52); - - if (FlxG.random.bool(1)) - { - ngSpr.loadGraphic(Paths.image('newgrounds_logo_classic')); - } - else if (FlxG.random.bool(30)) - { - ngSpr.loadGraphic(Paths.image('newgrounds_logo_animated'), true, 600); - ngSpr.animation.add('idle', [0, 1], 4); - ngSpr.animation.play('idle'); - ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.55)); - } - else - { - ngSpr.loadGraphic(Paths.image('newgrounds_logo')); - ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); - } - - add(ngSpr); - ngSpr.visible = false; - - ngSpr.updateHitbox(); - ngSpr.screenCenter(X); - ngSpr.antialiasing = true; - - FlxG.mouse.visible = false; - - if (initialized) - skipIntro(); - else - initialized = true; - - if (FlxG.sound.music != null) - FlxG.sound.music.onComplete = function() FlxG.switchState(new VideoState()); - } - - function getIntroTextShit():Array> - { - var fullText:String = Assets.getText(Paths.txt('introText')); - - var firstArray:Array = fullText.split('\n'); - var swagGoodArray:Array> = []; - - for (i in firstArray) - { - swagGoodArray.push(i.split('--')); - } - - return swagGoodArray; - } - - var transitioning:Bool = false; - - override function update(elapsed:Float) - { - #if HAS_PITCH - if (FlxG.keys.pressed.UP) - FlxG.sound.music.pitch += 0.5 * elapsed; - - if (FlxG.keys.pressed.DOWN) - FlxG.sound.music.pitch -= 0.5 * elapsed; - #end - - Conductor.update(); - - /* if (FlxG.onMobile) - { - if (gfDance != null) - { - gfDance.x = (FlxG.width / 2) + (FlxG.accelerometer.x * (FlxG.width / 2)); - // gfDance.y = (FlxG.height / 2) + (FlxG.accelerometer.y * (FlxG.height / 2)); - } - } - */ - if (FlxG.keys.justPressed.I) - { - FlxTween.tween(outlineShaderShit, {funnyX: 50, funnyY: 50}, 0.6, {ease: FlxEase.quartOut}); - } - if (FlxG.keys.pressed.D) - outlineShaderShit.funnyX += 1; - // outlineShaderShit.xPos.value[0] += 1; - - if (FlxG.keys.justPressed.Y) - { - FlxTween.tween(FlxG.stage.window, {x: FlxG.stage.window.x + 300}, 1.4, {ease: FlxEase.quadInOut, type: PINGPONG, startDelay: 0.35}); - FlxTween.tween(FlxG.stage.window, {y: FlxG.stage.window.y + 100}, 0.7, {ease: FlxEase.quadInOut, type: PINGPONG}); - } - - /* - FlxG.watch.addQuick('cur display', FlxG.stage.window.display.id); - if (FlxG.keys.justPressed.Y) - { - // trace(FlxG.stage.window.display.name); - - if (FlxG.gamepads.firstActive != null) - { - trace(FlxG.gamepads.firstActive.model); - FlxG.gamepads.firstActive.id - } - else - trace('gamepad null'); - - // FlxG.stage.window.title = Std.string(FlxG.random.int(0, 20000)); - // FlxG.stage.window.setIcon(Image.fromFile('assets/images/icon16.png')); - // FlxG.stage.window.readPixels; - - if (FlxG.stage.window.width == Std.int(FlxG.stage.window.display.bounds.width)) - { - FlxG.stage.window.width = 1280; - FlxG.stage.window.height = 720; - FlxG.stage.window.y = 30; - } - else - { - FlxG.stage.window.width = Std.int(FlxG.stage.window.display.bounds.width); - FlxG.stage.window.height = Std.int(FlxG.stage.window.display.bounds.height); - FlxG.stage.window.x = Std.int(FlxG.stage.window.display.bounds.x); - FlxG.stage.window.y = Std.int(FlxG.stage.window.display.bounds.y); - } - } - */ - - #if debug - if (FlxG.keys.justPressed.EIGHT) - FlxG.switchState(new CutsceneAnimTestState()); - #end - - if (FlxG.sound.music != null) - Conductor.songPosition = FlxG.sound.music.time; - if (FlxG.keys.justPressed.F) - FlxG.fullscreen = !FlxG.fullscreen; - - // do controls.PAUSE | controls.ACCEPT instead? - var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; - - if (FlxG.onMobile) - { - for (touch in FlxG.touches.list) - { - if (touch.justPressed) - { - FlxG.switchState(new FreeplayState()); - pressedEnter = true; - } - } - } - - var gamepad:FlxGamepad = FlxG.gamepads.lastActive; - - if (gamepad != null) - { - if (gamepad.justPressed.START) - pressedEnter = true; - #if switch - if (gamepad.justPressed.B) - pressedEnter = true; - #end - } - - // a faster intro thing lol! - if (pressedEnter && transitioning && skippedIntro) - { - FlxG.switchState(new MainMenuState()); - } - - if (pressedEnter && !transitioning && skippedIntro) - { - if (FlxG.sound.music != null) - FlxG.sound.music.onComplete = null; - // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - NGio.unlockMedal(60960); - // If it's Friday according to da clock - if (Date.now().getDay() == 5) - NGio.unlockMedal(61034); - titleText.animation.play('press'); - FlxG.camera.flash(FlxColor.WHITE, 1); - FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); - transitioning = true; - - var targetState:FlxState = new MainMenuState(); - - #if newgrounds - if (!OutdatedSubState.leftState) - { - NGio.checkVersion(function(version) - { - // Check if version is outdated - var localVersion:String = "v" + Application.current.meta.get('version'); - var onlineVersion = version.split(" ")[0].trim(); - if (version.trim() != onlineVersion) - { - trace('OLD VERSION!'); - // targetState = new OutdatedSubState(); - } - else - { - // targetState = new MainMenuState(); - } - // REDO FOR ITCH/FINAL SHIT - }); - } - #end - new FlxTimer().start(2, function(tmr:FlxTimer) - { - // These assets are very unlikely to be used for the rest of gameplay, so it unloads them from cache/memory - // Saves about 50mb of RAM or so??? - Assets.cache.clear(Paths.image('gfDanceTitle')); - Assets.cache.clear(Paths.image('logoBumpin')); - Assets.cache.clear(Paths.image('titleEnter')); - // ngSpr?? - FlxG.switchState(targetState); - }); - // FlxG.sound.play(Paths.music('titleShoot'), 0.7); - } - if (pressedEnter && !skippedIntro && initialized) - skipIntro(); - /* - #if web - if (!initialized && controls.ACCEPT) - { - // netStream.dispose(); - // FlxG.stage.removeChild(video); - - startIntro(); - skipIntro(); - } - #end - */ - - if (controls.UI_LEFT) - swagShader.update(-elapsed * 0.1); - if (controls.UI_RIGHT) - swagShader.update(elapsed * 0.1); - if (!cheatActive && skippedIntro) - cheatCodeShit(); - super.update(elapsed); - } - - override function draw() - { - super.draw(); - - // if (gfDance != null) - // { - // trace(gfDance.frame.uv); - // maskShader.frameUV = gfDance.frame.uv; - // } - } - - var cheatArray:Array = [0x0001, 0x0010, 0x0001, 0x0010, 0x0100, 0x1000, 0x0100, 0x1000]; - var curCheatPos:Int = 0; - var cheatActive:Bool = false; - - function cheatCodeShit():Void - { - if (FlxG.keys.justPressed.ANY) - { - if (controls.NOTE_DOWN_P || controls.UI_DOWN_P) - codePress(FlxDirectionFlags.DOWN); - if (controls.NOTE_UP_P || controls.UI_UP_P) - codePress(FlxDirectionFlags.UP); - if (controls.NOTE_LEFT_P || controls.UI_LEFT_P) - codePress(FlxDirectionFlags.LEFT); - if (controls.NOTE_RIGHT_P || controls.UI_RIGHT_P) - codePress(FlxDirectionFlags.RIGHT); - } - } - - function codePress(input:Int) - { - if (input == cheatArray[curCheatPos]) - { - curCheatPos += 1; - if (curCheatPos >= cheatArray.length) - startCheat(); - } - else - curCheatPos = 0; - - trace(input); - } - - function startCheat():Void - { - cheatActive = true; - - FlxG.sound.playMusic(Paths.music('tutorialTitle'), 1); - - var spec:SpectogramSprite = new SpectogramSprite(FlxG.sound.music); - add(spec); - - Conductor.forceBPM(190); - FlxG.camera.flash(FlxColor.WHITE, 1); - FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); - } - - function createCoolText(textArray:Array) - { - if (credGroup == null || textGroup == null) - return; - - for (i in 0...textArray.length) - { - var money:AtlasText = new AtlasText(0, 0, textArray[i], AtlasFont.BOLD); - money.screenCenter(X); - money.y += (i * 60) + 200; - // credGroup.add(money); - textGroup.add(money); - } - } - - function addMoreText(text:String) - { - if (credGroup == null || textGroup == null) - return; - - lime.ui.Haptic.vibrate(100, 100); - - var coolText:AtlasText = new AtlasText(0, 0, text.trim(), AtlasFont.BOLD); - coolText.screenCenter(X); - coolText.y += (textGroup.length * 60) + 200; - textGroup.add(coolText); - } - - function deleteCoolText() - { - if (credGroup == null || textGroup == null) - return; - - while (textGroup.members.length > 0) - { - // credGroup.remove(textGroup.members[0], true); - textGroup.remove(textGroup.members[0], true); - } - } - - var isRainbow:Bool = false; - var skippedIntro:Bool = false; - - override function beatHit():Bool - { - // super.beatHit() returns false if a module cancelled the event. - if (!super.beatHit()) - return false; - - if (!skippedIntro) - { - // FlxG.log.add(Conductor.currentBeat); - // if the user is draggin the window some beats will - // be missed so this is just to compensate - if (Conductor.currentBeat > lastBeat) - { - // TODO: Why does it perform ALL the previous steps each beat? - for (i in lastBeat...Conductor.currentBeat) - { - switch (i + 1) - { - case 1: - createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8r']); - case 3: - addMoreText('present'); - case 4: - deleteCoolText(); - case 5: - createCoolText(['In association', 'with']); - case 7: - addMoreText('newgrounds'); - if (ngSpr != null) - ngSpr.visible = true; - case 8: - deleteCoolText(); - if (ngSpr != null) - ngSpr.visible = false; - case 9: - createCoolText([curWacky[0]]); - case 11: - addMoreText(curWacky[1]); - case 12: - deleteCoolText(); - case 13: - addMoreText('Friday'); - case 14: - addMoreText('Night'); - case 15: - addMoreText('Funkin'); - case 16: - skipIntro(); - } - } - } - lastBeat = Conductor.currentBeat; - } - if (skippedIntro) - { - if (cheatActive && Conductor.currentBeat % 2 == 0) - swagShader.update(0.125); - - if (logoBl != null && logoBl.animation != null) - logoBl.animation.play('bump', true); - - danceLeft = !danceLeft; - - if (gfDance != null && gfDance.animation != null) - { - if (danceLeft) - gfDance.animation.play('danceRight'); - else - gfDance.animation.play('danceLeft'); - } - } - - return true; - } - - function skipIntro():Void - { - if (!skippedIntro) - { - remove(ngSpr); - - FlxG.camera.flash(FlxColor.WHITE, 4); - remove(credGroup); - skippedIntro = true; - } - } + persistentUpdate = true; + + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + add(bg); + + logoBl = new FlxSprite(-150, -100); + logoBl.frames = Paths.getSparrowAtlas('logoBumpin'); + logoBl.antialiasing = true; + logoBl.animation.addByPrefix('bump', 'logo bumpin', 24); + logoBl.animation.play('bump'); + + logoBl.updateHitbox(); + + outlineShaderShit = new TitleOutline(); + + gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); + gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); + gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); + gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); + gfDance.antialiasing = true; + + add(gfDance); + + // maskShader.swagSprX = gfDance.x; + // maskShader.swagMaskX = gfDance.x + 200; + // maskShader.frameUV = gfDance.frame.uv; + // gfDance.shader = maskShader; + + // gfDance.shader = swagShader.shader; + + // gfDance.shader = new TitleOutline(); + + add(logoBl); + + titleText = new FlxSprite(100, FlxG.height * 0.8); + titleText.frames = Paths.getSparrowAtlas('titleEnter'); + titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); + titleText.animation.addByPrefix('press', "ENTER PRESSED", 24); + titleText.antialiasing = true; + titleText.animation.play('idle'); + titleText.updateHitbox(); + // titleText.screenCenter(X); + add(titleText); + + credGroup = new FlxGroup(); + add(credGroup); + + textGroup = new FlxGroup(); + + blackScreen = bg.clone(); + credGroup.add(blackScreen); + credGroup.add(textGroup); + + // var atlasBullShit:FlxSprite = new FlxSprite(); + // atlasBullShit.frames = CoolUtil.fromAnimate(Paths.image('money'), Paths.file('images/money.json')); + // credGroup.add(atlasBullShit); + + ngSpr = new FlxSprite(0, FlxG.height * 0.52); + + if (FlxG.random.bool(1)) + { + ngSpr.loadGraphic(Paths.image('newgrounds_logo_classic')); + } + else if (FlxG.random.bool(30)) + { + ngSpr.loadGraphic(Paths.image('newgrounds_logo_animated'), true, 600); + ngSpr.animation.add('idle', [0, 1], 4); + ngSpr.animation.play('idle'); + ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.55)); + } + else + { + ngSpr.loadGraphic(Paths.image('newgrounds_logo')); + ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); + } + + add(ngSpr); + ngSpr.visible = false; + + ngSpr.updateHitbox(); + ngSpr.screenCenter(X); + ngSpr.antialiasing = true; + + FlxG.mouse.visible = false; + + if (initialized) skipIntro(); + else + initialized = true; + + if (FlxG.sound.music != null) FlxG.sound.music.onComplete = function() FlxG.switchState(new VideoState()); + } + + function getIntroTextShit():Array> + { + var fullText:String = Assets.getText(Paths.txt('introText')); + + var firstArray:Array = fullText.split('\n'); + var swagGoodArray:Array> = []; + + for (i in firstArray) + { + swagGoodArray.push(i.split('--')); + } + + return swagGoodArray; + } + + var transitioning:Bool = false; + + override function update(elapsed:Float) + { + #if HAS_PITCH + if (FlxG.keys.pressed.UP) FlxG.sound.music.pitch += 0.5 * elapsed; + + if (FlxG.keys.pressed.DOWN) FlxG.sound.music.pitch -= 0.5 * elapsed; + #end + + Conductor.update(); + + /* if (FlxG.onMobile) + { + if (gfDance != null) + { + gfDance.x = (FlxG.width / 2) + (FlxG.accelerometer.x * (FlxG.width / 2)); + // gfDance.y = (FlxG.height / 2) + (FlxG.accelerometer.y * (FlxG.height / 2)); + } + } + */ + if (FlxG.keys.justPressed.I) + { + FlxTween.tween(outlineShaderShit, {funnyX: 50, funnyY: 50}, 0.6, {ease: FlxEase.quartOut}); + } + if (FlxG.keys.pressed.D) outlineShaderShit.funnyX += 1; + // outlineShaderShit.xPos.value[0] += 1; + + if (FlxG.keys.justPressed.Y) + { + FlxTween.tween(FlxG.stage.window, {x: FlxG.stage.window.x + 300}, 1.4, {ease: FlxEase.quadInOut, type: PINGPONG, startDelay: 0.35}); + FlxTween.tween(FlxG.stage.window, {y: FlxG.stage.window.y + 100}, 0.7, {ease: FlxEase.quadInOut, type: PINGPONG}); + } + + /* + FlxG.watch.addQuick('cur display', FlxG.stage.window.display.id); + if (FlxG.keys.justPressed.Y) + { + // trace(FlxG.stage.window.display.name); + + if (FlxG.gamepads.firstActive != null) + { + trace(FlxG.gamepads.firstActive.model); + FlxG.gamepads.firstActive.id + } + else + trace('gamepad null'); + + // FlxG.stage.window.title = Std.string(FlxG.random.int(0, 20000)); + // FlxG.stage.window.setIcon(Image.fromFile('assets/images/icon16.png')); + // FlxG.stage.window.readPixels; + + if (FlxG.stage.window.width == Std.int(FlxG.stage.window.display.bounds.width)) + { + FlxG.stage.window.width = 1280; + FlxG.stage.window.height = 720; + FlxG.stage.window.y = 30; + } + else + { + FlxG.stage.window.width = Std.int(FlxG.stage.window.display.bounds.width); + FlxG.stage.window.height = Std.int(FlxG.stage.window.display.bounds.height); + FlxG.stage.window.x = Std.int(FlxG.stage.window.display.bounds.x); + FlxG.stage.window.y = Std.int(FlxG.stage.window.display.bounds.y); + } + } + */ + + #if debug + if (FlxG.keys.justPressed.EIGHT) FlxG.switchState(new CutsceneAnimTestState()); + #end + + if (FlxG.sound.music != null) Conductor.songPosition = FlxG.sound.music.time; + if (FlxG.keys.justPressed.F) FlxG.fullscreen = !FlxG.fullscreen; + + // do controls.PAUSE | controls.ACCEPT instead? + var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; + + if (FlxG.onMobile) + { + for (touch in FlxG.touches.list) + { + if (touch.justPressed) + { + FlxG.switchState(new FreeplayState()); + pressedEnter = true; + } + } + } + + var gamepad:FlxGamepad = FlxG.gamepads.lastActive; + + if (gamepad != null) + { + if (gamepad.justPressed.START) pressedEnter = true; + #if switch + if (gamepad.justPressed.B) pressedEnter = true; + #end + } + + // a faster intro thing lol! + if (pressedEnter && transitioning && skippedIntro) + { + FlxG.switchState(new MainMenuState()); + } + + if (pressedEnter && !transitioning && skippedIntro) + { + if (FlxG.sound.music != null) FlxG.sound.music.onComplete = null; + // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); + NGio.unlockMedal(60960); + // If it's Friday according to da clock + if (Date.now().getDay() == 5) NGio.unlockMedal(61034); + titleText.animation.play('press'); + FlxG.camera.flash(FlxColor.WHITE, 1); + FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); + transitioning = true; + + var targetState:FlxState = new MainMenuState(); + + #if newgrounds + if (!OutdatedSubState.leftState) + { + NGio.checkVersion(function(version) + { + // Check if version is outdated + var localVersion:String = "v" + Application.current.meta.get('version'); + var onlineVersion = version.split(" ")[0].trim(); + if (version.trim() != onlineVersion) + { + trace('OLD VERSION!'); + // targetState = new OutdatedSubState(); + } + else + { + // targetState = new MainMenuState(); + } + // REDO FOR ITCH/FINAL SHIT + }); + } + #end + new FlxTimer().start(2, function(tmr:FlxTimer) + { + // These assets are very unlikely to be used for the rest of gameplay, so it unloads them from cache/memory + // Saves about 50mb of RAM or so??? + Assets.cache.clear(Paths.image('gfDanceTitle')); + Assets.cache.clear(Paths.image('logoBumpin')); + Assets.cache.clear(Paths.image('titleEnter')); + // ngSpr?? + FlxG.switchState(targetState); + }); + // FlxG.sound.play(Paths.music('titleShoot'), 0.7); + } + if (pressedEnter && !skippedIntro && initialized) skipIntro(); + /* + #if web + if (!initialized && controls.ACCEPT) + { + // netStream.dispose(); + // FlxG.stage.removeChild(video); + + startIntro(); + skipIntro(); + } + #end + */ + + if (controls.UI_LEFT) swagShader.update(-elapsed * 0.1); + if (controls.UI_RIGHT) swagShader.update(elapsed * 0.1); + if (!cheatActive && skippedIntro) cheatCodeShit(); + super.update(elapsed); + } + + override function draw() + { + super.draw(); + + // if (gfDance != null) + // { + // trace(gfDance.frame.uv); + // maskShader.frameUV = gfDance.frame.uv; + // } + } + + var cheatArray:Array = [0x0001, 0x0010, 0x0001, 0x0010, 0x0100, 0x1000, 0x0100, 0x1000]; + var curCheatPos:Int = 0; + var cheatActive:Bool = false; + + function cheatCodeShit():Void + { + if (FlxG.keys.justPressed.ANY) + { + if (controls.NOTE_DOWN_P || controls.UI_DOWN_P) codePress(FlxDirectionFlags.DOWN); + if (controls.NOTE_UP_P || controls.UI_UP_P) codePress(FlxDirectionFlags.UP); + if (controls.NOTE_LEFT_P || controls.UI_LEFT_P) codePress(FlxDirectionFlags.LEFT); + if (controls.NOTE_RIGHT_P || controls.UI_RIGHT_P) codePress(FlxDirectionFlags.RIGHT); + } + } + + function codePress(input:Int) + { + if (input == cheatArray[curCheatPos]) + { + curCheatPos += 1; + if (curCheatPos >= cheatArray.length) startCheat(); + } + else + curCheatPos = 0; + + trace(input); + } + + function startCheat():Void + { + cheatActive = true; + + FlxG.sound.playMusic(Paths.music('tutorialTitle'), 1); + + var spec:SpectogramSprite = new SpectogramSprite(FlxG.sound.music); + add(spec); + + Conductor.forceBPM(190); + FlxG.camera.flash(FlxColor.WHITE, 1); + FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); + } + + function createCoolText(textArray:Array) + { + if (credGroup == null || textGroup == null) return; + + for (i in 0...textArray.length) + { + var money:AtlasText = new AtlasText(0, 0, textArray[i], AtlasFont.BOLD); + money.screenCenter(X); + money.y += (i * 60) + 200; + // credGroup.add(money); + textGroup.add(money); + } + } + + function addMoreText(text:String) + { + if (credGroup == null || textGroup == null) return; + + lime.ui.Haptic.vibrate(100, 100); + + var coolText:AtlasText = new AtlasText(0, 0, text.trim(), AtlasFont.BOLD); + coolText.screenCenter(X); + coolText.y += (textGroup.length * 60) + 200; + textGroup.add(coolText); + } + + function deleteCoolText() + { + if (credGroup == null || textGroup == null) return; + + while (textGroup.members.length > 0) + { + // credGroup.remove(textGroup.members[0], true); + textGroup.remove(textGroup.members[0], true); + } + } + + var isRainbow:Bool = false; + var skippedIntro:Bool = false; + + override function beatHit():Bool + { + // super.beatHit() returns false if a module cancelled the event. + if (!super.beatHit()) return false; + + if (!skippedIntro) + { + // FlxG.log.add(Conductor.currentBeat); + // if the user is draggin the window some beats will + // be missed so this is just to compensate + if (Conductor.currentBeat > lastBeat) + { + // TODO: Why does it perform ALL the previous steps each beat? + for (i in lastBeat...Conductor.currentBeat) + { + switch (i + 1) + { + case 1: + createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8r']); + case 3: + addMoreText('present'); + case 4: + deleteCoolText(); + case 5: + createCoolText(['In association', 'with']); + case 7: + addMoreText('newgrounds'); + if (ngSpr != null) ngSpr.visible = true; + case 8: + deleteCoolText(); + if (ngSpr != null) ngSpr.visible = false; + case 9: + createCoolText([curWacky[0]]); + case 11: + addMoreText(curWacky[1]); + case 12: + deleteCoolText(); + case 13: + addMoreText('Friday'); + case 14: + addMoreText('Night'); + case 15: + addMoreText('Funkin'); + case 16: + skipIntro(); + } + } + } + lastBeat = Conductor.currentBeat; + } + if (skippedIntro) + { + if (cheatActive && Conductor.currentBeat % 2 == 0) swagShader.update(0.125); + + if (logoBl != null && logoBl.animation != null) logoBl.animation.play('bump', true); + + danceLeft = !danceLeft; + + if (gfDance != null && gfDance.animation != null) + { + if (danceLeft) gfDance.animation.play('danceRight'); + else + gfDance.animation.play('danceLeft'); + } + } + + return true; + } + + function skipIntro():Void + { + if (!skippedIntro) + { + remove(ngSpr); + + FlxG.camera.flash(FlxColor.WHITE, 4); + remove(credGroup); + skippedIntro = true; + } + } } diff --git a/source/funkin/VideoState.hx b/source/funkin/VideoState.hx index d5954ccda..a169ce5af 100644 --- a/source/funkin/VideoState.hx +++ b/source/funkin/VideoState.hx @@ -10,93 +10,91 @@ import openfl.net.NetStream; class VideoState extends MusicBeatState { - var video:Video; - var netStream:NetStream; - private var overlay:Sprite; + var video:Video; + var netStream:NetStream; + var overlay:Sprite; - public static var seenVideo:Bool = false; + public static var seenVideo:Bool = false; - override function create() - { - super.create(); + override function create() + { + super.create(); - seenVideo = true; + seenVideo = true; - FlxG.save.data.seenVideo = true; - FlxG.save.flush(); + FlxG.save.data.seenVideo = true; + FlxG.save.flush(); - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); + if (FlxG.sound.music != null) FlxG.sound.music.stop(); - video = new Video(); - FlxG.addChildBelowMouse(video); + video = new Video(); + FlxG.addChildBelowMouse(video); - var netConnection = new NetConnection(); - netConnection.connect(null); + var netConnection = new NetConnection(); + netConnection.connect(null); - netStream = new NetStream(netConnection); - netStream.client = {onMetaData: client_onMetaData}; - netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError); - netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); - // netStream.addEventListener(NetStatusEvent.NET_STATUS); - netStream.play(Paths.file('music/kickstarterTrailer.mp4')); + netStream = new NetStream(netConnection); + netStream.client = {onMetaData: client_onMetaData}; + netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError); + netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); + // netStream.addEventListener(NetStatusEvent.NET_STATUS); + netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - overlay = new Sprite(); - overlay.graphics.beginFill(0, 0.5); - overlay.graphics.drawRect(0, 0, 1280, 720); - overlay.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); + overlay = new Sprite(); + overlay.graphics.beginFill(0, 0.5); + overlay.graphics.drawRect(0, 0, 1280, 720); + overlay.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); - overlay.buttonMode = true; - // FlxG.stage.addChild(overlay); - } + overlay.buttonMode = true; + // FlxG.stage.addChild(overlay); + } - override function update(elapsed:Float) - { - if (controls.ACCEPT) - finishVid(); + override function update(elapsed:Float) + { + if (controls.ACCEPT) finishVid(); - super.update(elapsed); - } + super.update(elapsed); + } - function finishVid():Void - { - netStream.dispose(); - FlxG.removeChild(video); + function finishVid():Void + { + netStream.dispose(); + FlxG.removeChild(video); - TitleState.initialized = false; - FlxG.switchState(new TitleState()); - } + TitleState.initialized = false; + FlxG.switchState(new TitleState()); + } - private function client_onMetaData(metaData:Dynamic) - { - video.attachNetStream(netStream); + function client_onMetaData(metaData:Dynamic) + { + video.attachNetStream(netStream); - video.width = video.videoWidth; - video.height = video.videoHeight; - // video. - } + video.width = video.videoWidth; + video.height = video.videoHeight; + // video. + } - private function netStream_onAsyncError(event:AsyncErrorEvent):Void - { - trace("Error loading video"); - } + function netStream_onAsyncError(event:AsyncErrorEvent):Void + { + trace("Error loading video"); + } - private function netConnection_onNetStatus(event:NetStatusEvent):Void - { - if (event.info.code == 'NetStream.Play.Complete') - { - finishVid(); - } + function netConnection_onNetStatus(event:NetStatusEvent):Void + { + if (event.info.code == 'NetStream.Play.Complete') + { + finishVid(); + } - trace(event.toString()); - } + trace(event.toString()); + } - private function overlay_onMouseDown(event:MouseEvent):Void - { - netStream.soundTransform.volume = 0.2; - netStream.soundTransform.pan = -1; - // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); + function overlay_onMouseDown(event:MouseEvent):Void + { + netStream.soundTransform.volume = 0.2; + netStream.soundTransform.pan = -1; + // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - FlxG.stage.removeChild(overlay); - } + FlxG.stage.removeChild(overlay); + } } diff --git a/source/funkin/VoicesGroup.hx b/source/funkin/VoicesGroup.hx index db31cb052..cf1014f29 100644 --- a/source/funkin/VoicesGroup.hx +++ b/source/funkin/VoicesGroup.hx @@ -7,147 +7,142 @@ import flixel.system.FlxSound; // when needed class VoicesGroup extends FlxTypedGroup { - public var time(get, set):Float; + public var time(get, set):Float; - public var volume(get, set):Float; + public var volume(get, set):Float; - public var pitch(get, set):Float; + public var pitch(get, set):Float; - // make it a group that you add to? - public function new() - { - super(); - } + // make it a group that you add to? + public function new() + { + super(); + } - // TODO: Remove this. - public static function build(song:String, ?files:Array = null):VoicesGroup - { - var result = new VoicesGroup(); + // TODO: Remove this. + public static function build(song:String, ?files:Array = null):VoicesGroup + { + var result = new VoicesGroup(); - if (files == null) - { - // Add an empty voice. - result.add(new FlxSound()); - return result; - } + if (files == null) + { + // Add an empty voice. + result.add(new FlxSound()); + return result; + } - for (sndFile in files) - { - var snd:FlxSound = new FlxSound().loadEmbedded(Paths.voices(song, '$sndFile')); - FlxG.sound.list.add(snd); // adds it to sound group for proper volumes - result.add(snd); // adds it to main group for other shit - } + for (sndFile in files) + { + var snd:FlxSound = new FlxSound().loadEmbedded(Paths.voices(song, '$sndFile')); + FlxG.sound.list.add(snd); // adds it to sound group for proper volumes + result.add(snd); // adds it to main group for other shit + } - return result; - } + return result; + } - /** - * Finds the largest deviation from the desired time inside this VoicesGroup. - * - * @param targetTime The time to check against. - * If none is provided, it checks the time of all members against the first member of this VoicesGroup. - * @return The largest deviation from the target time found. - */ - public function checkSyncError(?targetTime:Float):Float - { - var error:Float = 0; + /** + * Finds the largest deviation from the desired time inside this VoicesGroup. + * + * @param targetTime The time to check against. + * If none is provided, it checks the time of all members against the first member of this VoicesGroup. + * @return The largest deviation from the target time found. + */ + public function checkSyncError(?targetTime:Float):Float + { + var error:Float = 0; - forEachAlive(function(snd) - { - if (targetTime == null) - targetTime = snd.time; - else - { - var diff:Float = snd.time - targetTime; - if (Math.abs(diff) > Math.abs(error)) - error = diff; - } - }); - return error; - } + forEachAlive(function(snd) + { + if (targetTime == null) targetTime = snd.time; + else + { + var diff:Float = snd.time - targetTime; + if (Math.abs(diff) > Math.abs(error)) error = diff; + } + }); + return error; + } - // prob a better / cleaner way to do all these forEach stuff? - public function pause() - { - forEachAlive(function(snd) - { - snd.pause(); - }); - } + // prob a better / cleaner way to do all these forEach stuff? + public function pause() + { + forEachAlive(function(snd) + { + snd.pause(); + }); + } - public function play() - { - forEachAlive(function(snd) - { - snd.play(); - }); - } + public function play() + { + forEachAlive(function(snd) + { + snd.play(); + }); + } - public function stop() - { - forEachAlive(function(snd) - { - snd.stop(); - }); - } + public function stop() + { + forEachAlive(function(snd) + { + snd.stop(); + }); + } - function get_time():Float - { - if (getFirstAlive() != null) - return getFirstAlive().time; - else - return 0; - } + function get_time():Float + { + if (getFirstAlive() != null) return getFirstAlive().time; + else + return 0; + } - function set_time(time:Float):Float - { - forEachAlive(function(snd) - { - // account for different offsets per sound? - snd.time = time; - }); + function set_time(time:Float):Float + { + forEachAlive(function(snd) + { + // account for different offsets per sound? + snd.time = time; + }); - return time; - } + return time; + } - function get_volume():Float - { - if (getFirstAlive() != null) - return getFirstAlive().volume; - else - return 1; - } + function get_volume():Float + { + if (getFirstAlive() != null) return getFirstAlive().volume; + else + return 1; + } - // in PlayState, adjust the code so that it only mutes the player1 vocal tracks? - function set_volume(volume:Float):Float - { - forEachAlive(function(snd) - { - snd.volume = volume; - }); + // in PlayState, adjust the code so that it only mutes the player1 vocal tracks? + function set_volume(volume:Float):Float + { + forEachAlive(function(snd) + { + snd.volume = volume; + }); - return volume; - } + return volume; + } - function get_pitch():Float - { - #if FLX_PITCH - if (getFirstAlive() != null) - return getFirstAlive().pitch; - else - #end - return 1; - } + function get_pitch():Float + { + #if FLX_PITCH + if (getFirstAlive() != null) return getFirstAlive().pitch; + else + #end + return 1; + } - function set_pitch(val:Float):Float - { - #if FLX_PITCH - trace('Setting audio pitch to ' + val); - forEachAlive(function(snd) - { - snd.pitch = val; - }); - #end - return val; - } + function set_pitch(val:Float):Float + { + #if FLX_PITCH + trace('Setting audio pitch to ' + val); + forEachAlive(function(snd) + { + snd.pitch = val; + }); + #end + return val; + } } diff --git a/source/funkin/animate/AnimTestStage.hx b/source/funkin/animate/AnimTestStage.hx index 26e1fceb2..0b2291ee4 100644 --- a/source/funkin/animate/AnimTestStage.hx +++ b/source/funkin/animate/AnimTestStage.hx @@ -6,31 +6,31 @@ import flixel.addons.display.FlxGridOverlay; class AnimTestStage extends FlxState { - var tl:AnimateTimeline; - var swag:FlxAnimate; + var tl:AnimateTimeline; + var swag:FlxAnimate; - override function create() - { - var bg:FlxSprite = FlxGridOverlay.create(32, 32); - add(bg); - bg.scrollFactor.set(); + override function create() + { + var bg:FlxSprite = FlxGridOverlay.create(32, 32); + add(bg); + bg.scrollFactor.set(); - swag = new FlxAnimate(200, 200); - add(swag); + swag = new FlxAnimate(200, 200); + add(swag); - tl = new AnimateTimeline(Paths.file('images/tightBarsLol/Animation.json')); - add(tl); + tl = new AnimateTimeline(Paths.file('images/tightBarsLol/Animation.json')); + add(tl); - super.create(); - } + super.create(); + } - override function update(elapsed:Float) - { - tl.curFrame = swag.daFrame; + override function update(elapsed:Float) + { + tl.curFrame = swag.daFrame; - CoolUtil.mouseWheelZoom(); - CoolUtil.mouseCamDrag(); + CoolUtil.mouseWheelZoom(); + CoolUtil.mouseCamDrag(); - super.update(elapsed); - } + super.update(elapsed); + } } diff --git a/source/funkin/animate/AnimateTimeline.hx b/source/funkin/animate/AnimateTimeline.hx index 27f70f7ae..f5831d199 100644 --- a/source/funkin/animate/AnimateTimeline.hx +++ b/source/funkin/animate/AnimateTimeline.hx @@ -11,65 +11,64 @@ import lime.utils.Assets; class AnimateTimeline extends FlxTypedGroup { - // var coolParsed:Parsed; - var playhead:FlxSprite; + // var coolParsed:Parsed; + var playhead:FlxSprite; - public var curFrame(default, set):Int; + public var curFrame(default, set):Int; - function set_curFrame(frm:Int):Int - { - if (playhead != null) - playhead.x = 5 + (frm * 12) + (12 * 5); - return frm; - } + function set_curFrame(frm:Int):Int + { + if (playhead != null) playhead.x = 5 + (frm * 12) + (12 * 5); + return frm; + } - var hudCamShit:FlxCamera; + var hudCamShit:FlxCamera; - public function new(parsed:String) - { - super(); + public function new(parsed:String) + { + super(); - /* hudCamShit = new FlxCamera(); - hudCamShit.bgColor = FlxColor.TRANSPARENT; - FlxG.cameras.add(hudCamShit, false); + /* hudCamShit = new FlxCamera(); + hudCamShit.bgColor = FlxColor.TRANSPARENT; + FlxG.cameras.add(hudCamShit, false); - playhead = new FlxSprite(0, -12).makeGraphic(2, 10, FlxColor.MAGENTA); - add(playhead); + playhead = new FlxSprite(0, -12).makeGraphic(2, 10, FlxColor.MAGENTA); + add(playhead); - hudCamShit.follow(playhead); - hudCamShit.setScrollBounds(0, null, -14, null); + hudCamShit.follow(playhead); + hudCamShit.setScrollBounds(0, null, -14, null); - curFrame = 0; + curFrame = 0; - coolParsed = cast Json.parse(Assets.getText(parsed)); + coolParsed = cast Json.parse(Assets.getText(parsed)); - var layerNum:Int = 0; - for (layer in coolParsed.AN.TL.L) - { - var frameNum:Int = 0; + var layerNum:Int = 0; + for (layer in coolParsed.AN.TL.L) + { + var frameNum:Int = 0; - for (frame in layer.FR) - { - var coolFrame:TimelineFrame = new TimelineFrame((frame.I * 12) + 12 * 5, layerNum * 12, frame.DU, frame); - add(coolFrame); - frameNum++; - } + for (frame in layer.FR) + { + var coolFrame:TimelineFrame = new TimelineFrame((frame.I * 12) + 12 * 5, layerNum * 12, frame.DU, frame); + add(coolFrame); + frameNum++; + } - var layerName:FlxText = new FlxText(0, layerNum * 12, 0, layer.LN, 10); - layerName.color = FlxColor.PURPLE; - layerName.scrollFactor.x = 0; + var layerName:FlxText = new FlxText(0, layerNum * 12, 0, layer.LN, 10); + layerName.color = FlxColor.PURPLE; + layerName.scrollFactor.x = 0; - var layerBG:FlxSprite = new FlxSprite(0, layerNum * 12).makeGraphic(12 * 4, 12); - layerBG.scrollFactor.x = 0; + var layerBG:FlxSprite = new FlxSprite(0, layerNum * 12).makeGraphic(12 * 4, 12); + layerBG.scrollFactor.x = 0; - add(layerBG); - add(layerName); + add(layerBG); + add(layerName); - layerNum++; - } - + layerNum++; + } + - this.cameras = [hudCamShit]; - */ - } + this.cameras = [hudCamShit]; + */ + } } diff --git a/source/funkin/animate/FlxAnimate.hx b/source/funkin/animate/FlxAnimate.hx index 607776275..1a6d3dbad 100644 --- a/source/funkin/animate/FlxAnimate.hx +++ b/source/funkin/animate/FlxAnimate.hx @@ -21,271 +21,265 @@ import openfl.geom.Rectangle; class FlxAnimate extends FlxSymbol { - // var myAnim:Animation; - // var animBitmap:BitmapData; - var jsonAnim:AnimJson; + // var myAnim:Animation; + // var animBitmap:BitmapData; + var jsonAnim:AnimJson; - var sprGrp:FlxTypedGroup; + var sprGrp:FlxTypedGroup; - public function new(x:Float, y:Float) - { - super(x, y); + public function new(x:Float, y:Float) + { + super(x, y); - sprGrp = new FlxTypedGroup(); + sprGrp = new FlxTypedGroup(); - var tests:Array = ['tightBarsLol', 'tightestBars']; + var tests:Array = ['tightBarsLol', 'tightestBars']; - var folder:String = tests[1]; + var folder:String = tests[1]; - frames = FlxAnimate.fromAnimate(Paths.file('images/' + folder + "/spritemap1.png"), Paths.file('images/$folder/spritemap1.json')); + frames = FlxAnimate.fromAnimate(Paths.file('images/' + folder + "/spritemap1.png"), Paths.file('images/$folder/spritemap1.json')); - jsonAnim = cast CoolUtil.coolJSON(Assets.getText(Paths.file('images/$folder/Animation.json'))); - ParseAnimate.generateSymbolmap(jsonAnim.SD.S); - ParseAnimate.resetFrameList(); + jsonAnim = cast CoolUtil.coolJSON(Assets.getText(Paths.file('images/$folder/Animation.json'))); + ParseAnimate.generateSymbolmap(jsonAnim.SD.S); + ParseAnimate.resetFrameList(); - ParseAnimate.parseTimeline(jsonAnim.AN.TL, 0, 0); + ParseAnimate.parseTimeline(jsonAnim.AN.TL, 0, 0); - generateSpriteShit(); + generateSpriteShit(); - /* var folder:String = 'tightestBars'; - coolParse = cast Json.parse(Assets.getText(Paths.file('images/' + folder + '/Animation.json'))); + /* var folder:String = 'tightestBars'; + coolParse = cast Json.parse(Assets.getText(Paths.file('images/' + folder + '/Animation.json'))); - // reverses the layers, for proper rendering! - coolParse.AN.TL.L.reverse(); - super(x, y, coolParse); + // reverses the layers, for proper rendering! + coolParse.AN.TL.L.reverse(); + super(x, y, coolParse); - frames = FlxAnimate.fromAnimate(Paths.file('images/' + folder + '/spritemap1.png'), Paths.file('images/' + folder + '/spritemap1.json')); - */ + frames = FlxAnimate.fromAnimate(Paths.file('images/' + folder + '/spritemap1.png'), Paths.file('images/' + folder + '/spritemap1.json')); + */ - // frames - } + // frames + } - override function draw() - { - // having this commented out fixes some wacky scaling bullshit? - // or fixes drawing it twice? - // super.draw(); + override function draw() + { + // having this commented out fixes some wacky scaling bullshit? + // or fixes drawing it twice? + // super.draw(); - // renderFrame(coolParse.AN.TL, coolParse, true); + // renderFrame(coolParse.AN.TL, coolParse, true); - actualFrameRender(); - } + actualFrameRender(); + } - /** - * Puts all the needed sprites into a FlxTypedGroup, and properly recycles them? - **/ - function generateSpriteShit() - { - sprGrp.kill(); // kills group, maybe dont need to do this one so broadly? ehh whatev + /** + * Puts all the needed sprites into a FlxTypedGroup, and properly recycles them? + **/ + function generateSpriteShit() + { + sprGrp.kill(); // kills group, maybe dont need to do this one so broadly? ehh whatev - for (frameSorted in ParseAnimate.frameList) - { - for (i in frameSorted) - { - // instead of making them every frame, regenerate when needed? - var spr:FlxSymbol = sprGrp.recycle(FlxSymbol); // redo this to recycle from a list later - spr.frames = frames; - spr.frame = spr.frames.getByName(i.frameName); // this one is fine - spr.updateHitbox(); + for (frameSorted in ParseAnimate.frameList) + { + for (i in frameSorted) + { + // instead of making them every frame, regenerate when needed? + var spr:FlxSymbol = sprGrp.recycle(FlxSymbol); // redo this to recycle from a list later + spr.frames = frames; + spr.frame = spr.frames.getByName(i.frameName); // this one is fine + spr.updateHitbox(); - // move this? wont work here! - if (FlxG.keys.justPressed.I) - { - trace(i.frameName); - trace(i.depthString); - // trace("random lol: " + i.randomLol); - } + // move this? wont work here! + if (FlxG.keys.justPressed.I) + { + trace(i.frameName); + trace(i.depthString); + // trace("random lol: " + i.randomLol); + } - // cuz its in group, gets a lil fuckie when animated, need to go thru and properly reset each thing for shit like matrix! - // merely resets the matrix to normal ass one! - spr.transformMatrix.identity(); - spr.setPosition(); + // cuz its in group, gets a lil fuckie when animated, need to go thru and properly reset each thing for shit like matrix! + // merely resets the matrix to normal ass one! + spr.transformMatrix.identity(); + spr.setPosition(); - /* for (swagMatrix in i.matrixArray) - { - var alsoSwag:FlxMatrix = new FlxMatrix(swagMatrix[0], swagMatrix[1], swagMatrix[4], swagMatrix[5], swagMatrix[12], swagMatrix[13]); - spr.matrixExposed = true; - spr.transformMatrix.concat(alsoSwag); - }*/ + /* for (swagMatrix in i.matrixArray) + { + var alsoSwag:FlxMatrix = new FlxMatrix(swagMatrix[0], swagMatrix[1], swagMatrix[4], swagMatrix[5], swagMatrix[12], swagMatrix[13]); + spr.matrixExposed = true; + spr.transformMatrix.concat(alsoSwag); + }*/ - // i.fullMatrix.concat + // i.fullMatrix.concat - spr.matrixExposed = true; + spr.matrixExposed = true; - // trace(i.fullMatrix); + // trace(i.fullMatrix); - if (i.fullMatrix.a < 0) - { - trace('negative?'); - trace(i.fullMatrix); - } + if (i.fullMatrix.a < 0) + { + trace('negative?'); + trace(i.fullMatrix); + } - spr.transformMatrix.concat(i.fullMatrix); + spr.transformMatrix.concat(i.fullMatrix); - if (i.fullMatrix.a < 0) - { - trace('negative?'); - trace(i.fullMatrix); - trace(spr.transformMatrix); - } + if (i.fullMatrix.a < 0) + { + trace('negative?'); + trace(i.fullMatrix); + trace(spr.transformMatrix); + } - // trace(spr.transformMatrix); + // trace(spr.transformMatrix); - spr.origin.set(); + spr.origin.set(); - /* for (trpShit in i.trpArray) - { - spr.origin.x -= trpShit[0]; - spr.origin.y -= trpShit[1]; - } - */ - // spr.alpha = 0.3; + /* for (trpShit in i.trpArray) + { + spr.origin.x -= trpShit[0]; + spr.origin.y -= trpShit[1]; + } + */ + // spr.alpha = 0.3; - spr.antialiasing = true; - sprGrp.add(spr); - spr.alpha = 0.5; + spr.antialiasing = true; + sprGrp.add(spr); + spr.alpha = 0.5; - /* if (i == "0225") - { - trace('FUNNY MATRIX!'); - trace(spr._matrix); - trace("\n\n MATRIX MAP"); - for (m in ParseAnimate.matrixMap.get("0225")) - { - trace(m); - } + /* if (i == "0225") + { + trace('FUNNY MATRIX!'); + trace(spr._matrix); + trace("\n\n MATRIX MAP"); + for (m in ParseAnimate.matrixMap.get("0225")) + { + trace(m); + } - trace('\n\n'); - }*/ - } - } + trace('\n\n'); + }*/ + } + } - // trace(sprGrp.length); - } + // trace(sprGrp.length); + } - // fix render order of ALL layers! - // seperate frameList into layers - // go thru animate file to see how it should all be ordered - // per frame symbol stuff to fix lip sync (in ParseAnimate?) - // definitely need to dig through Animate.json stuff - // something with TRP stuff, look through tighterBars (GF scene) - // redo map stuff incase there's multiple assets - // ONE CENTRAL THING FOR THIS DUMBASS BULLSHIT - // sorted framelist put it all in there, then make i actually mean something + // fix render order of ALL layers! + // seperate frameList into layers + // go thru animate file to see how it should all be ordered + // per frame symbol stuff to fix lip sync (in ParseAnimate?) + // definitely need to dig through Animate.json stuff + // something with TRP stuff, look through tighterBars (GF scene) + // redo map stuff incase there's multiple assets + // ONE CENTRAL THING FOR THIS DUMBASS BULLSHIT + // sorted framelist put it all in there, then make i actually mean something - function actualFrameRender() - { - sprGrp.draw(); - } + function actualFrameRender() + { + sprGrp.draw(); + } - // notes to self - // account for different layers - var playingAnim:Bool = false; - var frameTickTypeShit:Float = 0; - var animFrameRate:Int = 24; + // notes to self + // account for different layers + var playingAnim:Bool = false; + var frameTickTypeShit:Float = 0; + var animFrameRate:Int = 24; - // redo all the matrix animation stuff + // redo all the matrix animation stuff - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (FlxG.keys.justPressed.SPACE) - playingAnim = !playingAnim; + if (FlxG.keys.justPressed.SPACE) playingAnim = !playingAnim; - if (playingAnim) - { - frameTickTypeShit += elapsed; + if (playingAnim) + { + frameTickTypeShit += elapsed; - // prob fix this framerate thing for higher framerates? - if (frameTickTypeShit >= 1 / 24) - { - changeFrame(1); - frameTickTypeShit = 0; - ParseAnimate.resetFrameList(); - ParseAnimate.parseTimeline(jsonAnim.AN.TL, 0, daFrame); + // prob fix this framerate thing for higher framerates? + if (frameTickTypeShit >= 1 / 24) + { + changeFrame(1); + frameTickTypeShit = 0; + ParseAnimate.resetFrameList(); + ParseAnimate.parseTimeline(jsonAnim.AN.TL, 0, daFrame); - generateSpriteShit(); - } - } + generateSpriteShit(); + } + } - if (FlxG.keys.justPressed.RIGHT) - { - changeFrame(1); + if (FlxG.keys.justPressed.RIGHT) + { + changeFrame(1); - ParseAnimate.resetFrameList(); - ParseAnimate.parseTimeline(jsonAnim.AN.TL, 0, daFrame); + ParseAnimate.resetFrameList(); + ParseAnimate.parseTimeline(jsonAnim.AN.TL, 0, daFrame); - generateSpriteShit(); - } - if (FlxG.keys.justPressed.LEFT) - changeFrame(-1); - } + generateSpriteShit(); + } + if (FlxG.keys.justPressed.LEFT) changeFrame(-1); + } - /** - * PARSES THE 'spritemap1.png' or whatever into a FlxAtlasFrames!!! - */ - public static function fromAnimate(Source:FlxGraphicAsset, Description:String):FlxAtlasFrames - { - var graphic:FlxGraphic = FlxG.bitmap.add(Source); - if (graphic == null) - return null; + /** + * PARSES THE 'spritemap1.png' or whatever into a FlxAtlasFrames!!! + */ + public static function fromAnimate(Source:FlxGraphicAsset, Description:String):FlxAtlasFrames + { + var graphic:FlxGraphic = FlxG.bitmap.add(Source); + if (graphic == null) return null; - var frames:FlxAtlasFrames = FlxAtlasFrames.findFrame(graphic); - if (frames != null) - return frames; + var frames:FlxAtlasFrames = FlxAtlasFrames.findFrame(graphic); + if (frames != null) return frames; - if (graphic == null || Description == null) - return null; + if (graphic == null || Description == null) return null; - frames = new FlxAtlasFrames(graphic); + frames = new FlxAtlasFrames(graphic); - var data:Spritemap; + var data:Spritemap; - var json:String = Description; + var json:String = Description; - // trace(json); + // trace(json); - var funnyJson:Dynamic = {}; - if (Assets.exists(json)) - funnyJson = JaySon.parseFile(json); + var funnyJson:Dynamic = {}; + if (Assets.exists(json)) funnyJson = JaySon.parseFile(json); - // trace(json); + // trace(json); - // data = c + // data = c - data = cast funnyJson; + data = cast funnyJson; - for (sprite in data.ATLAS.SPRITES) - { - // probably nicer way to do this? Oh well - var swagSprite:Sprite = sprite.SPRITE; + for (sprite in data.ATLAS.SPRITES) + { + // probably nicer way to do this? Oh well + var swagSprite:Sprite = sprite.SPRITE; - var rect = FlxRect.get(swagSprite.x, swagSprite.y, swagSprite.w, swagSprite.h); + var rect = FlxRect.get(swagSprite.x, swagSprite.y, swagSprite.w, swagSprite.h); - var size = new Rectangle(0, 0, rect.width, rect.height); + var size = new Rectangle(0, 0, rect.width, rect.height); - var offset = FlxPoint.get(-size.left, -size.top); - var sourceSize = FlxPoint.get(size.width, size.height); + var offset = FlxPoint.get(-size.left, -size.top); + var sourceSize = FlxPoint.get(size.width, size.height); - frames.addAtlasFrame(rect, sourceSize, offset, swagSprite.name); - } + frames.addAtlasFrame(rect, sourceSize, offset, swagSprite.name); + } - return frames; - } + return frames; + } } // handy json function that has some hashlink fix, see the thing in CoolUtils file to see the link / where i stole it from class JaySon { - public static function parseFile(name:String) - { - var cont = Assets.getText(name); - function is(n:Int, what:Int) - return cont.charCodeAt(n) == what; - return JsonParser.parse(cont.substr(if (is(0, 65279)) /// looks like a HL target, skipping only first character here: - 1 else if (is(0, 239) && is(1, 187) && is(2, 191)) /// it seems to be Neko or PHP, start from position 3: - 3 else /// all other targets, that prepare the UTF string correctly - 0)); - } + public static function parseFile(name:String) + { + var cont = Assets.getText(name); + function is(n:Int, what:Int) + return cont.charCodeAt(n) == what; + return JsonParser.parse(cont.substr(if (is(0, 65279)) /// looks like a HL target, skipping only first character here: + 1 else if (is(0, 239) && is(1, 187) && is(2, 191)) /// it seems to be Neko or PHP, start from position 3: + 3 else /// all other targets, that prepare the UTF string correctly + 0)); + } } diff --git a/source/funkin/animate/FlxSymbol.hx b/source/funkin/animate/FlxSymbol.hx index 3e2fffd84..cd01b4937 100644 --- a/source/funkin/animate/FlxSymbol.hx +++ b/source/funkin/animate/FlxSymbol.hx @@ -20,63 +20,62 @@ import openfl.geom.Matrix; class FlxSymbol extends FlxSprite { - // Loop types shit - public static inline var LOOP:String = 'LP'; - public static inline var PLAY_ONCE:String = 'PO'; - public static inline var SINGLE_FRAME:String = 'SF'; + // Loop types shit + public static inline var LOOP:String = 'LP'; + public static inline var PLAY_ONCE:String = 'PO'; + public static inline var SINGLE_FRAME:String = 'SF'; - public var transformMatrix:Matrix = new Matrix(); - public var daLoopType:String = 'LP'; // LP by default, is set below!!! + public var transformMatrix:Matrix = new Matrix(); + public var daLoopType:String = 'LP'; // LP by default, is set below!!! - /** - * Bool flag showing whether transformMatrix is used for rendering or not. - * False by default, which means that transformMatrix isn't used for rendering - */ - public var matrixExposed:Bool = true; + /** + * Bool flag showing whether transformMatrix is used for rendering or not. + * False by default, which means that transformMatrix isn't used for rendering + */ + public var matrixExposed:Bool = true; - public function new(x:Float, y:Float) - { - super(x, y); - } + public function new(x:Float, y:Float) + { + super(x, y); + } - public var daFrame:Int = 0; + public var daFrame:Int = 0; - function changeFrame(frameChange:Int = 0):Void - { - daFrame += frameChange; - } + function changeFrame(frameChange:Int = 0):Void + { + daFrame += frameChange; + } - /** - * custom "homemade" (nabbed from FlxSkewSprite) draw function, to make having a matrix transform slightly - * less painful - */ - override function drawComplex(camera:FlxCamera):Void - { - _frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY()); - _matrix.translate(-origin.x, -origin.y); - _matrix.scale(scale.x, scale.y); + /** + * custom "homemade" (nabbed from FlxSkewSprite) draw function, to make having a matrix transform slightly + * less painful + */ + override function drawComplex(camera:FlxCamera):Void + { + _frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY()); + _matrix.translate(-origin.x, -origin.y); + _matrix.scale(scale.x, scale.y); - if (matrixExposed) - { - _matrix.concat(transformMatrix); - } + if (matrixExposed) + { + _matrix.concat(transformMatrix); + } - if (bakedRotationAngle <= 0) - { - updateTrig(); + if (bakedRotationAngle <= 0) + { + updateTrig(); - if (angle != 0) - _matrix.rotateWithTrig(_cosAngle, _sinAngle); - } + if (angle != 0) _matrix.rotateWithTrig(_cosAngle, _sinAngle); + } - _point.addPoint(origin); - _matrix.translate(_point.x, _point.y); + _point.addPoint(origin); + _matrix.translate(_point.x, _point.y); - if (isPixelPerfectRender(camera)) - { - _matrix.tx = Math.floor(_matrix.tx); - _matrix.ty = Math.floor(_matrix.ty); - } - camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader); - } + if (isPixelPerfectRender(camera)) + { + _matrix.tx = Math.floor(_matrix.tx); + _matrix.ty = Math.floor(_matrix.ty); + } + camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader); + } } diff --git a/source/funkin/animate/ParseAnimate.hx b/source/funkin/animate/ParseAnimate.hx index c41aba0f7..9375ed47b 100644 --- a/source/funkin/animate/ParseAnimate.hx +++ b/source/funkin/animate/ParseAnimate.hx @@ -15,503 +15,503 @@ import sys.io.File; */ class ParseAnimate { - // make list of frames needed to render (with ASI) - // make GIANT list of all the frames ever and have them in order? - public static var symbolMap:Map = new Map(); - public static var actualSprites:Map = new Map(); - - private var _atlas:Map; - private var _symbolData:Map; - private var _defaultSymbolName:String; - - public function new(data:AnimJson, atlas:Spritemap) - { - // bitmap data could prob be instead - // this code is mostly nabbed from https://github.com/miltoncandelero/OpenFLAnimateAtlas/blob/master/Source/animateatlas/displayobject/SpriteAnimationLibrary.hx - parseAnimationData(data); - parseAtlasData(atlas); - } - - private function parseAnimationData(data:AnimJson):Void - { - _symbolData = new Map(); - - var symbols = data.SD.S; - for (symbol in symbols) - _symbolData[symbol.SN] = preprocessSymbolData(symbol); - - var defaultSymbol:Symbol = preprocessSymbolData(data.AN); - _defaultSymbolName = defaultSymbol.SN; - _symbolData.set(_defaultSymbolName, defaultSymbol); - } - - // at little redundant, does exactly the same thing as genSpritemap() - private function parseAtlasData(atlas:Spritemap):Void - { - _atlas = new Map(); - if (atlas.ATLAS != null && atlas.ATLAS.SPRITES != null) - { - for (s in atlas.ATLAS.SPRITES) - _atlas.set(s.SPRITE.name, s.SPRITE); - } - } - - /** - * Not used, was used for testing stuff though! - */ - public static function init() - { - // Main.gids - var folder:String = 'tightestBars'; - - // var spritemap:Spritemap = - // var spritemap:Spritemap = genSpritemap('test/$folder/spritemap1.json'); - - actualSprites = genSpritemap('test/$folder/spritemap1.json'); - - var animation:AnimJson = cast CoolUtil.coolJSON(Assets.getText('src/$folder/Animation.json')); - - generateSymbolmap(animation.SD.S); - - trace("\n\nANIMATION SHIT\n"); - - var timelineLength:Int = 0; - for (lyr in animation.AN.TL.L) - timelineLength = Std.int(Math.max(lyr.FR.length, timelineLength)); - - var content:String = animation.AN.TL.L[0].LN; - content += "TOTAL FRAMES NEEDED: " + timelineLength + "\n"; - - for (frm in 0...timelineLength) - { - trace('FRAME NUMBER ' + frm); - try - { - parseTimeline(animation.AN.TL, 1, frm); - content += 'Good write on frame: ' + frm + "\n"; - } - catch (e) - { - content += "BAD WRITE : " + frm + "\n"; - content += "\t" + e + "\n"; - trace(e); - } - - // File.saveContent("output.txt", content); - } - - parseTimeline(animation.AN.TL, 1, 0); - trace(actualSprites); - } - - /** - * a MAP of SPRITES, not to be confused with Spritemap... lol - */ - public static function genSpritemap(json:String):Map - { - var sprShitty:Spritemap = cast CoolUtil.coolJSON(json); - var sprMap:Map = new Map(); - - for (spr in sprShitty.ATLAS.SPRITES) - sprMap.set(spr.SPRITE.name, spr.SPRITE); - return sprMap; - } - - // should change dis to all private? - public static function generateSymbolmap(symbols:Array) - { - for (symbol in symbols) - { - // trace(symbol.SN + "has: " + symbol.TL.L.length + " LAYERS"); - - symbolMap.set(symbol.SN, symbol); - // parseTimeline(symbol.TL); - } - } - - public static function preprocessSymbolData(anim:Symbol):Symbol - { - var timelineData:Timeline = anim.TL; - var layerData:Array = timelineData.L; - - if (!timelineData.sortedForRender) - { - timelineData.sortedForRender = true; - layerData.reverse(); - } - - for (layerStuff in layerData) - { - var frames:Array = layerStuff.FR; - - for (frame in frames) - { - var elements:Array = frame.E; - for (e in 0...elements.length) - { - var element:Element = elements[e]; - if (element.ASI != null) - { - element = elements[e] = { - SI: { - SN: "ATLAS_SYMBOL_SPRITE", - LP: "LP", - TRP: {x: 0, y: 0}, - M3D: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], - FF: 0, - ST: "G", - ASI: element.ASI - } - } - } - } - } - } - - return anim; - } - - public static var curLoopType:String; - - /** - * Stuff for debug parsing - */ - public static var depthTypeBeat:String = ""; - - /** - * Array of bullshit that will eventually be RENDERED by whoever wanna use it! - */ - public static var frameList:Array> = []; - - // for loop stuf - - /** - * Similar to frameList, keeps track of shit according to framess? - * That amount of arrays within arrays is fuckin dumb - * but innermost array is basically just x and y value, cuz im dum - */ - public static var matrixHelp:Array>> = []; - - public static var trpHelpIDK:Array>> = []; - - public static var loopedFrameShit:Int = 0; - - public static var funnyMatrix:Matrix = new Matrix(); - public static var matrixFlipper:Array = []; - - // clean up all the crazy ass arrays - - public static function resetFrameList() - { - // funnyMatrix.identity(); - - frameList = []; - frameList.push([]); - matrixHelp = []; - matrixHelp.push([]); - - trpHelpIDK = []; - trpHelpIDK.push([]); - } - - public static var isFlipped:Bool = false; - - public static function parseTimeline(TL:Timeline, tabbed:Int = 0, ?frameInput:Int) - { - var strTab:String = ""; - for (i in 0...tabbed) - strTab += '\t'; - - for (layer in TL.L) - { - var frameArray:Array = []; - var frameMap:Map = new Map(); - - for (frms in layer.FR) - { - for (i in 0...frms.DU) - frameArray.push(frms.I); - - frameMap.set(frms.I, frms); - } - - if (frameInput == null) - frameInput = 0; - - var oldFrm:Int = frameInput; - /* - if (curLoopType == "SF") - { - trace(layer.LN); - - trace(frameArray); - trace(frameInput); - trace(curLoopType); - }*/ - - if (curLoopType == "LP") - frameInput = frameArray[frameInput % frameArray.length]; - else if (curLoopType == "SF") - { - frameInput = frameArray[loopedFrameShit]; - - // see what happens when something has more than 2 layer? - // single frame stuff isn't fully implemented - } - else - frameInput = frameArray[frameInput]; + // make list of frames needed to render (with ASI) + // make GIANT list of all the frames ever and have them in order? + public static var symbolMap:Map = new Map(); + public static var actualSprites:Map = new Map(); + + var _atlas:Map; + var _symbolData:Map; + var _defaultSymbolName:String; + + public function new(data:AnimJson, atlas:Spritemap) + { + // bitmap data could prob be instead + // this code is mostly nabbed from https://github.com/miltoncandelero/OpenFLAnimateAtlas/blob/master/Source/animateatlas/displayobject/SpriteAnimationLibrary.hx + parseAnimationData(data); + parseAtlasData(atlas); + } + + function parseAnimationData(data:AnimJson):Void + { + _symbolData = new Map(); + + var symbols = data.SD.S; + for (symbol in symbols) + _symbolData[symbol.SN] = preprocessSymbolData(symbol); + + var defaultSymbol:Symbol = preprocessSymbolData(data.AN); + _defaultSymbolName = defaultSymbol.SN; + _symbolData.set(_defaultSymbolName, defaultSymbol); + } + + // at little redundant, does exactly the same thing as genSpritemap() + function parseAtlasData(atlas:Spritemap):Void + { + _atlas = new Map(); + if (atlas.ATLAS != null && atlas.ATLAS.SPRITES != null) + { + for (s in atlas.ATLAS.SPRITES) + _atlas.set(s.SPRITE.name, s.SPRITE); + } + } + + /** + * Not used, was used for testing stuff though! + */ + public static function init() + { + // Main.gids + var folder:String = 'tightestBars'; + + // var spritemap:Spritemap = + // var spritemap:Spritemap = genSpritemap('test/$folder/spritemap1.json'); + + actualSprites = genSpritemap('test/$folder/spritemap1.json'); + + var animation:AnimJson = cast CoolUtil.coolJSON(Assets.getText('src/$folder/Animation.json')); + + generateSymbolmap(animation.SD.S); + + trace("\n\nANIMATION SHIT\n"); + + var timelineLength:Int = 0; + for (lyr in animation.AN.TL.L) + timelineLength = Std.int(Math.max(lyr.FR.length, timelineLength)); + + var content:String = animation.AN.TL.L[0].LN; + content += "TOTAL FRAMES NEEDED: " + timelineLength + "\n"; + + for (frm in 0...timelineLength) + { + trace('FRAME NUMBER ' + frm); + try + { + parseTimeline(animation.AN.TL, 1, frm); + content += 'Good write on frame: ' + frm + "\n"; + } + catch (e) + { + content += "BAD WRITE : " + frm + "\n"; + content += "\t" + e + "\n"; + trace(e); + } + + // File.saveContent("output.txt", content); + } + + parseTimeline(animation.AN.TL, 1, 0); + trace(actualSprites); + } + + /** + * a MAP of SPRITES, not to be confused with Spritemap... lol + */ + public static function genSpritemap(json:String):Map + { + var sprShitty:Spritemap = cast CoolUtil.coolJSON(json); + var sprMap:Map = new Map(); + + for (spr in sprShitty.ATLAS.SPRITES) + sprMap.set(spr.SPRITE.name, spr.SPRITE); + return sprMap; + } + + // should change dis to all private? + public static function generateSymbolmap(symbols:Array) + { + for (symbol in symbols) + { + // trace(symbol.SN + "has: " + symbol.TL.L.length + " LAYERS"); + + symbolMap.set(symbol.SN, symbol); + // parseTimeline(symbol.TL); + } + } + + public static function preprocessSymbolData(anim:Symbol):Symbol + { + var timelineData:Timeline = anim.TL; + var layerData:Array = timelineData.L; + + if (!timelineData.sortedForRender) + { + timelineData.sortedForRender = true; + layerData.reverse(); + } + + for (layerStuff in layerData) + { + var frames:Array = layerStuff.FR; + + for (frame in frames) + { + var elements:Array = frame.E; + for (e in 0...elements.length) + { + var element:Element = elements[e]; + if (element.ASI != null) + { + element = elements[e] = + { + SI: + { + SN: "ATLAS_SYMBOL_SPRITE", + LP: "LP", + TRP: {x: 0, y: 0}, + M3D: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], + FF: 0, + ST: "G", + ASI: element.ASI + } + } + } + } + } + } + + return anim; + } + + public static var curLoopType:String; + + /** + * Stuff for debug parsing + */ + public static var depthTypeBeat:String = ""; + + /** + * Array of bullshit that will eventually be RENDERED by whoever wanna use it! + */ + public static var frameList:Array> = []; + + // for loop stuf + + /** + * Similar to frameList, keeps track of shit according to framess? + * That amount of arrays within arrays is fuckin dumb + * but innermost array is basically just x and y value, cuz im dum + */ + public static var matrixHelp:Array>> = []; + + public static var trpHelpIDK:Array>> = []; + + public static var loopedFrameShit:Int = 0; + + public static var funnyMatrix:Matrix = new Matrix(); + public static var matrixFlipper:Array = []; + + // clean up all the crazy ass arrays + + public static function resetFrameList() + { + // funnyMatrix.identity(); + + frameList = []; + frameList.push([]); + matrixHelp = []; + matrixHelp.push([]); + + trpHelpIDK = []; + trpHelpIDK.push([]); + } + + public static var isFlipped:Bool = false; + + public static function parseTimeline(TL:Timeline, tabbed:Int = 0, ?frameInput:Int) + { + var strTab:String = ""; + for (i in 0...tabbed) + strTab += '\t'; + + for (layer in TL.L) + { + var frameArray:Array = []; + var frameMap:Map = new Map(); + + for (frms in layer.FR) + { + for (i in 0...frms.DU) + frameArray.push(frms.I); + + frameMap.set(frms.I, frms); + } + + if (frameInput == null) frameInput = 0; + + var oldFrm:Int = frameInput; + /* + if (curLoopType == "SF") + { + trace(layer.LN); + + trace(frameArray); + trace(frameInput); + trace(curLoopType); + }*/ + + if (curLoopType == "LP") frameInput = frameArray[frameInput % frameArray.length]; + else if (curLoopType == "SF") + { + frameInput = frameArray[loopedFrameShit]; + + // see what happens when something has more than 2 layer? + // single frame stuff isn't fully implemented + } + else + frameInput = frameArray[frameInput]; - // trace(frameMap.get(frameInput)); + // trace(frameMap.get(frameInput)); - var frame:Frame = frameMap.get(frameInput); + var frame:Frame = frameMap.get(frameInput); - // get somethin sorted per element list, which would essentially be per symbol things properly sorted - // seperate data types if symbol or atlassymbolinstance? would probably be maybe slightly less memory intensive? i dunno + // get somethin sorted per element list, which would essentially be per symbol things properly sorted + // seperate data types if symbol or atlassymbolinstance? would probably be maybe slightly less memory intensive? i dunno - // goes thru each layer, and then each element - // after it gets thru each element it adds to the layer frame stuff. - // make somethin that works recursively, maybe thats the symbol dictionary type shit? + // goes thru each layer, and then each element + // after it gets thru each element it adds to the layer frame stuff. + // make somethin that works recursively, maybe thats the symbol dictionary type shit? - for (element in frame.E) - { - if (Reflect.hasField(element, "ASI")) - { - matrixHelp[matrixHelp.length - 1].push(element.ASI.M3D); + for (element in frame.E) + { + if (Reflect.hasField(element, "ASI")) + { + matrixHelp[matrixHelp.length - 1].push(element.ASI.M3D); - var m3D = element.ASI.M3D; - var lilMatrix:Matrix = new Matrix(m3D[0], m3D[1], m3D[4], m3D[5], m3D[12], m3D[13]); - matrixFlipper.push(lilMatrix); + var m3D = element.ASI.M3D; + var lilMatrix:Matrix = new Matrix(m3D[0], m3D[1], m3D[4], m3D[5], m3D[12], m3D[13]); + matrixFlipper.push(lilMatrix); - // matrixFlipper.reverse(); + // matrixFlipper.reverse(); - // funnyMatrix.identity(); + // funnyMatrix.identity(); - // for (m in matrixFlipper) - // funnyMatrix.concat(m); + // for (m in matrixFlipper) + // funnyMatrix.concat(m); - if (isFlipped) - { - trace("MORE FLIPPED SHIT"); - trace("MORE FLIPPED SHIT"); - trace("MORE FLIPPED SHIT"); - trace(funnyMatrix); - trace(matrixFlipper); - } + if (isFlipped) + { + trace("MORE FLIPPED SHIT"); + trace("MORE FLIPPED SHIT"); + trace("MORE FLIPPED SHIT"); + trace(funnyMatrix); + trace(matrixFlipper); + } - // trace(funnyMatrix); + // trace(funnyMatrix); - funnyMatrix.concat(lilMatrix); - // trace(funnyMatrix); + funnyMatrix.concat(lilMatrix); + // trace(funnyMatrix); - frameList[frameList.length - 1].push({ - frameName: element.ASI.N, - depthString: depthTypeBeat, - matrixArray: matrixHelp[matrixHelp.length - 1], - trpArray: trpHelpIDK[trpHelpIDK.length - 1], - fullMatrix: funnyMatrix.clone() - }); + frameList[frameList.length - 1].push( + { + frameName: element.ASI.N, + depthString: depthTypeBeat, + matrixArray: matrixHelp[matrixHelp.length - 1], + trpArray: trpHelpIDK[trpHelpIDK.length - 1], + fullMatrix: funnyMatrix.clone() + }); - // flips the matrix once?? I cant remember exactly why it needs to be flipped - // matrixHelp[matrixHelp.length - 1].reverse(); + // flips the matrix once?? I cant remember exactly why it needs to be flipped + // matrixHelp[matrixHelp.length - 1].reverse(); - // trpHelpIDK = []; + // trpHelpIDK = []; - // push the matrix array after each symbol? + // push the matrix array after each symbol? - funnyMatrix.identity(); - matrixFlipper = []; + funnyMatrix.identity(); + matrixFlipper = []; - depthTypeBeat = ""; - curLoopType = ""; - loopedFrameShit = 0; + depthTypeBeat = ""; + curLoopType = ""; + loopedFrameShit = 0; - isFlipped = false; - } - else - { - var m3D = element.SI.M3D; - var lilMatrix:Matrix = new Matrix(m3D[0], m3D[1], m3D[4], m3D[5], m3D[12], m3D[13]); + isFlipped = false; + } + else + { + var m3D = element.SI.M3D; + var lilMatrix:Matrix = new Matrix(m3D[0], m3D[1], m3D[4], m3D[5], m3D[12], m3D[13]); - if (lilMatrix.a == -1) - { - isFlipped = true; + if (lilMatrix.a == -1) + { + isFlipped = true; - trace('IS THE NEGATIVE ONE'); - } + trace('IS THE NEGATIVE ONE'); + } - if (isFlipped) - trace(lilMatrix); + if (isFlipped) trace(lilMatrix); - funnyMatrix.concat(lilMatrix); - matrixFlipper.push(lilMatrix); - // trace(funnyMatrix); + funnyMatrix.concat(lilMatrix); + matrixFlipper.push(lilMatrix); + // trace(funnyMatrix); - matrixHelp[matrixHelp.length - 1].push(element.SI.M3D); - trpHelpIDK[trpHelpIDK.length - 1].push([element.SI.TRP.x, element.SI.TRP.y]); // trpHelpIDK.push(); - depthTypeBeat += "->" + element.SI.SN; - curLoopType = element.SI.LP; + matrixHelp[matrixHelp.length - 1].push(element.SI.M3D); + trpHelpIDK[trpHelpIDK.length - 1].push([element.SI.TRP.x, element.SI.TRP.y]); // trpHelpIDK.push(); + depthTypeBeat += "->" + element.SI.SN; + curLoopType = element.SI.LP; - var inputFrame:Int = element.SI.FF; + var inputFrame:Int = element.SI.FF; - // JANKY FIX, MAY NOT ACCOUNT FOR ALL SCENARIOS OF SINGLE FRAME ANIMATIONS!! - if (curLoopType == "SF") - { - // trace("LOOP SHIT: " + inputFrame); - loopedFrameShit = inputFrame; - } + // JANKY FIX, MAY NOT ACCOUNT FOR ALL SCENARIOS OF SINGLE FRAME ANIMATIONS!! + if (curLoopType == "SF") + { + // trace("LOOP SHIT: " + inputFrame); + loopedFrameShit = inputFrame; + } - // condense the animation code, so it automatically already fills up animation shit per symbol + // condense the animation code, so it automatically already fills up animation shit per symbol - parseTimeline(symbolMap.get(element.SI.SN).TL, tabbed + 1, inputFrame); - } + parseTimeline(symbolMap.get(element.SI.SN).TL, tabbed + 1, inputFrame); + } - // idk if this should go per layer or per element / object? + // idk if this should go per layer or per element / object? - matrixHelp.push([]); - trpHelpIDK.push([]); - } + matrixHelp.push([]); + trpHelpIDK.push([]); + } - if (tabbed == 0) - { - frameList[frameList.length - 1].reverse(); - frameList.push([]); // new layer essentially - } - } + if (tabbed == 0) + { + frameList[frameList.length - 1].reverse(); + frameList.push([]); // new layer essentially + } + } - frameList.reverse(); - } + frameList.reverse(); + } } typedef VALIDFRAME = { - frameName:String, - depthString:String, - matrixArray:Array>, - trpArray:Array>, - fullMatrix:Matrix + frameName:String, + depthString:String, + matrixArray:Array>, + trpArray:Array>, + fullMatrix:Matrix } typedef AnimJson = { - AN:Animation, - SD:SymbolDictionary, - MD:MetaData + AN:Animation, + SD:SymbolDictionary, + MD:MetaData } typedef Animation = { - N:String, - SN:String, - TL:Timeline + N:String, + SN:String, + TL:Timeline } typedef SymbolDictionary = { - S:Array + S:Array } typedef Symbol = { - /**Symbol name*/ - SN:String, + /**Symbol name*/ + SN:String, - TL:Timeline + TL:Timeline } typedef Timeline = { - ?sortedForRender:Bool, - L:Array + ?sortedForRender:Bool, + L:Array } typedef Layer = { - LN:String, - FR:Array + LN:String, + FR:Array } typedef Frame = { - E:Array, - I:Int, - DU:Int - // maybe need to implement names if it has frame labels? + E:Array, + I:Int, + DU:Int + // maybe need to implement names if it has frame labels? } typedef Element = { - SI:SymbolInstance, - ?ASI:AlsoSymbolInstance - // lmfao idk what ASI stands for lmfaoo, i dont think its "also" + SI:SymbolInstance, + ?ASI:AlsoSymbolInstance + // lmfao idk what ASI stands for lmfaoo, i dont think its "also" } typedef SymbolInstance = { - SN:String, - ASI:AlsoSymbolInstance, + SN:String, + ASI:AlsoSymbolInstance, - /**Symbol type, prob either G (graphic), or movie clip?*/ ST:String, + /**Symbol type, prob either G (graphic), or movie clip?*/ ST:String, - /**First frame*/ FF:Int, + /**First frame*/ FF:Int, - /**Loop type, loop ping pong, etc.*/ LP:String, + /**Loop type, loop ping pong, etc.*/ LP:String, - /**3D matrix*/ M3D:Array, + /**3D matrix*/ M3D:Array, - TRP: - { - x:Float, y:Float - } + TRP: + { + x:Float, y:Float + } } typedef AlsoSymbolInstance = { - N:String, - M3D:Array + N:String, + M3D:Array } typedef MetaData = { - /** - * Framerate - */ - FRT:Int + /** + * Framerate + */ + FRT:Int } // SPRITEMAP BULLSHIT typedef Spritemap = { - ATLAS: - { - SPRITES:Array - }, - meta:Meta + ATLAS: + { + SPRITES:Array + }, + meta:Meta } typedef SpriteBullshit = { - SPRITE:Sprite + SPRITE:Sprite } typedef Sprite = { - name:String, - x:Int, - y:Int, - w:Int, - h:Int, - rotated:Bool + name:String, + x:Int, + y:Int, + w:Int, + h:Int, + rotated:Bool } typedef Meta = { - app:String, - verstion:String, - image:String, - format:String, - size: - { - w:Int, h:Float - }, - resolution:Float + app:String, + verstion:String, + image:String, + format:String, + size: + { + w:Int, h:Float + }, + resolution:Float } diff --git a/source/funkin/animate/TimelineFrame.hx b/source/funkin/animate/TimelineFrame.hx index 6355a036f..530859443 100644 --- a/source/funkin/animate/TimelineFrame.hx +++ b/source/funkin/animate/TimelineFrame.hx @@ -7,57 +7,57 @@ import funkin.animate.ParseAnimate.Frame; class TimelineFrame extends FlxSprite { - public var data:Frame; + public var data:Frame; - public function new(x:Float, y:Float, length:Int = 0, data:Frame) - { - super(x, y); + public function new(x:Float, y:Float, length:Int = 0, data:Frame) + { + super(x, y); - this.data = data; + this.data = data; - makeGraphic((10 * length) + (2 * (length - 1)), 10, FlxColor.RED); + makeGraphic((10 * length) + (2 * (length - 1)), 10, FlxColor.RED); - FlxMouseEvent.add(this, null, null, function(spr:TimelineFrame) - { - alpha = 0.5; - }, function(spr:TimelineFrame) - { - alpha = 1; - }, false, true, true); - } + FlxMouseEvent.add(this, null, null, function(spr:TimelineFrame) + { + alpha = 0.5; + }, function(spr:TimelineFrame) + { + alpha = 1; + }, false, true, true); + } - override function update(elapsed:Float) - { - // if (FlxG.mouse.overlaps(this, cameras[1])) - // alpha = 0.6; - // else - // alpha = 1; + override function update(elapsed:Float) + { + // if (FlxG.mouse.overlaps(this, cameras[1])) + // alpha = 0.6; + // else + // alpha = 1; - if (FlxG.mouse.overlaps(this, cameras[0]) && FlxG.mouse.justPressed) - { - trace("\nFRAME DATA - \n\tFRAME NUM: " + data.I + "\n\tFRAME DURATION: " + data.DU); + if (FlxG.mouse.overlaps(this, cameras[0]) && FlxG.mouse.justPressed) + { + trace("\nFRAME DATA - \n\tFRAME NUM: " + data.I + "\n\tFRAME DURATION: " + data.DU); - for (e in data.E) - { - var elementOutput:String = "\n"; + for (e in data.E) + { + var elementOutput:String = "\n"; - if (Reflect.hasField(e, 'ASI')) - { - elementOutput += "ELEMENT IS ASI!"; + if (Reflect.hasField(e, 'ASI')) + { + elementOutput += "ELEMENT IS ASI!"; - elementOutput += "\n\t"; - elementOutput += "FRAME NAME: " + e.ASI.N; - } - else - { - elementOutput += "ELEMENT IS SYMBOL INSTANCE!"; - elementOutput += "\n\tSYMBOL NAME: " + e.SI.SN; - } + elementOutput += "\n\t"; + elementOutput += "FRAME NAME: " + e.ASI.N; + } + else + { + elementOutput += "ELEMENT IS SYMBOL INSTANCE!"; + elementOutput += "\n\tSYMBOL NAME: " + e.SI.SN; + } - trace(elementOutput); - } - } + trace(elementOutput); + } + } - super.update(elapsed); - } + super.update(elapsed); + } } diff --git a/source/funkin/api/newgrounds/NGUnsafe.hx b/source/funkin/api/newgrounds/NGUnsafe.hx index bb2305a55..9616dfe18 100644 --- a/source/funkin/api/newgrounds/NGUnsafe.hx +++ b/source/funkin/api/newgrounds/NGUnsafe.hx @@ -22,55 +22,54 @@ import io.newgrounds.objects.events.Result.GetVersionResult; */ class NGUnsafe { - static public function logEvent(event:String) - { - #if newgrounds - NG.core.calls.event.logEvent(event).send(); - trace('should have logged: ' + event); - #else - #if debug - trace('event:$event - not logged, missing NG.io lib'); - #end - #end - } + static public function logEvent(event:String) + { + #if newgrounds + NG.core.calls.event.logEvent(event).send(); + trace('should have logged: ' + event); + #else + #if debug + trace('event:$event - not logged, missing NG.io lib'); + #end + #end + } - static public function unlockMedal(id:Int) - { - #if newgrounds - if (isLoggedIn) - { - var medal = NG.core.medals.get(id); - if (!medal.unlocked) - medal.sendUnlock(); - } - #else - #if debug - trace('medal:$id - not unlocked, missing NG.io lib'); - #end - #end - } + static public function unlockMedal(id:Int) + { + #if newgrounds + if (isLoggedIn) + { + var medal = NG.core.medals.get(id); + if (!medal.unlocked) medal.sendUnlock(); + } + #else + #if debug + trace('medal:$id - not unlocked, missing NG.io lib'); + #end + #end + } - static public function postScore(score:Int = 0, song:String) - { - #if newgrounds - if (isLoggedIn) - { - for (id in NG.core.scoreBoards.keys()) - { - var board = NG.core.scoreBoards.get(id); + static public function postScore(score:Int = 0, song:String) + { + #if newgrounds + if (isLoggedIn) + { + for (id in NG.core.scoreBoards.keys()) + { + var board = NG.core.scoreBoards.get(id); - if (song == board.name) - { - board.postScore(score, "Uhh meow?"); - } + if (song == board.name) + { + board.postScore(score, "Uhh meow?"); + } - // trace('loaded scoreboard id:$id, name:${board.name}'); - } - } - #else - #if debug - trace('Song:$song, Score:$score - not posted, missing NG.io lib'); - #end - #end - } + // trace('loaded scoreboard id:$id, name:${board.name}'); + } + } + #else + #if debug + trace('Song:$song, Score:$score - not posted, missing NG.io lib'); + #end + #end + } } diff --git a/source/funkin/api/newgrounds/NGUtil.hx b/source/funkin/api/newgrounds/NGUtil.hx index ef4081050..9d6f02680 100644 --- a/source/funkin/api/newgrounds/NGUtil.hx +++ b/source/funkin/api/newgrounds/NGUtil.hx @@ -22,237 +22,236 @@ import io.newgrounds.objects.events.Result.GetVersionResult; */ class NGUtil { - #if newgrounds - /** - * True, if the saved sessionId was used in the initial login, and failed to connect. - * Used in MainMenuState to show a popup to establish a new connection - */ - public static var savedSessionFailed(default, null):Bool = false; + #if newgrounds + /** + * True, if the saved sessionId was used in the initial login, and failed to connect. + * Used in MainMenuState to show a popup to establish a new connection + */ + public static var savedSessionFailed(default, null):Bool = false; - public static var scoreboardsLoaded:Bool = false; - public static var isLoggedIn(get, never):Bool; + public static var scoreboardsLoaded:Bool = false; + public static var isLoggedIn(get, never):Bool; - inline static function get_isLoggedIn() - { - return NG.core != null && NG.core.loggedIn; - } + inline static function get_isLoggedIn() + { + return NG.core != null && NG.core.loggedIn; + } - public static var scoreboardArray:Array = []; + public static var scoreboardArray:Array = []; - public static var ngDataLoaded(default, null):FlxSignal = new FlxSignal(); - public static var ngScoresLoaded(default, null):FlxSignal = new FlxSignal(); + public static var ngDataLoaded(default, null):FlxSignal = new FlxSignal(); + public static var ngScoresLoaded(default, null):FlxSignal = new FlxSignal(); - public static var GAME_VER:String = ""; + public static var GAME_VER:String = ""; - static public function checkVersion(callback:String->Void) - { - trace('checking NG.io version'); - GAME_VER = "v" + Application.current.meta.get('version'); + static public function checkVersion(callback:String->Void) + { + trace('checking NG.io version'); + GAME_VER = "v" + Application.current.meta.get('version'); - NG.core.calls.app.getCurrentVersion(GAME_VER).addDataHandler(function(response) - { - GAME_VER = response.result.data.currentVersion; - trace('CURRENT NG VERSION: ' + GAME_VER); - callback(GAME_VER); - }).send(); - } + NG.core.calls.app.getCurrentVersion(GAME_VER).addDataHandler(function(response) + { + GAME_VER = response.result.data.currentVersion; + trace('CURRENT NG VERSION: ' + GAME_VER); + callback(GAME_VER); + }).send(); + } - static public function init() - { - var api = APIStuff.API; - if (api == null || api.length == 0) - { - trace("Missing Newgrounds API key, aborting connection"); - return; - } - trace("connecting to newgrounds"); + static public function init() + { + var api = APIStuff.API; + if (api == null || api.length == 0) + { + trace("Missing Newgrounds API key, aborting connection"); + return; + } + trace("connecting to newgrounds"); - #if NG_FORCE_EXPIRED_SESSION - var sessionId:String = "fake_session_id"; - function onSessionFail(error:Error) - { - trace("Forcing an expired saved session. " + "To disable, comment out NG_FORCE_EXPIRED_SESSION in Project.xml"); - savedSessionFailed = true; - } - #else - var sessionId:String = NGLite.getSessionId(); - if (sessionId != null) - trace("found web session id"); + #if NG_FORCE_EXPIRED_SESSION + var sessionId:String = "fake_session_id"; + function onSessionFail(error:Error) + { + trace("Forcing an expired saved session. " + "To disable, comment out NG_FORCE_EXPIRED_SESSION in Project.xml"); + savedSessionFailed = true; + } + #else + var sessionId:String = NGLite.getSessionId(); + if (sessionId != null) trace("found web session id"); - #if (debug) - if (sessionId == null && APIStuff.SESSION != null) - { - trace("using debug session id"); - sessionId = APIStuff.SESSION; - } - #end + #if (debug) + if (sessionId == null && APIStuff.SESSION != null) + { + trace("using debug session id"); + sessionId = APIStuff.SESSION; + } + #end - var onSessionFail:Error->Void = null; - if (sessionId == null && FlxG.save.data.sessionId != null) - { - trace("using stored session id"); - sessionId = FlxG.save.data.sessionId; - onSessionFail = function(error) savedSessionFailed = true; - } - #end + var onSessionFail:Error->Void = null; + if (sessionId == null && FlxG.save.data.sessionId != null) + { + trace("using stored session id"); + sessionId = FlxG.save.data.sessionId; + onSessionFail = function(error) savedSessionFailed = true; + } + #end - NG.create(api, sessionId, #if NG_DEBUG true #else false #end, onSessionFail); + NG.create(api, sessionId, #if NG_DEBUG true #else false #end, onSessionFail); - #if NG_VERBOSE - NG.core.verbose = true; - #end - // Set the encryption cipher/format to RC4/Base64. AES128 and Hex are not implemented yet - NG.core.initEncryption(APIStuff.EncKey); // Found in you NG project view + #if NG_VERBOSE + NG.core.verbose = true; + #end + // Set the encryption cipher/format to RC4/Base64. AES128 and Hex are not implemented yet + NG.core.initEncryption(APIStuff.EncKey); // Found in you NG project view - if (NG.core.attemptingLogin) - { - /* a session_id was found in the loadervars, this means the user is playing on newgrounds.com - * and we should login shortly. lets wait for that to happen - */ - trace("attempting login"); - NG.core.onLogin.add(onNGLogin); - } - // GK: taking out auto login, adding a login button to the main menu - // else - // { - // /* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to. - // * Note: This will cause a new browser window to pop up where they can log in to newgrounds - // */ - // NG.core.requestLogin(onNGLogin); - // } - } + if (NG.core.attemptingLogin) + { + /* a session_id was found in the loadervars, this means the user is playing on newgrounds.com + * and we should login shortly. lets wait for that to happen + */ + trace("attempting login"); + NG.core.onLogin.add(onNGLogin); + } + // GK: taking out auto login, adding a login button to the main menu + // else + // { + // /* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to. + // * Note: This will cause a new browser window to pop up where they can log in to newgrounds + // */ + // NG.core.requestLogin(onNGLogin); + // } + } - /** - * Attempts to log in to newgrounds by requesting a new session ID, only call if no session ID was found automatically - * @param popupLauncher The function to call to open the login url, must be inside - * a user input event or the popup blocker will block it. - * @param onComplete A callback with the result of the connection. - */ - static public function login(?popupLauncher:(Void->Void)->Void, onComplete:ConnectionResult->Void) - { - trace("Logging in manually"); - var onPending:Void->Void = null; - if (popupLauncher != null) - { - onPending = function() popupLauncher(NG.core.openPassportUrl); - } + /** + * Attempts to log in to newgrounds by requesting a new session ID, only call if no session ID was found automatically + * @param popupLauncher The function to call to open the login url, must be inside + * a user input event or the popup blocker will block it. + * @param onComplete A callback with the result of the connection. + */ + static public function login(?popupLauncher:(Void->Void)->Void, onComplete:ConnectionResult->Void) + { + trace("Logging in manually"); + var onPending:Void->Void = null; + if (popupLauncher != null) + { + onPending = function() popupLauncher(NG.core.openPassportUrl); + } - var onSuccess:Void->Void = onNGLogin; - var onFail:Error->Void = null; - var onCancel:Void->Void = null; - if (onComplete != null) - { - onSuccess = function() - { - onNGLogin(); - onComplete(Success); - } - onFail = function(e) onComplete(Fail(e.message)); - onCancel = function() onComplete(Cancelled); - } + var onSuccess:Void->Void = onNGLogin; + var onFail:Error->Void = null; + var onCancel:Void->Void = null; + if (onComplete != null) + { + onSuccess = function() + { + onNGLogin(); + onComplete(Success); + } + onFail = function(e) onComplete(Fail(e.message)); + onCancel = function() onComplete(Cancelled); + } - NG.core.requestLogin(onSuccess, onPending, onFail, onCancel); - } + NG.core.requestLogin(onSuccess, onPending, onFail, onCancel); + } - inline static public function cancelLogin():Void - { - NG.core.cancelLoginRequest(); - } + inline static public function cancelLogin():Void + { + NG.core.cancelLoginRequest(); + } - static function onNGLogin():Void - { - trace('logged in! user:${NG.core.user.name}'); - FlxG.save.data.sessionId = NG.core.sessionId; - FlxG.save.flush(); - // Load medals then call onNGMedalFetch() - NG.core.requestMedals(onNGMedalFetch); + static function onNGLogin():Void + { + trace('logged in! user:${NG.core.user.name}'); + FlxG.save.data.sessionId = NG.core.sessionId; + FlxG.save.flush(); + // Load medals then call onNGMedalFetch() + NG.core.requestMedals(onNGMedalFetch); - // Load Scoreboards hten call onNGBoardsFetch() - NG.core.requestScoreBoards(onNGBoardsFetch); + // Load Scoreboards hten call onNGBoardsFetch() + NG.core.requestScoreBoards(onNGBoardsFetch); - ngDataLoaded.dispatch(); - } + ngDataLoaded.dispatch(); + } - static public function logout() - { - NG.core.logOut(); + static public function logout() + { + NG.core.logOut(); - FlxG.save.data.sessionId = null; - FlxG.save.flush(); - } + FlxG.save.data.sessionId = null; + FlxG.save.flush(); + } - // --- MEDALS - static function onNGMedalFetch():Void - { - /* - // Reading medal info - for (id in NG.core.medals.keys()) - { - var medal = NG.core.medals.get(id); - trace('loaded medal id:$id, name:${medal.name}, description:${medal.description}'); - } + // --- MEDALS + static function onNGMedalFetch():Void + { + /* + // Reading medal info + for (id in NG.core.medals.keys()) + { + var medal = NG.core.medals.get(id); + trace('loaded medal id:$id, name:${medal.name}, description:${medal.description}'); + } - // Unlocking medals - var unlockingMedal = NG.core.medals.get(54352);// medal ids are listed in your NG project viewer - if (!unlockingMedal.unlocked) - unlockingMedal.sendUnlock(); - */ - } + // Unlocking medals + var unlockingMedal = NG.core.medals.get(54352);// medal ids are listed in your NG project viewer + if (!unlockingMedal.unlocked) + unlockingMedal.sendUnlock(); + */ + } - // --- SCOREBOARDS - static function onNGBoardsFetch():Void - { - /* - // Reading medal info - for (id in NG.core.scoreBoards.keys()) - { - var board = NG.core.scoreBoards.get(id); - trace('loaded scoreboard id:$id, name:${board.name}'); - } - */ - // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view + // --- SCOREBOARDS + static function onNGBoardsFetch():Void + { + /* + // Reading medal info + for (id in NG.core.scoreBoards.keys()) + { + var board = NG.core.scoreBoards.get(id); + trace('loaded scoreboard id:$id, name:${board.name}'); + } + */ + // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view - // Posting a score thats OVER 9000! - // board.postScore(FlxG.random.int(0, 1000)); + // Posting a score thats OVER 9000! + // board.postScore(FlxG.random.int(0, 1000)); - // --- To view the scores you first need to select the range of scores you want to see --- + // --- To view the scores you first need to select the range of scores you want to see --- - // add an update listener so we know when we get the new scores - // board.onUpdate.add(onNGScoresFetch); - trace("shoulda got score by NOW!"); - // board.requestScores(20);// get the best 10 scores ever logged - // more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores - } + // add an update listener so we know when we get the new scores + // board.onUpdate.add(onNGScoresFetch); + trace("shoulda got score by NOW!"); + // board.requestScores(20);// get the best 10 scores ever logged + // more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores + } - static function onNGScoresFetch():Void - { - scoreboardsLoaded = true; + static function onNGScoresFetch():Void + { + scoreboardsLoaded = true; - ngScoresLoaded.dispatch(); - /* - for (score in NG.core.scoreBoards.get(8737).scores) - { - trace('score loaded user:${score.user.name}, score:${score.formatted_value}'); + ngScoresLoaded.dispatch(); + /* + for (score in NG.core.scoreBoards.get(8737).scores) + { + trace('score loaded user:${score.user.name}, score:${score.formatted_value}'); - } - */ + } + */ - // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view - // board.postScore(HighScore.score); + // var board = NG.core.scoreBoards.get(8004);// ID found in NG project view + // board.postScore(HighScore.score); - // NGUtil.scoreboardArray = NG.core.scoreBoards.get(8004).scores; - } - #end + // NGUtil.scoreboardArray = NG.core.scoreBoards.get(8004).scores; + } + #end } enum ConnectionResult { - /** Log in successful */ - Success; + /** Log in successful */ + Success; - /** Could not login */ - Fail(msg:String); + /** Could not login */ + Fail(msg:String); - /** User cancelled the login */ - Cancelled; + /** User cancelled the login */ + Cancelled; } diff --git a/source/funkin/api/newgrounds/NgPrompt.hx b/source/funkin/api/newgrounds/NgPrompt.hx index 5f08bf443..7f7d677ef 100644 --- a/source/funkin/api/newgrounds/NgPrompt.hx +++ b/source/funkin/api/newgrounds/NgPrompt.hx @@ -6,99 +6,99 @@ import funkin.ui.Prompt; class NgPrompt extends Prompt { - public function new(text:String, style:ButtonStyle = Yes_No) - { - super(text, style); - } + public function new(text:String, style:ButtonStyle = Yes_No) + { + super(text, style); + } - static public function showLogin() - { - return showLoginPrompt(true); - } + static public function showLogin() + { + return showLoginPrompt(true); + } - static public function showSavedSessionFailed() - { - return showLoginPrompt(false); - } + static public function showSavedSessionFailed() + { + return showLoginPrompt(false); + } - static function showLoginPrompt(fromUi:Bool) - { - var prompt = new NgPrompt("Talking to server...", None); - prompt.openCallback = NGUtil.login.bind(function popupLauncher(openPassportUrl) - { - var choiceMsg = fromUi ? #if web "Log in to Newgrounds?" #else null #end // User-input needed to allow popups - : "Your session has expired.\n Please login again."; + static function showLoginPrompt(fromUi:Bool) + { + var prompt = new NgPrompt("Talking to server...", None); + prompt.openCallback = NGUtil.login.bind(function popupLauncher(openPassportUrl) + { + var choiceMsg = fromUi ? #if web "Log in to Newgrounds?" #else null #end // User-input needed to allow popups + : "Your session has expired.\n Please login again."; - if (choiceMsg != null) - { - prompt.setText(choiceMsg); - prompt.setButtons(Yes_No); - #if web - prompt.buttons.getItem("yes").fireInstantly = true; - #end - prompt.onYes = function() - { - prompt.setText("Connecting..." #if web + "\n(check your popup blocker)" #end); - prompt.setButtons(None); - openPassportUrl(); - }; - prompt.onNo = function() - { - prompt.close(); - prompt = null; - NGio.cancelLogin(); - }; - } - else - { - prompt.setText("Connecting..."); - openPassportUrl(); - } - }, function onLoginComplete(result:ConnectionResult) - { - switch (result) - { - case Success: - { - prompt.setText("Login Successful"); - prompt.setButtons(Ok); - prompt.onYes = prompt.close; - } - case Fail(msg): - { - trace("Login Error:" + msg); - prompt.setText("Login failed"); - prompt.setButtons(Ok); - prompt.onYes = prompt.close; - } - case Cancelled: - { - if (prompt != null) - { - prompt.setText("Login cancelled by user"); - prompt.setButtons(Ok); - prompt.onYes = prompt.close; - } - else - trace("Login cancelled via prompt"); - } - } - }); + if (choiceMsg != null) + { + prompt.setText(choiceMsg); + prompt.setButtons(Yes_No); + #if web + prompt.buttons.getItem("yes").fireInstantly = true; + #end + prompt.onYes = function() + { + prompt.setText("Connecting..." #if web + "\n(check your popup blocker)" #end); + prompt.setButtons(None); + openPassportUrl(); + }; + prompt.onNo = function() + { + prompt.close(); + prompt = null; + NGio.cancelLogin(); + }; + } + else + { + prompt.setText("Connecting..."); + openPassportUrl(); + } + }, function onLoginComplete(result:ConnectionResult) + { + switch (result) + { + case Success: + { + prompt.setText("Login Successful"); + prompt.setButtons(Ok); + prompt.onYes = prompt.close; + } + case Fail(msg): + { + trace("Login Error:" + msg); + prompt.setText("Login failed"); + prompt.setButtons(Ok); + prompt.onYes = prompt.close; + } + case Cancelled: + { + if (prompt != null) + { + prompt.setText("Login cancelled by user"); + prompt.setButtons(Ok); + prompt.onYes = prompt.close; + } + else + trace("Login cancelled via prompt"); + } + } + }); - return prompt; - } + return prompt; + } - static public function showLogout() - { - var user = io.newgrounds.NG.core.user.name; - var prompt = new NgPrompt('Log out of $user?', Yes_No); - prompt.onYes = function() - { - NGio.logout(); - prompt.close(); - }; - prompt.onNo = prompt.close; - return prompt; - } + static public function showLogout() + { + var user = io.newgrounds.NG.core.user.name; + var prompt = new NgPrompt('Log out of $user?', Yes_No); + prompt.onYes = function() + { + NGio.logout(); + prompt.close(); + }; + prompt.onNo = prompt.close; + return prompt; + } } #end diff --git a/source/funkin/audio/FlxAudioGroup.hx b/source/funkin/audio/FlxAudioGroup.hx index a06979a32..66044b3cc 100644 --- a/source/funkin/audio/FlxAudioGroup.hx +++ b/source/funkin/audio/FlxAudioGroup.hx @@ -14,195 +14,190 @@ import flixel.system.FlxSound; */ class FlxAudioGroup extends FlxTypedGroup { - /** - * The position in time of the sounds in the group. - * Measured in milliseconds. - */ - public var time(get, set):Float; + /** + * The position in time of the sounds in the group. + * Measured in milliseconds. + */ + public var time(get, set):Float; - function get_time():Float - { - if (getFirstAlive() != null) - return getFirstAlive().time; - else - return 0; - } + function get_time():Float + { + if (getFirstAlive() != null) return getFirstAlive().time; + else + return 0; + } - function set_time(time:Float):Float - { - forEachAlive(function(sound:FlxSound) - { - // account for different offsets per sound? - sound.time = time; - }); + function set_time(time:Float):Float + { + forEachAlive(function(sound:FlxSound) + { + // account for different offsets per sound? + sound.time = time; + }); - return time; - } + return time; + } - /** - * The volume of the sounds in the group. - */ - public var volume(get, set):Float; + /** + * The volume of the sounds in the group. + */ + public var volume(get, set):Float; - function get_volume():Float - { - if (getFirstAlive() != null) - return getFirstAlive().volume; - else - return 1.0; - } + function get_volume():Float + { + if (getFirstAlive() != null) return getFirstAlive().volume; + else + return 1.0; + } - function set_volume(volume:Float):Float - { - forEachAlive(function(sound:FlxSound) - { - sound.volume = volume; - }); + function set_volume(volume:Float):Float + { + forEachAlive(function(sound:FlxSound) + { + sound.volume = volume; + }); - return volume; - } + return volume; + } - /** - * The pitch of the sounds in the group, as a multiplier of 1.0x. - * `2.0` would play the audio twice as fast with a higher pitch, - * and `0.5` would play the audio at half speed with a lower pitch. - */ - public var pitch(get, set):Float; + /** + * The pitch of the sounds in the group, as a multiplier of 1.0x. + * `2.0` would play the audio twice as fast with a higher pitch, + * and `0.5` would play the audio at half speed with a lower pitch. + */ + public var pitch(get, set):Float; - function get_pitch():Float - { - #if FLX_PITCH - if (getFirstAlive() != null) - return getFirstAlive().pitch; - else - #end - return 1; - } + function get_pitch():Float + { + #if FLX_PITCH + if (getFirstAlive() != null) return getFirstAlive().pitch; + else + #end + return 1; + } - function set_pitch(val:Float):Float - { - #if FLX_PITCH - trace('Setting audio pitch to ' + val); - forEachAlive(function(sound:FlxSound) - { - sound.pitch = val; - }); - #end - return val; - } + function set_pitch(val:Float):Float + { + #if FLX_PITCH + trace('Setting audio pitch to ' + val); + forEachAlive(function(sound:FlxSound) + { + sound.pitch = val; + }); + #end + return val; + } - /** - * Whether members of the group should be destroyed when they finish playing. - */ - public var autoDestroyMembers(default, set):Bool = false; + /** + * Whether members of the group should be destroyed when they finish playing. + */ + public var autoDestroyMembers(default, set):Bool = false; - function set_autoDestroyMembers(value:Bool):Bool - { - autoDestroyMembers = value; - forEachAlive(function(sound:FlxSound) - { - sound.autoDestroy = value; - }); - return value; - } + function set_autoDestroyMembers(value:Bool):Bool + { + autoDestroyMembers = value; + forEachAlive(function(sound:FlxSound) + { + sound.autoDestroy = value; + }); + return value; + } - /** - * Add a sound to the group. - */ - public override function add(sound:FlxSound):FlxSound - { - var result:FlxSound = super.add(sound); + /** + * Add a sound to the group. + */ + public override function add(sound:FlxSound):FlxSound + { + var result:FlxSound = super.add(sound); - if (result == null) - return null; + if (result == null) return null; - // Apply parameters to the new sound. - result.autoDestroy = this.autoDestroyMembers; - result.pitch = this.pitch; - result.volume = this.volume; + // Apply parameters to the new sound. + result.autoDestroy = this.autoDestroyMembers; + result.pitch = this.pitch; + result.volume = this.volume; - // We have to play, then pause the sound to set the time, - // else the sound will restart immediately when played. - result.play(true, 0.0); - result.pause(); - result.time = this.time; + // We have to play, then pause the sound to set the time, + // else the sound will restart immediately when played. + result.play(true, 0.0); + result.pause(); + result.time = this.time; - return result; - } + return result; + } - /** - * Pause all the sounds in the group. - */ - public function pause() - { - forEachAlive(function(sound:FlxSound) - { - sound.pause(); - }); - } + /** + * Pause all the sounds in the group. + */ + public function pause() + { + forEachAlive(function(sound:FlxSound) + { + sound.pause(); + }); + } - /** - * Play all the sounds in the group. - */ - public function play(forceRestart:Bool = false, startTime:Float = 0.0, ?endTime:Float) - { - forEachAlive(function(sound:FlxSound) - { - sound.play(forceRestart, startTime, endTime); - }); - } + /** + * Play all the sounds in the group. + */ + public function play(forceRestart:Bool = false, startTime:Float = 0.0, ?endTime:Float) + { + forEachAlive(function(sound:FlxSound) + { + sound.play(forceRestart, startTime, endTime); + }); + } - /** - * Resume all the sounds in the group. - */ - public function resume() - { - forEachAlive(function(sound:FlxSound) - { - sound.resume(); - }); - } + /** + * Resume all the sounds in the group. + */ + public function resume() + { + forEachAlive(function(sound:FlxSound) + { + sound.resume(); + }); + } - /** - * Stop all the sounds in the group. - */ - public function stop() - { - forEachAlive(function(sound:FlxSound) - { - sound.stop(); - }); - } + /** + * Stop all the sounds in the group. + */ + public function stop() + { + forEachAlive(function(sound:FlxSound) + { + sound.stop(); + }); + } - public override function clear():Void { - this.stop(); + public override function clear():Void + { + this.stop(); - super.clear(); - } + super.clear(); + } - /** - * Calculates the deviation of the sounds in the group from the target time. - * - * @param targetTime The time to compare the sounds to. - * If null, the current time of the first sound in the group is used. - * @return The largest deviation of the sounds in the group from the target time. - */ - public function calcDeviation(?targetTime:Float):Float - { - var deviation:Float = 0; + /** + * Calculates the deviation of the sounds in the group from the target time. + * + * @param targetTime The time to compare the sounds to. + * If null, the current time of the first sound in the group is used. + * @return The largest deviation of the sounds in the group from the target time. + */ + public function calcDeviation(?targetTime:Float):Float + { + var deviation:Float = 0; - forEachAlive(function(sound:FlxSound) - { - if (targetTime == null) - targetTime = sound.time; - else - { - var diff:Float = sound.time - targetTime; - if (Math.abs(diff) > Math.abs(deviation)) - deviation = diff; - } - }); + forEachAlive(function(sound:FlxSound) + { + if (targetTime == null) targetTime = sound.time; + else + { + var diff:Float = sound.time - targetTime; + if (Math.abs(diff) > Math.abs(deviation)) deviation = diff; + } + }); - return deviation; - } + return deviation; + } } diff --git a/source/funkin/audio/VocalGroup.hx b/source/funkin/audio/VocalGroup.hx index 2dce0d4c0..31539eab1 100644 --- a/source/funkin/audio/VocalGroup.hx +++ b/source/funkin/audio/VocalGroup.hx @@ -7,113 +7,113 @@ import flixel.system.FlxSound; */ class VocalGroup extends FlxAudioGroup { - /** - * The player's vocal track. - */ - var playerVocals:FlxSound; + /** + * The player's vocal track. + */ + var playerVocals:FlxSound; - /** - * The opponent's vocal track. - */ - var opponentVocals:FlxSound; + /** + * The opponent's vocal track. + */ + var opponentVocals:FlxSound; - /** - * The volume of the player's vocal track. + /** + * The volume of the player's vocal track. * Nore that this value is multiplied by the overall volume of the group. - */ - public var playerVolume(default, set):Float; + */ + public var playerVolume(default, set):Float; - function set_playerVolume(value:Float):Float - { - playerVolume = value; - if (playerVocals != null) - { - // Make sure volume is capped at 1.0. - playerVocals.volume = Math.min(playerVolume * this.volume, 1.0); - } - return playerVolume; - } - - /** - * The volume of the opponent's vocal track. - * Nore that this value is multiplied by the overall volume of the group. - */ - public var opponentVolume(default, set):Float; - - function set_opponentVolume(value:Float):Float - { - opponentVolume = value; - if (opponentVocals != null) - { - // Make sure volume is capped at 1.0. - opponentVocals.volume = opponentVolume * this.volume; - } - return opponentVolume; - } - - /** - * Sets up the player's vocal track. - * Stops and removes the existing player track if one exists. - */ - public function setPlayerVocals(sound:FlxSound):FlxSound - { - if (playerVocals != null) - { - playerVocals.stop(); - remove(playerVocals); - playerVocals = null; - } - - playerVocals = add(sound); - playerVocals.volume = this.playerVolume * this.volume; - - return playerVocals; - } - - /** - * Sets up the opponent's vocal track. - * Stops and removes the existing player track if one exists. - */ - public function setOpponentVocals(sound:FlxSound):FlxSound - { - if (opponentVocals != null) - { - opponentVocals.stop(); - remove(opponentVocals); - opponentVocals = null; - } - - opponentVocals = add(sound); - opponentVocals.volume = this.opponentVolume * this.volume; - - return opponentVocals; - } - - /** - * In this extension of FlxAudioGroup, there is a separate overall volume - * which affects all the members of the group. - */ - var _volume = 1.0; - - override function get_volume():Float + function set_playerVolume(value:Float):Float + { + playerVolume = value; + if (playerVocals != null) { - return _volume; + // Make sure volume is capped at 1.0. + playerVocals.volume = Math.min(playerVolume * this.volume, 1.0); + } + return playerVolume; + } + + /** + * The volume of the opponent's vocal track. + * Nore that this value is multiplied by the overall volume of the group. + */ + public var opponentVolume(default, set):Float; + + function set_opponentVolume(value:Float):Float + { + opponentVolume = value; + if (opponentVocals != null) + { + // Make sure volume is capped at 1.0. + opponentVocals.volume = opponentVolume * this.volume; + } + return opponentVolume; + } + + /** + * Sets up the player's vocal track. + * Stops and removes the existing player track if one exists. + */ + public function setPlayerVocals(sound:FlxSound):FlxSound + { + if (playerVocals != null) + { + playerVocals.stop(); + remove(playerVocals); + playerVocals = null; } - override function set_volume(value:Float):Float - { - _volume = super.set_volume(value); + playerVocals = add(sound); + playerVocals.volume = this.playerVolume * this.volume; - if (playerVocals != null) - { - playerVocals.volume = playerVolume * _volume; - } + return playerVocals; + } - if (opponentVocals != null) - { - opponentVocals.volume = opponentVolume * _volume; - } + /** + * Sets up the opponent's vocal track. + * Stops and removes the existing player track if one exists. + */ + public function setOpponentVocals(sound:FlxSound):FlxSound + { + if (opponentVocals != null) + { + opponentVocals.stop(); + remove(opponentVocals); + opponentVocals = null; + } - return _volume; - } + opponentVocals = add(sound); + opponentVocals.volume = this.opponentVolume * this.volume; + + return opponentVocals; + } + + /** + * In this extension of FlxAudioGroup, there is a separate overall volume + * which affects all the members of the group. + */ + var _volume = 1.0; + + override function get_volume():Float + { + return _volume; + } + + override function set_volume(value:Float):Float + { + _volume = super.set_volume(value); + + if (playerVocals != null) + { + playerVocals.volume = playerVolume * _volume; + } + + if (opponentVocals != null) + { + opponentVocals.volume = opponentVolume * _volume; + } + + return _volume; + } } diff --git a/source/funkin/audio/visualize/PolygonSpectogram.hx b/source/funkin/audio/visualize/PolygonSpectogram.hx index f1ccebdb7..c9f1c5dbf 100644 --- a/source/funkin/audio/visualize/PolygonSpectogram.hx +++ b/source/funkin/audio/visualize/PolygonSpectogram.hx @@ -10,146 +10,141 @@ import lime.utils.Int16Array; class PolygonSpectogram extends MeshRender { - var sampleRate:Int; + var sampleRate:Int; - public var vis:VisShit; - public var visType:VISTYPE = UPDATED; - public var daHeight:Float = FlxG.height; - public var realtimeVisLenght:Float = 0.2; + public var vis:VisShit; + public var visType:VISTYPE = UPDATED; + public var daHeight:Float = FlxG.height; + public var realtimeVisLenght:Float = 0.2; - var numSamples:Int = 0; - var setBuffer:Bool = false; + var numSamples:Int = 0; + var setBuffer:Bool = false; - public var audioData:Int16Array; - public var detail:Float = 1; + public var audioData:Int16Array; + public var detail:Float = 1; - public var thickness:Float = 2; - public var waveAmplitude:Int = 100; + public var thickness:Float = 2; + public var waveAmplitude:Int = 100; - public function new(daSound:FlxSound, ?col:FlxColor = FlxColor.WHITE, ?height:Float = 720, ?detail:Float = 1) - { - super(0, 0, col); + public function new(daSound:FlxSound, ?col:FlxColor = FlxColor.WHITE, ?height:Float = 720, ?detail:Float = 1) + { + super(0, 0, col); - setSound(daSound); + setSound(daSound); - if (height != null) - this.daHeight = height; + if (height != null) this.daHeight = height; - this.detail = detail; + this.detail = detail; - // col not in yet - } + // col not in yet + } - public function setSound(daSound:FlxSound) - { - vis = new VisShit(daSound); - } + public function setSound(daSound:FlxSound) + { + vis = new VisShit(daSound); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - switch (visType) - { - case UPDATED: - realtimeVis(); - default: - } - } + switch (visType) + { + case UPDATED: + realtimeVis(); + default: + } + } - var prevAudioData:Int16Array; + var prevAudioData:Int16Array; - /** - * Generates and draws a section of the audio data to a visual waveform - * @param start start of the song in milliseconds - * @param seconds how long to generate (also in milliseconds) - */ - public function generateSection(start:Float = 0, seconds:Float = 1):Void - { - checkAndSetBuffer(); + /** + * Generates and draws a section of the audio data to a visual waveform + * @param start start of the song in milliseconds + * @param seconds how long to generate (also in milliseconds) + */ + public function generateSection(start:Float = 0, seconds:Float = 1):Void + { + checkAndSetBuffer(); - if (setBuffer) - { - clear(); + if (setBuffer) + { + clear(); - start = Math.max(start, 0); + start = Math.max(start, 0); - var samplesToGen:Int = Std.int(sampleRate * seconds); - // gets which sample to start at - var startSample:Int = Std.int(FlxMath.remapToRange(start, 0, vis.snd.length, 0, numSamples)); + var samplesToGen:Int = Std.int(sampleRate * seconds); + // gets which sample to start at + var startSample:Int = Std.int(FlxMath.remapToRange(start, 0, vis.snd.length, 0, numSamples)); - var prevPoint:FlxPoint = new FlxPoint(); + var prevPoint:FlxPoint = new FlxPoint(); - var funnyPixels:Int = Std.int(daHeight); // sorta redundant but just need it for different var... + var funnyPixels:Int = Std.int(daHeight); // sorta redundant but just need it for different var... - if (prevAudioData == audioData.subarray(startSample, startSample + samplesToGen)) - return; // optimize / finish funciton here, no need to re-render + if (prevAudioData == audioData.subarray(startSample, startSample + samplesToGen)) return; // optimize / finish funciton here, no need to re-render - prevAudioData = audioData.subarray(startSample, samplesToGen); + prevAudioData = audioData.subarray(startSample, samplesToGen); - for (i in 0...funnyPixels) - { - var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, funnyPixels, startSample, startSample + samplesToGen)); - var curAud:CurAudioInfo = VisShit.getCurAud(audioData, sampleApprox); + for (i in 0...funnyPixels) + { + var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, funnyPixels, startSample, startSample + samplesToGen)); + var curAud:CurAudioInfo = VisShit.getCurAud(audioData, sampleApprox); - var coolPoint:FlxPoint = new FlxPoint(); - coolPoint.x = (curAud.balanced * waveAmplitude); - coolPoint.y = (i / funnyPixels * daHeight); + var coolPoint:FlxPoint = new FlxPoint(); + coolPoint.x = (curAud.balanced * waveAmplitude); + coolPoint.y = (i / funnyPixels * daHeight); - add_quad(prevPoint.x, prevPoint.y, prevPoint.x - + thickness, prevPoint.y, coolPoint.x, coolPoint.y, coolPoint.x - + thickness, - coolPoint.y - + thickness); + add_quad(prevPoint.x, prevPoint.y, prevPoint.x + + thickness, prevPoint.y, coolPoint.x, coolPoint.y, coolPoint.x + + thickness, coolPoint.y + + thickness); - prevPoint.x = coolPoint.x; - prevPoint.y = coolPoint.y; - } - } - } + prevPoint.x = coolPoint.x; + prevPoint.y = coolPoint.y; + } + } + } - var curTime:Float = 0; + var curTime:Float = 0; - function realtimeVis():Void - { - if (vis.snd != null) - { - if (curTime != vis.snd.time) - { - // trace("DOIN SHIT" + FlxG.random.int(0, 200)); + function realtimeVis():Void + { + if (vis.snd != null) + { + if (curTime != vis.snd.time) + { + // trace("DOIN SHIT" + FlxG.random.int(0, 200)); - if (vis.snd.playing) - curTime = vis.snd.time; - else - { - if (Math.abs(curTime - vis.snd.time) > 10) - curTime = FlxMath.lerp(curTime, vis.snd.time, 0.5); - } + if (vis.snd.playing) curTime = vis.snd.time; + else + { + if (Math.abs(curTime - vis.snd.time) > 10) curTime = FlxMath.lerp(curTime, vis.snd.time, 0.5); + } - curTime = vis.snd.time; + curTime = vis.snd.time; - generateSection(vis.snd.time, realtimeVisLenght); - } - } - } + generateSection(vis.snd.time, realtimeVisLenght); + } + } + } - public function checkAndSetBuffer() - { - vis.checkAndSetBuffer(); + public function checkAndSetBuffer() + { + vis.checkAndSetBuffer(); - if (vis.setBuffer) - { - audioData = vis.audioData; - sampleRate = vis.sampleRate; - setBuffer = vis.setBuffer; - numSamples = Std.int(audioData.length / 2); - } - } + if (vis.setBuffer) + { + audioData = vis.audioData; + sampleRate = vis.sampleRate; + setBuffer = vis.setBuffer; + numSamples = Std.int(audioData.length / 2); + } + } } enum VISTYPE { - STATIC; - UPDATED; - FREQUENCIES; + STATIC; + UPDATED; + FREQUENCIES; } diff --git a/source/funkin/audiovis/ABot.hx b/source/funkin/audiovis/ABot.hx index 51df8bb40..11c123fb2 100644 --- a/source/funkin/audiovis/ABot.hx +++ b/source/funkin/audiovis/ABot.hx @@ -5,8 +5,8 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; class ABot extends FlxTypedSpriteGroup { - public function new() - { - super(); - } + public function new() + { + super(); + } } diff --git a/source/funkin/audiovis/ABotVis.hx b/source/funkin/audiovis/ABotVis.hx index 07b1b51d3..482c1b00e 100644 --- a/source/funkin/audiovis/ABotVis.hx +++ b/source/funkin/audiovis/ABotVis.hx @@ -13,152 +13,149 @@ using Lambda; class ABotVis extends FlxTypedSpriteGroup { - public var vis:VisShit; + public var vis:VisShit; - var volumes:Array = []; + var volumes:Array = []; - public function new(snd:FlxSound) - { - super(); + public function new(snd:FlxSound) + { + super(); - vis = new VisShit(snd); - // vis.snd = snd; + vis = new VisShit(snd); + // vis.snd = snd; - var visFrms:FlxAtlasFrames = Paths.getSparrowAtlas('aBotViz'); + var visFrms:FlxAtlasFrames = Paths.getSparrowAtlas('aBotViz'); - for (lol in 1...8) - { - // pushes initial value - volumes.push(0.0); + for (lol in 1...8) + { + // pushes initial value + volumes.push(0.0); - var viz:FlxSprite = new FlxSprite(50 * lol, 0); - viz.frames = visFrms; - add(viz); + var viz:FlxSprite = new FlxSprite(50 * lol, 0); + viz.frames = visFrms; + add(viz); - var visStr = 'VIZ'; - if (lol == 5) - visStr = 'viz'; // lol makes it lowercase, accomodates for art that I dont wanna rename! + var visStr = 'VIZ'; + if (lol == 5) visStr = 'viz'; // lol makes it lowercase, accomodates for art that I dont wanna rename! - viz.animation.addByPrefix('VIZ', visStr + lol, 0); - viz.animation.play('VIZ', false, false, -1); - } - } + viz.animation.addByPrefix('VIZ', visStr + lol, 0); + viz.animation.play('VIZ', false, false, -1); + } + } - override function update(elapsed:Float) - { - // updateViz(); + override function update(elapsed:Float) + { + // updateViz(); - updateFFT(elapsed); + updateFFT(elapsed); - super.update(elapsed); - } + super.update(elapsed); + } - function updateFFT(elapsed:Float) - { - if (vis.snd != null) - { - vis.checkAndSetBuffer(); + function updateFFT(elapsed:Float) + { + if (vis.snd != null) + { + vis.checkAndSetBuffer(); - if (vis.setBuffer) - { - var remappedShit:Int = 0; + if (vis.setBuffer) + { + var remappedShit:Int = 0; - if (vis.snd.playing) - remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); - else - remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, vis.numSamples)); + if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); + else + remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, vis.numSamples)); - var fftSamples:Array = []; + var fftSamples:Array = []; - var swagBucks = remappedShit; + var swagBucks = remappedShit; - for (i in remappedShit...remappedShit + (Std.int((44100 * (1 / 144))))) - { - var left = vis.audioData[swagBucks] / 32767; - var right = vis.audioData[swagBucks + 1] / 32767; + for (i in remappedShit...remappedShit + (Std.int((44100 * (1 / 144))))) + { + var left = vis.audioData[swagBucks] / 32767; + var right = vis.audioData[swagBucks + 1] / 32767; - var balanced = (left + right) / 2; + var balanced = (left + right) / 2; - swagBucks += 2; + swagBucks += 2; - fftSamples.push(balanced); - } + fftSamples.push(balanced); + } - var freqShit = vis.funnyFFT(fftSamples); + var freqShit = vis.funnyFFT(fftSamples); - for (i in 0...group.members.length) - { - var getSliceShit = function(s:Int) - { - var powShit = FlxMath.remapToRange(s, 0, group.members.length, 0, CoolUtil.coolBaseLog(10, freqShit[0].length)); - return Math.round(Math.pow(10, powShit)); - }; + for (i in 0...group.members.length) + { + var getSliceShit = function(s:Int) + { + var powShit = FlxMath.remapToRange(s, 0, group.members.length, 0, CoolUtil.coolBaseLog(10, freqShit[0].length)); + return Math.round(Math.pow(10, powShit)); + }; - // var powShit:Float = getSliceShit(i); - var hzSliced:Int = getSliceShit(i); + // var powShit:Float = getSliceShit(i); + var hzSliced:Int = getSliceShit(i); - var sliceLength:Int = Std.int(freqShit[0].length / group.members.length); + var sliceLength:Int = Std.int(freqShit[0].length / group.members.length); - var volSlice = freqShit[0].slice(hzSliced, getSliceShit(i + 1)); + var volSlice = freqShit[0].slice(hzSliced, getSliceShit(i + 1)); - var avgVel:Float = 0; + var avgVel:Float = 0; - for (slice in volSlice) - { - avgVel += slice; - } + for (slice in volSlice) + { + avgVel += slice; + } - avgVel /= volSlice.length; + avgVel /= volSlice.length; - avgVel *= 10000000; + avgVel *= 10000000; - volumes[i] += avgVel - (elapsed * (volumes[i] * 50)); + volumes[i] += avgVel - (elapsed * (volumes[i] * 50)); - var animFrame:Int = Std.int(volumes[i]); + var animFrame:Int = Std.int(volumes[i]); - animFrame = Math.floor(Math.min(5, animFrame)); - animFrame = Math.floor(Math.max(0, animFrame)); + animFrame = Math.floor(Math.min(5, animFrame)); + animFrame = Math.floor(Math.max(0, animFrame)); - animFrame = Std.int(Math.abs(animFrame - 5)); // shitty dumbass flip, cuz dave got da shit backwards lol! + animFrame = Std.int(Math.abs(animFrame - 5)); // shitty dumbass flip, cuz dave got da shit backwards lol! - group.members[i].animation.curAnim.curFrame = animFrame; - if (FlxG.keys.justPressed.U) - { - trace(avgVel); - trace(group.members[i].animation.curAnim.curFrame); - } - } + group.members[i].animation.curAnim.curFrame = animFrame; + if (FlxG.keys.justPressed.U) + { + trace(avgVel); + trace(group.members[i].animation.curAnim.curFrame); + } + } - // group.members[0].animation.curAnim.curFrame = - } - } - } + // group.members[0].animation.curAnim.curFrame = + } + } + } - public function updateViz() - { - if (vis.snd != null) - { - var remappedShit:Int = 0; - vis.checkAndSetBuffer(); + public function updateViz() + { + if (vis.snd != null) + { + var remappedShit:Int = 0; + vis.checkAndSetBuffer(); - if (vis.setBuffer) - { - // var startingSample:Int = Std.int(FlxMath.remapToRange) + if (vis.setBuffer) + { + // var startingSample:Int = Std.int(FlxMath.remapToRange) - if (vis.snd.playing) - remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); + if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); - for (i in 0...group.members.length) - { - var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, remappedShit, remappedShit + 500)); + for (i in 0...group.members.length) + { + var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, remappedShit, remappedShit + 500)); - var left = vis.audioData[sampleApprox] / 32767; + var left = vis.audioData[sampleApprox] / 32767; - var animFrame:Int = Std.int(FlxMath.remapToRange(left, -1, 1, 0, 6)); + var animFrame:Int = Std.int(FlxMath.remapToRange(left, -1, 1, 0, 6)); - group.members[i].animation.curAnim.curFrame = animFrame; - } - } - } - } + group.members[i].animation.curAnim.curFrame = animFrame; + } + } + } + } } diff --git a/source/funkin/audiovis/SpectogramSprite.hx b/source/funkin/audiovis/SpectogramSprite.hx index 8d33f80be..62291403c 100644 --- a/source/funkin/audiovis/SpectogramSprite.hx +++ b/source/funkin/audiovis/SpectogramSprite.hx @@ -19,265 +19,263 @@ using flixel.util.FlxSpriteUtil; class SpectogramSprite extends FlxTypedSpriteGroup { - var sampleRate:Int; + var sampleRate:Int; - var lengthOfShit:Int = 500; + var lengthOfShit:Int = 500; - public var visType:VISTYPE = UPDATED; + public var visType:VISTYPE = UPDATED; - public var col:Int = FlxColor.WHITE; - public var daHeight:Float = FlxG.height; + public var col:Int = FlxColor.WHITE; + public var daHeight:Float = FlxG.height; - public var vis:VisShit; + public var vis:VisShit; - public function new(daSound:FlxSound, ?col:FlxColor = FlxColor.WHITE, ?height:Float = 720, ?amnt:Int = 500) - { - super(); + public function new(daSound:FlxSound, ?col:FlxColor = FlxColor.WHITE, ?height:Float = 720, ?amnt:Int = 500) + { + super(); - vis = new VisShit(daSound); - this.col = col; - this.daHeight = height; - lengthOfShit = amnt; + vis = new VisShit(daSound); + this.col = col; + this.daHeight = height; + lengthOfShit = amnt; - regenLineShit(); + regenLineShit(); - // makeGraphic(200, 200, FlxColor.BLACK); - } + // makeGraphic(200, 200, FlxColor.BLACK); + } - public function regenLineShit():Void - { - for (i in 0...lengthOfShit) - { - var lineShit:FlxSprite = new FlxSprite(100, i / lengthOfShit * daHeight).makeGraphic(1, 1, col); - lineShit.active = false; - lineShit.ID = i; - add(lineShit); - } - } + public function regenLineShit():Void + { + for (i in 0...lengthOfShit) + { + var lineShit:FlxSprite = new FlxSprite(100, i / lengthOfShit * daHeight).makeGraphic(1, 1, col); + lineShit.active = false; + lineShit.ID = i; + add(lineShit); + } + } - var setBuffer:Bool = false; + var setBuffer:Bool = false; - public var audioData:Int16Array; + public var audioData:Int16Array; - var numSamples:Int = 0; + var numSamples:Int = 0; - public var wavOptimiz:Int = 10; + public var wavOptimiz:Int = 10; - override function update(elapsed:Float) - { - switch (visType) - { - case UPDATED: - updateVisulizer(); + override function update(elapsed:Float) + { + switch (visType) + { + case UPDATED: + updateVisulizer(); - case FREQUENCIES: - updateFFT(); - default: - } + case FREQUENCIES: + updateFFT(); + default: + } - forEach(spr -> - { - spr.visible = spr.ID % wavOptimiz == 0; - }); + forEach(spr -> + { + spr.visible = spr.ID % wavOptimiz == 0; + }); - // if visType is static, call updateVisulizer() manually whenever you want to update it! + // if visType is static, call updateVisulizer() manually whenever you want to update it! - super.update(elapsed); - } + super.update(elapsed); + } - /** - * @param start is the start in milliseconds? - */ - public function generateSection(start:Float = 0, seconds:Float = 1):Void - { - checkAndSetBuffer(); + /** + * @param start is the start in milliseconds? + */ + public function generateSection(start:Float = 0, seconds:Float = 1):Void + { + checkAndSetBuffer(); - // vis.checkAndSetBuffer(); + // vis.checkAndSetBuffer(); - if (setBuffer) - { - var samplesToGen:Int = Std.int(sampleRate * seconds); - var startingSample:Int = Std.int(FlxMath.remapToRange(start, 0, vis.snd.length, 0, numSamples)); + if (setBuffer) + { + var samplesToGen:Int = Std.int(sampleRate * seconds); + var startingSample:Int = Std.int(FlxMath.remapToRange(start, 0, vis.snd.length, 0, numSamples)); - var prevLine:FlxPoint = new FlxPoint(); + var prevLine:FlxPoint = new FlxPoint(); - for (i in 0...group.members.length) - { - var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, startingSample, startingSample + samplesToGen)); - var curAud:CurAudioInfo = VisShit.getCurAud(audioData, sampleApprox); + for (i in 0...group.members.length) + { + var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, startingSample, startingSample + samplesToGen)); + var curAud:CurAudioInfo = VisShit.getCurAud(audioData, sampleApprox); - var swagheight:Int = 200; + var swagheight:Int = 200; - group.members[i].x = prevLine.x; - group.members[i].y = prevLine.y; + group.members[i].x = prevLine.x; + group.members[i].y = prevLine.y; - prevLine.x = (curAud.balanced * swagheight / 2 + swagheight / 2) + x; - prevLine.y = (i / group.members.length * daHeight) + y; + prevLine.x = (curAud.balanced * swagheight / 2 + swagheight / 2) + x; + prevLine.y = (i / group.members.length * daHeight) + y; - var line = FlxPoint.get(prevLine.x - group.members[i].x, prevLine.y - group.members[i].y); + var line = FlxPoint.get(prevLine.x - group.members[i].x, prevLine.y - group.members[i].y); - group.members[i].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); - group.members[i].angle = line.degrees; - } + group.members[i].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); + group.members[i].angle = line.degrees; + } - wavOptimiz = 1; // hard set wavOptimiz to 1 so its a pure thing - } - } + wavOptimiz = 1; // hard set wavOptimiz to 1 so its a pure thing + } + } - public function checkAndSetBuffer() - { - vis.checkAndSetBuffer(); + public function checkAndSetBuffer() + { + vis.checkAndSetBuffer(); - if (vis.setBuffer) - { - audioData = vis.audioData; - sampleRate = vis.sampleRate; - setBuffer = vis.setBuffer; - numSamples = Std.int(audioData.length / 2); - } - } + if (vis.setBuffer) + { + audioData = vis.audioData; + sampleRate = vis.sampleRate; + setBuffer = vis.setBuffer; + numSamples = Std.int(audioData.length / 2); + } + } - var doAnim:Bool = false; - var frameCounter:Int = 0; + var doAnim:Bool = false; + var frameCounter:Int = 0; - public function updateFFT() - { - if (vis.snd != null) - { - var remappedShit:Int = 0; + public function updateFFT() + { + if (vis.snd != null) + { + var remappedShit:Int = 0; - checkAndSetBuffer(); + checkAndSetBuffer(); - if (!doAnim) - { - frameCounter++; + if (!doAnim) + { + frameCounter++; - if (frameCounter >= 0) - { - frameCounter = 0; - doAnim = true; - } - } + if (frameCounter >= 0) + { + frameCounter = 0; + doAnim = true; + } + } - if (setBuffer && doAnim) - { - doAnim = false; + if (setBuffer && doAnim) + { + doAnim = false; - if (vis.snd.playing) - remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, numSamples)); - else - remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, numSamples)); + if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, numSamples)); + else + remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, numSamples)); - var fftSamples:Array = []; - var i = remappedShit; + var fftSamples:Array = []; + var i = remappedShit; - for (sample in remappedShit...remappedShit + (Std.int((44100 * (1 / 144))))) - { - var curAud:CurAudioInfo = VisShit.getCurAud(audioData, i); - i += 2; + for (sample in remappedShit...remappedShit + (Std.int((44100 * (1 / 144))))) + { + var curAud:CurAudioInfo = VisShit.getCurAud(audioData, i); + i += 2; - fftSamples.push(curAud.balanced); - } + fftSamples.push(curAud.balanced); + } - var freqShit = vis.funnyFFT(fftSamples); - var prevLine:FlxPoint = new FlxPoint(); - var swagheight:Int = 200; + var freqShit = vis.funnyFFT(fftSamples); + var prevLine:FlxPoint = new FlxPoint(); + var swagheight:Int = 200; - for (i in 0...group.members.length) - { - // needs to be exponential growth / scaling - // still need to optmize the FFT to run better, gets only samples needed? - // not every frequency is built the same! - // 20hz to 40z is a LOT of subtle low ends, but somethin like 20,000hz to 20,020hz, the difference is NOT the same! + for (i in 0...group.members.length) + { + // needs to be exponential growth / scaling + // still need to optmize the FFT to run better, gets only samples needed? + // not every frequency is built the same! + // 20hz to 40z is a LOT of subtle low ends, but somethin like 20,000hz to 20,020hz, the difference is NOT the same! - var powedShit:Float = FlxMath.remapToRange(i, 0, group.members.length, 0, 4); + var powedShit:Float = FlxMath.remapToRange(i, 0, group.members.length, 0, 4); - // a value between 10hz and 100Khz - var hzPicker:Float = Math.pow(10, powedShit); + // a value between 10hz and 100Khz + var hzPicker:Float = Math.pow(10, powedShit); - // var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, startingSample, startingSample + samplesToGen)); - var remappedFreq:Int = Std.int(FlxMath.remapToRange(hzPicker, 0, 10000, 0, freqShit[0].length - 1)); + // var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, startingSample, startingSample + samplesToGen)); + var remappedFreq:Int = Std.int(FlxMath.remapToRange(hzPicker, 0, 10000, 0, freqShit[0].length - 1)); - group.members[i].x = prevLine.x; - group.members[i].y = prevLine.y; + group.members[i].x = prevLine.x; + group.members[i].y = prevLine.y; - var freqPower:Float = 0; + var freqPower:Float = 0; - for (pow in 0...freqShit.length) - freqPower += freqShit[pow][remappedFreq]; + for (pow in 0...freqShit.length) + freqPower += freqShit[pow][remappedFreq]; - freqPower /= freqShit.length; - var freqIDK:Float = FlxMath.remapToRange(freqPower, 0, 0.000005, 0, 50); + freqPower /= freqShit.length; + var freqIDK:Float = FlxMath.remapToRange(freqPower, 0, 0.000005, 0, 50); - prevLine.x = (freqIDK * swagheight / 2 + swagheight / 2) + x; - prevLine.y = (i / group.members.length * daHeight) + y; + prevLine.x = (freqIDK * swagheight / 2 + swagheight / 2) + x; + prevLine.y = (i / group.members.length * daHeight) + y; - var line = FlxPoint.get(prevLine.x - group.members[i].x, prevLine.y - group.members[i].y); + var line = FlxPoint.get(prevLine.x - group.members[i].x, prevLine.y - group.members[i].y); - // dont draw a line until i figure out a nicer way to view da spikes and shit idk lol! - // group.members[i].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); - // group.members[i].angle = line.degrees; - } - } - } - } + // dont draw a line until i figure out a nicer way to view da spikes and shit idk lol! + // group.members[i].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); + // group.members[i].angle = line.degrees; + } + } + } + } - var curTime:Float = 0; + var curTime:Float = 0; - public function updateVisulizer():Void - { - if (vis.snd != null) - { - var remappedShit:Int = 0; + public function updateVisulizer():Void + { + if (vis.snd != null) + { + var remappedShit:Int = 0; - checkAndSetBuffer(); + checkAndSetBuffer(); - if (setBuffer) - { - if (vis.snd.playing) - remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, numSamples)); - else - { - if (curTime == Conductor.songPosition) - { - wavOptimiz = 3; - return; // already did shit, so finishes function early - } + if (setBuffer) + { + if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, numSamples)); + else + { + if (curTime == Conductor.songPosition) + { + wavOptimiz = 3; + return; // already did shit, so finishes function early + } - curTime = Conductor.songPosition; + curTime = Conductor.songPosition; - remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, numSamples)); - } + remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, numSamples)); + } - wavOptimiz = 8; + wavOptimiz = 8; - var i = remappedShit; - var prevLine:FlxPoint = new FlxPoint(); + var i = remappedShit; + var prevLine:FlxPoint = new FlxPoint(); - var swagheight:Int = 200; + var swagheight:Int = 200; - for (sample in remappedShit...remappedShit + lengthOfShit) - { - var curAud:CurAudioInfo = VisShit.getCurAud(audioData, i); + for (sample in remappedShit...remappedShit + lengthOfShit) + { + var curAud:CurAudioInfo = VisShit.getCurAud(audioData, i); - i += 2; + i += 2; - var remappedSample:Float = FlxMath.remapToRange(sample, remappedShit, remappedShit + lengthOfShit, 0, lengthOfShit - 1); + var remappedSample:Float = FlxMath.remapToRange(sample, remappedShit, remappedShit + lengthOfShit, 0, lengthOfShit - 1); - group.members[Std.int(remappedSample)].x = prevLine.x; - group.members[Std.int(remappedSample)].y = prevLine.y; - // group.members[0].y = prevLine.y; + group.members[Std.int(remappedSample)].x = prevLine.x; + group.members[Std.int(remappedSample)].y = prevLine.y; + // group.members[0].y = prevLine.y; - // FlxSpriteUtil.drawLine(this, prevLine.x, prevLine.y, width * remappedSample, left * height / 2 + height / 2); - prevLine.x = (curAud.balanced * swagheight / 2 + swagheight / 2) + x; - prevLine.y = (Std.int(remappedSample) / lengthOfShit * daHeight) + y; + // FlxSpriteUtil.drawLine(this, prevLine.x, prevLine.y, width * remappedSample, left * height / 2 + height / 2); + prevLine.x = (curAud.balanced * swagheight / 2 + swagheight / 2) + x; + prevLine.y = (Std.int(remappedSample) / lengthOfShit * daHeight) + y; - var line = FlxPoint.get(prevLine.x - group.members[Std.int(remappedSample)].x, prevLine.y - group.members[Std.int(remappedSample)].y); + var line = FlxPoint.get(prevLine.x - group.members[Std.int(remappedSample)].x, prevLine.y - group.members[Std.int(remappedSample)].y); - group.members[Std.int(remappedSample)].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); - group.members[Std.int(remappedSample)].angle = line.degrees; - } - } - } - } + group.members[Std.int(remappedSample)].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); + group.members[Std.int(remappedSample)].angle = line.degrees; + } + } + } + } } diff --git a/source/funkin/audiovis/VisShit.hx b/source/funkin/audiovis/VisShit.hx index f15a3c37a..3dd7f5aaa 100644 --- a/source/funkin/audiovis/VisShit.hx +++ b/source/funkin/audiovis/VisShit.hx @@ -11,141 +11,139 @@ using Lambda; class VisShit { - public var snd:FlxSound; - public var setBuffer:Bool = false; - public var audioData:Int16Array; - public var sampleRate:Int = 44100; // default, ez? - public var numSamples:Int = 0; + public var snd:FlxSound; + public var setBuffer:Bool = false; + public var audioData:Int16Array; + public var sampleRate:Int = 44100; // default, ez? + public var numSamples:Int = 0; - public function new(snd:FlxSound) - { - this.snd = snd; - } + public function new(snd:FlxSound) + { + this.snd = snd; + } - public function funnyFFT(samples:Array, ?skipped:Int = 1):Array> - { - // nab multiple samples at once in while / for loops? + public function funnyFFT(samples:Array, ?skipped:Int = 1):Array> + { + // nab multiple samples at once in while / for loops? - var fs:Float = 44100 / skipped; // sample rate shit? + var fs:Float = 44100 / skipped; // sample rate shit? - final fftN = 1024; - final halfN = Std.int(fftN / 2); - final overlap = 0.5; - final hop = Std.int(fftN * (1 - overlap)); + final fftN = 1024; + final halfN = Std.int(fftN / 2); + final overlap = 0.5; + final hop = Std.int(fftN * (1 - overlap)); - // window function to compensate for overlapping - final a0 = 0.5; // => Hann(ing) window - final window = (n:Int) -> a0 - (1 - a0) * Math.cos(2 * Math.PI * n / fftN); + // window function to compensate for overlapping + final a0 = 0.5; // => Hann(ing) window + final window = (n:Int) -> a0 - (1 - a0) * Math.cos(2 * Math.PI * n / fftN); - // NOTE TO SELF FOR WHEN I WAKE UP + // NOTE TO SELF FOR WHEN I WAKE UP - // helpers, note that spectrum indexes suppose non-negative frequencies - final binSize = fs / fftN; - final indexToFreq = function(k:Int) - { - var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, CoolUtil.coolBaseLog(10, halfN)); // 4.3 is almost the log of 20Khz or so. Close enuf lol + // helpers, note that spectrum indexes suppose non-negative frequencies + final binSize = fs / fftN; + final indexToFreq = function(k:Int) + { + var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, CoolUtil.coolBaseLog(10, halfN)); // 4.3 is almost the log of 20Khz or so. Close enuf lol - return 1.0 * (Math.pow(10, powShit)); // we need the `1.0` to avoid overflows - }; + return 1.0 * (Math.pow(10, powShit)); // we need the `1.0` to avoid overflows + }; - // "melodic" band-pass filter - final minFreq = 20.70; - final maxFreq = 4000.01; - final melodicBandPass = function(k:Int, s:Float) - { - final freq = indexToFreq(k); - final filter = freq > minFreq - binSize && freq < maxFreq + binSize ? 1 : 0; - return s; - }; + // "melodic" band-pass filter + final minFreq = 20.70; + final maxFreq = 4000.01; + final melodicBandPass = function(k:Int, s:Float) + { + final freq = indexToFreq(k); + final filter = freq > minFreq - binSize && freq < maxFreq + binSize ? 1 : 0; + return s; + }; - var freqOutput:Array> = []; + var freqOutput:Array> = []; - var c = 0; // index where each chunk begins - var indexOfArray:Int = 0; - while (c < samples.length) - { - // take a chunk (zero-padded if needed) and apply the window - final chunk = [ - for (n in 0...fftN) - (c + n < samples.length ? samples[c + n] : 0.0) * window(n) - ]; + var c = 0; // index where each chunk begins + var indexOfArray:Int = 0; + while (c < samples.length) + { + // take a chunk (zero-padded if needed) and apply the window + final chunk = [ + for (n in 0...fftN) + (c + n < samples.length ? samples[c + n] : 0.0) * window(n) + ]; - // compute positive spectrum with sampling correction and BP filter - final freqs = FFT.rfft(chunk).map(z -> z.scale(1 / fftN).magnitude).mapi(melodicBandPass); + // compute positive spectrum with sampling correction and BP filter + final freqs = FFT.rfft(chunk).map(z -> z.scale(1 / fftN).magnitude).mapi(melodicBandPass); - freqOutput.push([]); + freqOutput.push([]); - // if (FlxG.keys.justPressed.M) - // trace(FFT.rfft(chunk).map(z -> z.scale(1 / fs).magnitude)); + // if (FlxG.keys.justPressed.M) + // trace(FFT.rfft(chunk).map(z -> z.scale(1 / fs).magnitude)); - // find spectral peaks and their instantaneous frequencies - for (k => s in freqs) - { - final time = c / fs; - final freq = indexToFreq(k); - final power = s * s; - if (FlxG.keys.justPressed.I) - { - trace(k); + // find spectral peaks and their instantaneous frequencies + for (k => s in freqs) + { + final time = c / fs; + final freq = indexToFreq(k); + final power = s * s; + if (FlxG.keys.justPressed.I) + { + trace(k); - haxe.Log.trace('${time};${freq};${power}', null); - } - if (freq < maxFreq) - freqOutput[indexOfArray].push(power); - // - } - // haxe.Log.trace("", null); + haxe.Log.trace('${time};${freq};${power}', null); + } + if (freq < maxFreq) freqOutput[indexOfArray].push(power); + // + } + // haxe.Log.trace("", null); - indexOfArray++; - // move to next (overlapping) chunk - c += hop; - } + indexOfArray++; + // move to next (overlapping) chunk + c += hop; + } - if (FlxG.keys.justPressed.C) - trace(freqOutput.length); + if (FlxG.keys.justPressed.C) trace(freqOutput.length); - return freqOutput; - } + return freqOutput; + } - public static function getCurAud(aud:Int16Array, index:Int):CurAudioInfo - { - var left = aud[index] / 32767; - var right = aud[index + 2] / 32767; - var balanced = (left + right) / 2; + public static function getCurAud(aud:Int16Array, index:Int):CurAudioInfo + { + var left = aud[index] / 32767; + var right = aud[index + 2] / 32767; + var balanced = (left + right) / 2; - var funny:CurAudioInfo = {left: left, right: right, balanced: balanced}; + var funny:CurAudioInfo = {left: left, right: right, balanced: balanced}; - return funny; - } + return funny; + } - public function checkAndSetBuffer() - { - if (snd != null && snd.playing) - { - if (!setBuffer) - { - // Math.pow3 - @:privateAccess - var buf = snd._channel.__source.buffer; + public function checkAndSetBuffer() + { + if (snd != null && snd.playing) + { + if (!setBuffer) + { + // Math.pow3 + @:privateAccess + var buf = snd._channel.__source.buffer; - // @:privateAccess - audioData = cast buf.data; // jank and hacky lol! kinda busted on HTML5 also!! - sampleRate = buf.sampleRate; + // @:privateAccess + audioData = cast buf.data; // jank and hacky lol! kinda busted on HTML5 also!! + sampleRate = buf.sampleRate; - trace('got audio buffer shit'); - trace(sampleRate); - trace(buf.bitsPerSample); + trace('got audio buffer shit'); + trace(sampleRate); + trace(buf.bitsPerSample); - setBuffer = true; - numSamples = Std.int(audioData.length / 2); - } - } - } + setBuffer = true; + numSamples = Std.int(audioData.length / 2); + } + } + } } typedef CurAudioInfo = { - var left:Float; - var right:Float; - var balanced:Float; + var left:Float; + var right:Float; + var balanced:Float; } diff --git a/source/funkin/audiovis/dsp/Complex.hx b/source/funkin/audiovis/dsp/Complex.hx index eeff9679f..523549e99 100644 --- a/source/funkin/audiovis/dsp/Complex.hx +++ b/source/funkin/audiovis/dsp/Complex.hx @@ -1,80 +1,80 @@ package funkin.audiovis.dsp; /** - Complex number representation. + Complex number representation. **/ @:forward(real, imag) @:notNull @:pure abstract Complex({ - final real:Float; - final imag:Float; + final real:Float; + final imag:Float; }) { - public inline function new(real:Float, imag:Float) - this = {real: real, imag: imag}; + public inline function new(real:Float, imag:Float) + this = {real: real, imag: imag}; - /** - Makes a Complex number with the given Float as its real part and a zero imag part. - **/ - @:from - public static inline function fromReal(r:Float) - return new Complex(r, 0); + /** + Makes a Complex number with the given Float as its real part and a zero imag part. + **/ + @:from + public static inline function fromReal(r:Float) + return new Complex(r, 0); - /** - Complex argument, in radians. - **/ - public var angle(get, never):Float; + /** + Complex argument, in radians. + **/ + public var angle(get, never):Float; - inline function get_angle() - return Math.atan2(this.imag, this.real); + inline function get_angle() + return Math.atan2(this.imag, this.real); - /** - Complex module. - **/ - public var magnitude(get, never):Float; + /** + Complex module. + **/ + public var magnitude(get, never):Float; - inline function get_magnitude() - return Math.sqrt(this.real * this.real + this.imag * this.imag); + inline function get_magnitude() + return Math.sqrt(this.real * this.real + this.imag * this.imag); - @:op(A + B) - public inline function add(rhs:Complex):Complex - return new Complex(this.real + rhs.real, this.imag + rhs.imag); + @:op(A + B) + public inline function add(rhs:Complex):Complex + return new Complex(this.real + rhs.real, this.imag + rhs.imag); - @:op(A - B) - public inline function sub(rhs:Complex):Complex - return new Complex(this.real - rhs.real, this.imag - rhs.imag); + @:op(A - B) + public inline function sub(rhs:Complex):Complex + return new Complex(this.real - rhs.real, this.imag - rhs.imag); - @:op(A * B) - public inline function mult(rhs:Complex):Complex - return new Complex(this.real * rhs.real - this.imag * rhs.imag, this.real * rhs.imag + this.imag * rhs.real); + @:op(A * B) + public inline function mult(rhs:Complex):Complex + return new Complex(this.real * rhs.real - this.imag * rhs.imag, this.real * rhs.imag + this.imag * rhs.real); - /** - Returns the complex conjugate, does not modify this object. - **/ - public inline function conj():Complex - return new Complex(this.real, -this.imag); + /** + Returns the complex conjugate, does not modify this object. + **/ + public inline function conj():Complex + return new Complex(this.real, -this.imag); - /** - Multiplication by a real factor, does not modify this object. - **/ - public inline function scale(k:Float):Complex - return new Complex(this.real * k, this.imag * k); + /** + Multiplication by a real factor, does not modify this object. + **/ + public inline function scale(k:Float):Complex + return new Complex(this.real * k, this.imag * k); - public inline function copy():Complex - return new Complex(this.real, this.imag); + public inline function copy():Complex + return new Complex(this.real, this.imag); - /** - The imaginary unit. - **/ - public static final im = new Complex(0, 1); + /** + The imaginary unit. + **/ + public static final im = new Complex(0, 1); - /** - The complex zero. - **/ - public static final zero = new Complex(0, 0); + /** + The complex zero. + **/ + public static final zero = new Complex(0, 0); - /** - Computes the complex exponential `e^(iw)`. - **/ - public static inline function exp(w:Float) - return new Complex(Math.cos(w), Math.sin(w)); + /** + Computes the complex exponential `e^(iw)`. + **/ + public static inline function exp(w:Float) + return new Complex(Math.cos(w), Math.sin(w)); } diff --git a/source/funkin/audiovis/dsp/FFT.hx b/source/funkin/audiovis/dsp/FFT.hx index 7929c0f0a..d1d99140e 100644 --- a/source/funkin/audiovis/dsp/FFT.hx +++ b/source/funkin/audiovis/dsp/FFT.hx @@ -8,160 +8,154 @@ using funkin.audiovis.dsp.Signal; // these are only used for testing, down in FFT.main() /** - Fast/Finite Fourier Transforms. + Fast/Finite Fourier Transforms. **/ class FFT { - /** - Computes the Discrete Fourier Transform (DFT) of a `Complex` sequence. + /** + Computes the Discrete Fourier Transform (DFT) of a `Complex` sequence. - If the input has N data points (N should be a power of 2 or padding will be added) - from a signal sampled at intervals of 1/Fs, the result will be a sequence of N - samples from the Discrete-Time Fourier Transform (DTFT) - which is Fs-periodic - - with a spacing of Fs/N Hz between them and a scaling factor of Fs. - **/ - public static function fft(input:Array):Array - return do_fft(input, false); + If the input has N data points (N should be a power of 2 or padding will be added) + from a signal sampled at intervals of 1/Fs, the result will be a sequence of N + samples from the Discrete-Time Fourier Transform (DTFT) - which is Fs-periodic - + with a spacing of Fs/N Hz between them and a scaling factor of Fs. + **/ + public static function fft(input:Array):Array + return do_fft(input, false); - /** - Like `fft`, but for a real (Float) sequence input. + /** + Like `fft`, but for a real (Float) sequence input. - Since the input time signal is real, its frequency representation is - Hermitian-symmetric so we only return the positive frequencies. - **/ - public static function rfft(input:Array):Array - { - final s = fft(input.map(Complex.fromReal)); - return s.slice(0, Std.int(s.length / 2) + 1); - } + Since the input time signal is real, its frequency representation is + Hermitian-symmetric so we only return the positive frequencies. + **/ + public static function rfft(input:Array):Array + { + final s = fft(input.map(Complex.fromReal)); + return s.slice(0, Std.int(s.length / 2) + 1); + } - /** - Computes the Inverse DFT of a periodic input sequence. + /** + Computes the Inverse DFT of a periodic input sequence. - If the input contains N (a power of 2) DTFT samples, each spaced Fs/N Hz - from each other, the result will consist of N data points as sampled - from a time signal at intervals of 1/Fs with a scaling factor of 1/Fs. - **/ - public static function ifft(input:Array):Array - return do_fft(input, true); + If the input contains N (a power of 2) DTFT samples, each spaced Fs/N Hz + from each other, the result will consist of N data points as sampled + from a time signal at intervals of 1/Fs with a scaling factor of 1/Fs. + **/ + public static function ifft(input:Array):Array + return do_fft(input, true); - // Handles padding and scaling for forwards and inverse FFTs. - private static function do_fft(input:Array, inverse:Bool):Array - { - final n = nextPow2(input.length); - var ts = [for (i in 0...n) if (i < input.length) input[i] else Complex.zero]; - var fs = [for (_ in 0...n) Complex.zero]; - ditfft2(ts, 0, fs, 0, n, 1, inverse); - return inverse ? fs.map(z -> z.scale(1 / n)) : fs; - return fs; - } + // Handles padding and scaling for forwards and inverse FFTs. + static function do_fft(input:Array, inverse:Bool):Array + { + final n = nextPow2(input.length); + var ts = [for (i in 0...n) if (i < input.length) input[i] else Complex.zero]; + var fs = [for (_ in 0...n) Complex.zero]; + ditfft2(ts, 0, fs, 0, n, 1, inverse); + return inverse ? fs.map(z -> z.scale(1 / n)) : fs; + return fs; + } - // Radix-2 Decimation-In-Time variant of Cooley–Tukey's FFT, recursive. - private static function ditfft2(time:Array, t:Int, freq:Array, f:Int, n:Int, step:Int, inverse:Bool):Void - { - if (n == 1) - { - freq[f] = time[t].copy(); - } - else - { - final halfLen = Std.int(n / 2); - ditfft2(time, t, freq, f, halfLen, step * 2, inverse); - ditfft2(time, t + step, freq, f + halfLen, halfLen, step * 2, inverse); - for (k in 0...halfLen) - { - final twiddle = Complex.exp((inverse ? 1 : -1) * 2 * Math.PI * k / n); - final even = freq[f + k].copy(); - final odd = freq[f + k + halfLen].copy(); - freq[f + k] = even + twiddle * odd; - freq[f + k + halfLen] = even - twiddle * odd; - } - } - } + // Radix-2 Decimation-In-Time variant of Cooley–Tukey's FFT, recursive. + static function ditfft2(time:Array, t:Int, freq:Array, f:Int, n:Int, step:Int, inverse:Bool):Void + { + if (n == 1) + { + freq[f] = time[t].copy(); + } + else + { + final halfLen = Std.int(n / 2); + ditfft2(time, t, freq, f, halfLen, step * 2, inverse); + ditfft2(time, t + step, freq, f + halfLen, halfLen, step * 2, inverse); + for (k in 0...halfLen) + { + final twiddle = Complex.exp((inverse ? 1 : -1) * 2 * Math.PI * k / n); + final even = freq[f + k].copy(); + final odd = freq[f + k + halfLen].copy(); + freq[f + k] = even + twiddle * odd; + freq[f + k + halfLen] = even - twiddle * odd; + } + } + } - // Naive O(n^2) DFT, used for testing purposes. - private static function dft(ts:Array, ?inverse:Bool):Array - { - if (inverse == null) - inverse = false; - final n = ts.length; - var fs = new Array(); - fs.resize(n); - for (f in 0...n) - { - var sum = Complex.zero; - for (t in 0...n) - { - sum += ts[t] * Complex.exp((inverse ? 1 : -1) * 2 * Math.PI * f * t / n); - } - fs[f] = inverse ? sum.scale(1 / n) : sum; - } - return fs; - } + // Naive O(n^2) DFT, used for testing purposes. + static function dft(ts:Array, ?inverse:Bool):Array + { + if (inverse == null) inverse = false; + final n = ts.length; + var fs = new Array(); + fs.resize(n); + for (f in 0...n) + { + var sum = Complex.zero; + for (t in 0...n) + { + sum += ts[t] * Complex.exp((inverse ? 1 : -1) * 2 * Math.PI * f * t / n); + } + fs[f] = inverse ? sum.scale(1 / n) : sum; + } + return fs; + } - /** - Finds the power of 2 that is equal to or greater than the given natural. - **/ - static function nextPow2(x:Int):Int - { - if (x < 2) - return 1; - else if ((x & (x - 1)) == 0) - return x; - var pow = 2; - x--; - while ((x >>= 1) != 0) - pow <<= 1; - return pow; - } + /** + Finds the power of 2 that is equal to or greater than the given natural. + **/ + static function nextPow2(x:Int):Int + { + if (x < 2) return 1; + else if ((x & (x - 1)) == 0) return x; + var pow = 2; + x--; + while ((x >>= 1) != 0) + pow <<= 1; + return pow; + } - // testing, but also acts like an example - static function main() - { - // sampling and buffer parameters - final Fs = 44100.0; - final N = 512; - final halfN = Std.int(N / 2); + // testing, but also acts like an example + static function main() + { + // sampling and buffer parameters + final Fs = 44100.0; + final N = 512; + final halfN = Std.int(N / 2); - // build a time signal as a sum of sinusoids - final freqs = [5919.911]; - final ts = [for (n in 0...N) freqs.map(f -> Math.sin(2 * Math.PI * f * n / Fs)).sum()]; + // build a time signal as a sum of sinusoids + final freqs = [5919.911]; + final ts = [for (n in 0...N) freqs.map(f -> Math.sin(2 * Math.PI * f * n / Fs)).sum()]; - // get positive spectrum and use its symmetry to reconstruct negative domain - final fs_pos = rfft(ts); - final fs_fft = new OffsetArray([for (k in -(halfN - 1)...0) fs_pos[-k].conj()].concat(fs_pos), -(halfN - 1)); + // get positive spectrum and use its symmetry to reconstruct negative domain + final fs_pos = rfft(ts); + final fs_fft = new OffsetArray([for (k in -(halfN - 1)...0) fs_pos[-k].conj()].concat(fs_pos), -(halfN - 1)); - // double-check with naive DFT - final fs_dft = new OffsetArray(dft(ts.map(Complex.fromReal)).circShift(halfN - 1), -(halfN - 1)); - final fs_err = [for (k in -(halfN - 1)...halfN) fs_fft[k] - fs_dft[k]]; - final max_fs_err = fs_err.map(z -> z.magnitude).max(); - if (max_fs_err > 1e-6) - haxe.Log.trace('FT Error: ${max_fs_err}', null); - // else for (k => s in fs_fft) haxe.Log.trace('${k * Fs / N};${s.scale(1 / Fs).magnitude}', null); + // double-check with naive DFT + final fs_dft = new OffsetArray(dft(ts.map(Complex.fromReal)).circShift(halfN - 1), -(halfN - 1)); + final fs_err = [for (k in -(halfN - 1)...halfN) fs_fft[k] - fs_dft[k]]; + final max_fs_err = fs_err.map(z -> z.magnitude).max(); + if (max_fs_err > 1e-6) haxe.Log.trace('FT Error: ${max_fs_err}', null); + // else for (k => s in fs_fft) haxe.Log.trace('${k * Fs / N};${s.scale(1 / Fs).magnitude}', null); - // find spectral peaks to detect signal frequencies - final freqis = fs_fft.array.map(z -> z.magnitude) - .findPeaks() - .map(k -> (k - (halfN - 1)) * Fs / N) - .filter(f -> f >= 0); - if (freqis.length != freqs.length) - { - trace('Found frequencies: ${freqis}'); - } - else - { - final freqs_err = [for (i in 0...freqs.length) freqis[i] - freqs[i]]; - final max_freqs_err = freqs_err.map(Math.abs).max(); - if (max_freqs_err > Fs / N) - trace('Frequency Errors: ${freqs_err}'); - } + // find spectral peaks to detect signal frequencies + final freqis = fs_fft.array.map(z -> z.magnitude) + .findPeaks() + .map(k -> (k - (halfN - 1)) * Fs / N) + .filter(f -> f >= 0); + if (freqis.length != freqs.length) + { + trace('Found frequencies: ${freqis}'); + } + else + { + final freqs_err = [for (i in 0...freqs.length) freqis[i] - freqs[i]]; + final max_freqs_err = freqs_err.map(Math.abs).max(); + if (max_freqs_err > Fs / N) trace('Frequency Errors: ${freqs_err}'); + } - // recover time signal from the frequency domain - final ts_ifft = ifft(fs_fft.array.circShift(-(halfN - 1)).map(z -> z.scale(1 / Fs))); - final ts_err = [for (n in 0...N) ts_ifft[n].scale(Fs).real - ts[n]]; - final max_ts_err = ts_err.map(Math.abs).max(); - if (max_ts_err > 1e-6) - haxe.Log.trace('IFT Error: ${max_ts_err}', null); - // else for (n in 0...ts_ifft.length) haxe.Log.trace('${n / Fs};${ts_ifft[n].scale(Fs).real}', null); - } + // recover time signal from the frequency domain + final ts_ifft = ifft(fs_fft.array.circShift(-(halfN - 1)).map(z -> z.scale(1 / Fs))); + final ts_err = [for (n in 0...N) ts_ifft[n].scale(Fs).real - ts[n]]; + final max_ts_err = ts_err.map(Math.abs).max(); + if (max_ts_err > 1e-6) haxe.Log.trace('IFT Error: ${max_ts_err}', null); + // else for (n in 0...ts_ifft.length) haxe.Log.trace('${n / Fs};${ts_ifft[n].scale(Fs).real}', null); + } } diff --git a/source/funkin/audiovis/dsp/OffsetArray.hx b/source/funkin/audiovis/dsp/OffsetArray.hx index db06ce40f..bd066a727 100644 --- a/source/funkin/audiovis/dsp/OffsetArray.hx +++ b/source/funkin/audiovis/dsp/OffsetArray.hx @@ -1,87 +1,86 @@ package funkin.audiovis.dsp; /** - A view into an Array with an indexing offset. + A view into an Array with an indexing offset. - Usages include 1-indexed sequences or zero-centered buffers with negative indexing. + Usages include 1-indexed sequences or zero-centered buffers with negative indexing. **/ @:forward(array, offset) abstract OffsetArray({ - final array:Array; - final offset:Int; + final array:Array; + final offset:Int; }) { - public inline function new(array:Array, offset:Int) - this = {array: array, offset: offset}; + public inline function new(array:Array, offset:Int) + this = {array: array, offset: offset}; - public var length(get, never):Int; + public var length(get, never):Int; - inline function get_length() - return this.array.length; + inline function get_length() + return this.array.length; - @:arrayAccess - public inline function get(index:Int):T - return this.array[index - this.offset]; + @:arrayAccess + public inline function get(index:Int):T + return this.array[index - this.offset]; - @:arrayAccess - public inline function set(index:Int, value:T):Void - this.array[index - this.offset] = value; + @:arrayAccess + public inline function set(index:Int, value:T):Void + this.array[index - this.offset] = value; - /** - Iterates through items in their original order while providing the altered indexes as keys. - **/ - public inline function keyValueIterator():KeyValueIterator - return new OffsetArrayIterator(this.array, this.offset); + /** + Iterates through items in their original order while providing the altered indexes as keys. + **/ + public inline function keyValueIterator():KeyValueIterator + return new OffsetArrayIterator(this.array, this.offset); - @:from - static inline function fromArray(array:Array) - return new OffsetArray(array, 0); + @:from + static inline function fromArray(array:Array) + return new OffsetArray(array, 0); - @:to - inline function toArray() - return this.array; + @:to + inline function toArray() + return this.array; - /** - Makes a shifted version of the given `array`, where elements are in the - same order but shifted by `n` positions (to the right if positive and to - the left if negative) in **circular** fashion (no elements discarded). - **/ - public static function circShift(array:Array, n:Int):Array - { - if (n < 0) - return circShift(array, array.length + n); + /** + Makes a shifted version of the given `array`, where elements are in the + same order but shifted by `n` positions (to the right if positive and to + the left if negative) in **circular** fashion (no elements discarded). + **/ + public static function circShift(array:Array, n:Int):Array + { + if (n < 0) return circShift(array, array.length + n); - var shifted = new Array(); + var shifted = new Array(); - n = n % array.length; - for (i in array.length - n...array.length) - shifted.push(array[i]); - for (i in 0...array.length - n) - shifted.push(array[i]); + n = n % array.length; + for (i in array.length - n...array.length) + shifted.push(array[i]); + for (i in 0...array.length - n) + shifted.push(array[i]); - return shifted; - } + return shifted; + } } private class OffsetArrayIterator { - private final array:Array; - private final offset:Int; - private var enumeration:Int; + final array:Array; + final offset:Int; + var enumeration:Int; - public inline function new(array:Array, offset:Int) - { - this.array = array; - this.offset = offset; - this.enumeration = 0; - } + public inline function new(array:Array, offset:Int) + { + this.array = array; + this.offset = offset; + this.enumeration = 0; + } - public inline function next():{key:Int, value:T} - { - final i = this.enumeration++; - return {key: i + this.offset, value: this.array[i]}; - } + public inline function next():{key:Int, value:T} + { + final i = this.enumeration++; + return {key: i + this.offset, value: this.array[i]}; + } - public inline function hasNext():Bool - return this.enumeration < this.array.length; + public inline function hasNext():Bool + return this.enumeration < this.array.length; } diff --git a/source/funkin/audiovis/dsp/Signal.hx b/source/funkin/audiovis/dsp/Signal.hx index aeb6c3f91..1f7cc6114 100644 --- a/source/funkin/audiovis/dsp/Signal.hx +++ b/source/funkin/audiovis/dsp/Signal.hx @@ -3,112 +3,112 @@ package funkin.audiovis.dsp; using Lambda; /** - Signal processing miscellaneous utilities. + Signal processing miscellaneous utilities. **/ class Signal { - /** - Returns a smoothed version of the input array using a moving average. - **/ - public static function smooth(y:Array, n:Int):Array - { - if (n <= 0) - { - return null; - } - else if (n == 1) - { - return y.copy(); - } - else - { - var smoothed = new Array(); - smoothed.resize(y.length); - for (i in 0...y.length) - { - var m = i + 1 < n ? i : n - 1; - smoothed[i] = sum(y.slice(i - m, i + 1)); - } - return smoothed; - } - } + /** + Returns a smoothed version of the input array using a moving average. + **/ + public static function smooth(y:Array, n:Int):Array + { + if (n <= 0) + { + return null; + } + else if (n == 1) + { + return y.copy(); + } + else + { + var smoothed = new Array(); + smoothed.resize(y.length); + for (i in 0...y.length) + { + var m = i + 1 < n ? i : n - 1; + smoothed[i] = sum(y.slice(i - m, i + 1)); + } + return smoothed; + } + } - /** - Finds indexes of peaks in the order they appear in the input sequence. + /** + Finds indexes of peaks in the order they appear in the input sequence. - @param threshold Minimal peak height wrt. its neighbours, defaults to 0. - @param minHeight Minimal peak height wrt. the whole input, defaults to global minimum. - **/ - public static function findPeaks(y:Array, ?threshold:Float, ?minHeight:Float):Array - { - threshold = threshold == null ? 0.0 : Math.abs(threshold); - minHeight = minHeight == null ? Signal.min(y) : minHeight; + @param threshold Minimal peak height wrt. its neighbours, defaults to 0. + @param minHeight Minimal peak height wrt. the whole input, defaults to global minimum. + **/ + public static function findPeaks(y:Array, ?threshold:Float, ?minHeight:Float):Array + { + threshold = threshold == null ? 0.0 : Math.abs(threshold); + minHeight = minHeight == null ? Signal.min(y) : minHeight; - var peaks = new Array(); + var peaks = new Array(); - final dy = [for (i in 1...y.length) y[i] - y[i - 1]]; - for (i in 1...dy.length) - { - // peak: function growth positive to its left and negative to its right - if (dy[i - 1] > threshold && dy[i] < -threshold && y[i] > minHeight) - { - peaks.push(i); - } - } + final dy = [for (i in 1...y.length) y[i] - y[i - 1]]; + for (i in 1...dy.length) + { + // peak: function growth positive to its left and negative to its right + if (dy[i - 1] > threshold && dy[i] < -threshold && y[i] > minHeight) + { + peaks.push(i); + } + } - return peaks; - } + return peaks; + } - /** - Returns the sum of all the elements of a given array. + /** + Returns the sum of all the elements of a given array. - This function tries to minimize floating-point precision errors. - **/ - public static function sum(array:Array):Float - { - // Neumaier's "improved Kahan-Babuska algorithm": + This function tries to minimize floating-point precision errors. + **/ + public static function sum(array:Array):Float + { + // Neumaier's "improved Kahan-Babuska algorithm": - var sum = 0.0; - var c = 0.0; // running compensation for lost precision + var sum = 0.0; + var c = 0.0; // running compensation for lost precision - for (v in array) - { - var t = sum + v; - c += Math.abs(sum) >= Math.abs(v) ? (sum - t) + v // sum is bigger => low-order digits of v are lost - : (v - t) + sum; // v is bigger => low-order digits of sum are lost - sum = t; - } + for (v in array) + { + var t = sum + v; + c += Math.abs(sum) >= Math.abs(v) ? (sum - t) + v // sum is bigger => low-order digits of v are lost + : (v - t) + sum; // v is bigger => low-order digits of sum are lost + sum = t; + } - return sum + c; // correction only applied at the very end - } + return sum + c; // correction only applied at the very end + } - /** - Returns the average value of an array. - **/ - public static function mean(y:Array):Float - return sum(y) / y.length; + /** + Returns the average value of an array. + **/ + public static function mean(y:Array):Float + return sum(y) / y.length; - /** - Returns the global maximum. - **/ - public static function max(y:Array):Float - return y.fold(Math.max, y[0]); + /** + Returns the global maximum. + **/ + public static function max(y:Array):Float + return y.fold(Math.max, y[0]); - /** - Returns the global maximum's index. - **/ - public static function maxi(y:Array):Int - return y.foldi((yi, m, i) -> yi > y[m] ? i : m, 0); + /** + Returns the global maximum's index. + **/ + public static function maxi(y:Array):Int + return y.foldi((yi, m, i) -> yi > y[m] ? i : m, 0); - /** - Returns the global minimum. - **/ - public static function min(y:Array):Float - return y.fold(Math.min, y[0]); + /** + Returns the global minimum. + **/ + public static function min(y:Array):Float + return y.fold(Math.min, y[0]); - /** - Returns the global minimum's index. - **/ - public static function mini(y:Array):Int - return y.foldi((yi, m, i) -> yi < y[m] ? i : m, 0); + /** + Returns the global minimum's index. + **/ + public static function mini(y:Array):Int + return y.foldi((yi, m, i) -> yi < y[m] ? i : m, 0); } diff --git a/source/funkin/charting/ChartingState.hx b/source/funkin/charting/ChartingState.hx index f6913d4ae..d9bc7f5e2 100644 --- a/source/funkin/charting/ChartingState.hx +++ b/source/funkin/charting/ChartingState.hx @@ -38,1540 +38,1520 @@ using flixel.util.FlxSpriteUtil; // add in "compiler save" that saves the JSON d class ChartingState extends MusicBeatState { - var _file:FileReference; + var _file:FileReference; - var UI_box:FlxUITabMenu; - var sidePreview:FlxSprite; + var UI_box:FlxUITabMenu; + var sidePreview:FlxSprite; - /** - * Array of notes showing when each section STARTS in STEPS - * Usually rounded up?? - */ - var curSection:Int = 0; + /** + * Array of notes showing when each section STARTS in STEPS + * Usually rounded up?? + */ + var curSection:Int = 0; - public static var lastSection:Int = 0; + public static var lastSection:Int = 0; - var bpmTxt:FlxText; + var bpmTxt:FlxText; - var strumLine:FlxSprite; - var curSong:String = 'Dadbattle'; - var amountSteps:Int = 0; - var bullshitUI:FlxGroup; + var strumLine:FlxSprite; + var curSong:String = 'Dadbattle'; + var amountSteps:Int = 0; + var bullshitUI:FlxGroup; - var highlight:FlxSprite; + var highlight:FlxSprite; - var GRID_SIZE:Int = 40; + var GRID_SIZE:Int = 40; - var dummyArrow:FlxSprite; + var dummyArrow:FlxSprite; - var curRenderedNotes:FlxTypedGroup; - var curRenderedSustains:FlxTypedGroup; + var curRenderedNotes:FlxTypedGroup; + var curRenderedSustains:FlxTypedGroup; - var gridBG:FlxSprite; + var gridBG:FlxSprite; - var _song:SwagSong; + var _song:SwagSong; - var typingShit:FlxInputText; - /* - * WILL BE THE CURRENT / LAST PLACED NOTE - **/ - var curSelectedNote:NoteData; + var typingShit:FlxInputText; + /* + * WILL BE THE CURRENT / LAST PLACED NOTE + **/ + var curSelectedNote:NoteData; - var tempBpm:Float = 0; + var tempBpm:Float = 0; - var vocals:VoicesGroup; + var vocals:VoicesGroup; - var leftIcon:HealthIcon; - var rightIcon:HealthIcon; + var leftIcon:HealthIcon; + var rightIcon:HealthIcon; - var audioBuf:AudioBuffer = new AudioBuffer(); + var audioBuf:AudioBuffer = new AudioBuffer(); - var playheadTest:FlxSprite; + var playheadTest:FlxSprite; - var staticSpecGrp:FlxTypedGroup; + var staticSpecGrp:FlxTypedGroup; - override function create() - { - curSection = lastSection; + override function create() + { + curSection = lastSection; - // sys.io.File.saveContent('./bitShit.txt', "swag"); + // sys.io.File.saveContent('./bitShit.txt', "swag"); - // trace(audioBuf.sampleRate); + // trace(audioBuf.sampleRate); - gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); - trace("GRD BG: " + gridBG.height); - add(gridBG); + gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); + trace("GRD BG: " + gridBG.height); + add(gridBG); - leftIcon = new HealthIcon('bf'); - rightIcon = new HealthIcon('dad'); - leftIcon.scrollFactor.set(1, 1); - rightIcon.scrollFactor.set(1, 1); + leftIcon = new HealthIcon('bf'); + rightIcon = new HealthIcon('dad'); + leftIcon.scrollFactor.set(1, 1); + rightIcon.scrollFactor.set(1, 1); - leftIcon.setGraphicSize(0, 45); - rightIcon.setGraphicSize(0, 45); + leftIcon.setGraphicSize(0, 45); + rightIcon.setGraphicSize(0, 45); - leftIcon.autoUpdate = false; - rightIcon.autoUpdate = false; + leftIcon.autoUpdate = false; + rightIcon.autoUpdate = false; - add(leftIcon); - add(rightIcon); + add(leftIcon); + add(rightIcon); - leftIcon.setPosition(0, -100); - rightIcon.setPosition(gridBG.width / 2, -100); + leftIcon.setPosition(0, -100); + rightIcon.setPosition(gridBG.width / 2, -100); - var gridBlackLine:FlxSprite = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); - add(gridBlackLine); + var gridBlackLine:FlxSprite = new FlxSprite(gridBG.x + gridBG.width / 2).makeGraphic(2, Std.int(gridBG.height), FlxColor.BLACK); + add(gridBlackLine); - curRenderedNotes = new FlxTypedGroup(); - curRenderedSustains = new FlxTypedGroup(); + curRenderedNotes = new FlxTypedGroup(); + curRenderedSustains = new FlxTypedGroup(); - if (PlayState.currentSong != null) - { - _song = SongLoad.songData = PlayState.currentSong; - trace("LOADED A PLAYSTATE SONGFILE"); - } - else - { - _song = SongLoad.songData = SongLoad.getDefaultSwagSong(); - } + if (PlayState.currentSong != null) + { + _song = SongLoad.songData = PlayState.currentSong; + trace("LOADED A PLAYSTATE SONGFILE"); + } + else + { + _song = SongLoad.songData = SongLoad.getDefaultSwagSong(); + } - FlxG.mouse.visible = true; - FlxG.save.bind('funkin', 'ninjamuffin99'); + FlxG.mouse.visible = true; + FlxG.save.bind('funkin', 'ninjamuffin99'); - tempBpm = _song.bpm; + tempBpm = _song.bpm; - addSection(); + addSection(); - // sections = SongLoad.getSong(); + // sections = SongLoad.getSong(); - updateGrid(); + updateGrid(); - loadSong(_song.song); - // Conductor.bpm = _song.bpm; - Conductor.mapBPMChanges(_song); + loadSong(_song.song); + // Conductor.bpm = _song.bpm; + Conductor.mapBPMChanges(_song); - bpmTxt = new FlxText(1000, 50, 0, "", 16); - bpmTxt.scrollFactor.set(); - add(bpmTxt); + bpmTxt = new FlxText(1000, 50, 0, "", 16); + bpmTxt.scrollFactor.set(); + add(bpmTxt); - strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(GRID_SIZE * 8), 4); - add(strumLine); + strumLine = new FlxSprite(0, 50).makeGraphic(Std.int(GRID_SIZE * 8), 4); + add(strumLine); - dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE, 0xFFCC2288); - dummyArrow.alpha = 0.3; - add(dummyArrow); + dummyArrow = new FlxSprite().makeGraphic(GRID_SIZE, GRID_SIZE, 0xFFCC2288); + dummyArrow.alpha = 0.3; + add(dummyArrow); - var tabs = [ - {name: "Song", label: 'Song'}, - {name: "Section", label: 'Section'}, - {name: "Note", label: 'Note'} - ]; + var tabs = [ + {name: "Song", label: 'Song'}, + {name: "Section", label: 'Section'}, + {name: "Note", label: 'Note'} + ]; - UI_box = new FlxUITabMenu(null, tabs, true); + UI_box = new FlxUITabMenu(null, tabs, true); - UI_box.resize(300, 400); - UI_box.x = (FlxG.width / 4) * 3; - UI_box.y = 120; - add(UI_box); + UI_box.resize(300, 400); + UI_box.x = (FlxG.width / 4) * 3; + UI_box.y = 120; + add(UI_box); - addSongUI(); - addSectionUI(); - addNoteUI(); + addSongUI(); + addSectionUI(); + addNoteUI(); - add(curRenderedNotes); - add(curRenderedSustains); + add(curRenderedNotes); + add(curRenderedSustains); - changeSection(); - super.create(); - } + changeSection(); + super.create(); + } - function addSongUI():Void - { - var UI_songTitle = new FlxUIInputText(10, 10, 70, _song.song, 8); - typingShit = UI_songTitle; - - var check_voices = new FlxUICheckBox(10, 25, null, null, "Has voice track", 100); - check_voices.checked = _song.needsVoices; - // _song.needsVoices = check_voices.checked; - check_voices.callback = function() - { - _song.needsVoices = check_voices.checked; - trace('CHECKED!'); - }; - - var check_mute_inst = new FlxUICheckBox(10, 200, null, null, "Mute Instrumental (in editor)", 100); - check_mute_inst.checked = false; - check_mute_inst.callback = function() - { - var vol:Float = 1; - - if (check_mute_inst.checked) - vol = 0; - - FlxG.sound.music.volume = vol; - }; - - var saveButton:FlxButton = new FlxButton(110, 8, "Save", function() - { - saveLevel(); - }); - - var saveCompiler:FlxButton = new FlxButton(110, 30, "Save compile", function() - { - saveLevel(true); - }); - - var reloadSong:FlxButton = new FlxButton(saveButton.x + saveButton.width + 10, saveButton.y, "Reload Audio", function() - { - loadSong(_song.song); - }); - - var reloadSongJson:FlxButton = new FlxButton(reloadSong.x, saveButton.y + 30, "Reload JSON", function() - { - FlxTransitionableState.skipNextTransIn = true; - FlxTransitionableState.skipNextTransOut = true; - loadJson(_song.song.toLowerCase()); - }); - - var loadAutosaveBtn:FlxButton = new FlxButton(reloadSongJson.x, reloadSongJson.y + 30, 'load autosave', loadAutosave); - - var stepperSpeed:FlxUINumericStepper = new FlxUINumericStepper(10, 80, 0.1, 1, 0.1, 10, 2); - stepperSpeed.value = SongLoad.getSpeed(); - // stepperSpeed.value = _song.speed[SongLoad.curDiff]; - stepperSpeed.name = 'song_speed'; - - var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 1, 100, 1, 999, 3); - stepperBPM.value = Conductor.bpm; - stepperBPM.name = 'song_bpm'; - - var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); - - var player1DropDown = new FlxUIDropDownMenu(10, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) - { - _song.player1 = characters[Std.parseInt(character)]; - updateHeads(); - }); - player1DropDown.selectedLabel = _song.player1; - - var player2DropDown = new FlxUIDropDownMenu(140, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) - { - _song.player2 = characters[Std.parseInt(character)]; - updateHeads(); - }); - player2DropDown.selectedLabel = _song.player2; - - var difficultyDropDown = new FlxUIDropDownMenu(10, 230, FlxUIDropDownMenu.makeStrIdLabelArray(_song.difficulties, true), function(diff:String) - { - SongLoad.curDiff = _song.difficulties[Std.parseInt(diff)]; - SongLoad.checkAndCreateNotemap(SongLoad.curDiff); - - while (SongLoad.getSong()[curSection] == null) - addSection(); - - updateGrid(); - }); - difficultyDropDown.selectedLabel = SongLoad.curDiff; - - var difficultyAdder = new FlxUIInputText(130, 230, 100, "", 12); - - var addDiff:FlxButton = new FlxButton(130, 250, "Add Difficulty", function() - { - difficultyAdder.text = ""; - // something to regenerate difficulties - }); - - var tab_group_song = new FlxUI(null, UI_box); - tab_group_song.name = "Song"; - tab_group_song.add(UI_songTitle); - - tab_group_song.add(check_voices); - tab_group_song.add(check_mute_inst); - tab_group_song.add(saveButton); - tab_group_song.add(saveCompiler); - tab_group_song.add(reloadSong); - tab_group_song.add(reloadSongJson); - tab_group_song.add(loadAutosaveBtn); - tab_group_song.add(stepperBPM); - tab_group_song.add(stepperSpeed); - tab_group_song.add(player1DropDown); - tab_group_song.add(player2DropDown); - tab_group_song.add(difficultyDropDown); - tab_group_song.add(difficultyAdder); - tab_group_song.add(addDiff); - - UI_box.addGroup(tab_group_song); - UI_box.scrollFactor.set(); - - FlxG.camera.focusOn(gridBG.getGraphicMidpoint()); - } - - var stepperLength:FlxUINumericStepper; - var check_mustHitSection:FlxUICheckBox; - var check_changeBPM:FlxUICheckBox; - var stepperSectionBPM:FlxUINumericStepper; - var check_altAnim:FlxUICheckBox; - - function addSectionUI():Void - { - var tab_group_section = new FlxUI(null, UI_box); - tab_group_section.name = 'Section'; - - stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0); - stepperLength.value = SongLoad.getSong()[curSection].lengthInSteps; - stepperLength.name = "section_length"; - - stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 1, 999, 3); - stepperSectionBPM.value = Conductor.bpm; - stepperSectionBPM.name = 'section_bpm'; - - var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 130, 1, 1, -999, 999, 0); - - var copyButton:FlxButton = new FlxButton(10, 130, "Copy last section", function() - { - copySection(Std.int(stepperCopy.value)); - }); - - var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear", clearSection); - - var swapSection:FlxButton = new FlxButton(10, 170, "Swap section", function() - { - for (i in 0...SongLoad.getSong()[curSection].sectionNotes.length) - { - var note:Note = new Note(0, 0); - note.data = SongLoad.getSong()[curSection].sectionNotes[i]; - note.data.noteData = (note.data.noteData + 4) % 8; - SongLoad.getSong()[curSection].sectionNotes[i] = note.data; - updateGrid(); - } - }); - - check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Must hit section", 100); - check_mustHitSection.name = 'check_mustHit'; - check_mustHitSection.checked = true; - // _song.needsVoices = check_mustHit.checked; - - check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alt Animation", 100); - check_altAnim.name = 'check_altAnim'; - - check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100); - check_changeBPM.name = 'check_changeBPM'; - - tab_group_section.add(stepperLength); - tab_group_section.add(stepperSectionBPM); - tab_group_section.add(stepperCopy); - tab_group_section.add(check_mustHitSection); - tab_group_section.add(check_altAnim); - tab_group_section.add(check_changeBPM); - tab_group_section.add(copyButton); - tab_group_section.add(clearSectionButton); - tab_group_section.add(swapSection); - - UI_box.addGroup(tab_group_section); - } - - var stepperSusLength:FlxUINumericStepper; - var stepperPerNoteSpeed:FlxUINumericStepper; - - function addNoteUI():Void - { - var tab_group_note = new FlxUI(null, UI_box); - tab_group_note.name = 'Note'; - - stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * 16); - stepperSusLength.value = 0; - stepperSusLength.name = 'note_susLength'; - - stepperPerNoteSpeed = new FlxUINumericStepper(10, 40, 0.1, 1, 0.01, 100, 2); - stepperPerNoteSpeed.value = 1; - stepperPerNoteSpeed.name = "note_PerNoteSpeed"; - - var noteSpeedName:FlxText = new FlxText(40, stepperPerNoteSpeed.y, 0, "Note Speed Multiplier"); - - var applyLength:FlxButton = new FlxButton(100, 10, 'Apply'); - - tab_group_note.add(stepperSusLength); - tab_group_note.add(stepperPerNoteSpeed); - tab_group_note.add(noteSpeedName); - tab_group_note.add(applyLength); - - UI_box.addGroup(tab_group_note); - } - - // var spec:SpectogramSprite; - - function loadSong(daSong:String):Void - { - if (FlxG.sound.music != null) - { - FlxG.sound.music.stop(); - // vocals.stop(); - } - - var pathShit = Paths.inst(daSong); - - if (!openfl.utils.Assets.cache.hasSound(pathShit)) - { - var library = Assets.getLibrary("songs"); - var symbolPath = pathShit.split(":").pop(); - // @:privateAccess - // library.types.set(symbolPath, SOUND); - // @:privateAccess - // library.pathGroups.set(symbolPath, [library.__cacheBreak(symbolPath)]); - // var callback = callbacks.add("song:" + pathShit); - openfl.utils.Assets.loadSound(pathShit).onComplete(function(_) - { - // callback(); - }); - } - - FlxG.sound.playMusic(Paths.inst(daSong), 0.6); - - var musSpec:PolygonSpectogram = new PolygonSpectogram(FlxG.sound.music, FlxColor.RED, FlxG.height / 2, Math.floor(FlxG.height / 2)); - musSpec.x += 170; - musSpec.scrollFactor.set(); - musSpec.waveAmplitude = 50; - // musSpec.visType = FREQUENCIES; - add(musSpec); - - sidePreview = new FlxSprite(0, 0).makeGraphic(40, FlxG.height, FlxColor.GRAY); - sidePreview.scrollFactor.set(); - add(sidePreview); - - // trace(audioBuf.data.length); - playheadTest = new FlxSprite(0, 0).makeGraphic(30, 2, FlxColor.RED); - playheadTest.scrollFactor.set(); - playheadTest.alpha = 0.5; - add(playheadTest); - - // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER - vocals = VoicesGroup.build(daSong, _song.voiceList); - // vocals = new FlxSound().loadEmbedded(Paths.voices(daSong)); - // FlxG.sound.list.add(vocals); - - staticSpecGrp = new FlxTypedGroup(); - add(staticSpecGrp); - - var aBoy:ABotVis = new ABotVis(FlxG.sound.music); - // add(aBoy); - - for (index => voc in vocals.members) - { - var vocalSpec:SpectogramSprite = new SpectogramSprite(voc, FlxG.random.color(0xFFAAAAAA, FlxColor.WHITE, 100), musSpec.daHeight, - Math.floor(FlxG.height / 2)); - vocalSpec.x = 70 - (50 * index); - // vocalSpec.visType = FREQUENCIES; - vocalSpec.daHeight = musSpec.daHeight; - vocalSpec.y = vocalSpec.daHeight; - vocalSpec.scrollFactor.set(); - add(vocalSpec); - - var staticVocal:SpectogramSprite = new SpectogramSprite(voc, FlxG.random.color(0xFFAAAAAA, FlxColor.WHITE, 100), GRID_SIZE * 16, GRID_SIZE * 8); - if (index == 0) - staticVocal.x -= 150; - - if (index == 1) - staticVocal.x = gridBG.width; - - staticVocal.visType = STATIC; - staticSpecGrp.add(staticVocal); - } - - FlxG.sound.music.pause(); - - vocals.pause(); - - FlxG.sound.music.onComplete = function() - { - vocals.pause(); - vocals.time = 0; - FlxG.sound.music.pause(); - FlxG.sound.music.time = 0; - changeSection(); - }; - } - - function generateUI():Void - { - while (bullshitUI.members.length > 0) - { - bullshitUI.remove(bullshitUI.members[0], true); - } - - // general shit - var title:FlxText = new FlxText(UI_box.x + 20, UI_box.y + 20, 0); - bullshitUI.add(title); - /* - var loopCheck = new FlxUICheckBox(UI_box.x + 10, UI_box.y + 50, null, null, "Loops", 100, ['loop check']); - loopCheck.checked = notes[0]elected.doesLoop; - tooltips.add(loopCheck, {title: 'Section looping', body: "Whether or not it's a simon says style section", style: tooltipType}); - bullshitUI.add(loopCheck); - - */ - } - - override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) - { - if (id == FlxUICheckBox.CLICK_EVENT) - { - var check:FlxUICheckBox = cast sender; - var label = check.getLabel().text; - switch (label) - { - case 'Must hit section': - SongLoad.getSong()[curSection].mustHitSection = check.checked; - - updateHeads(); - - case 'Change BPM': - SongLoad.getSong()[curSection].changeBPM = check.checked; - FlxG.log.add('changed bpm shit'); - case "Alt Animation": - SongLoad.getSong()[curSection].altAnim = check.checked; - } - } - else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) - { - var nums:FlxUINumericStepper = cast sender; - var wname = nums.name; - FlxG.log.add(wname); - if (wname == 'section_length') - { - SongLoad.getSong()[curSection].lengthInSteps = Std.int(nums.value); - updateGrid(); - } - else if (wname == 'song_speed') - { - // _song.speed[SongLoad.curDiff] = nums.value; - _song.speed.normal = nums.value; - } - else if (wname == 'song_bpm') - { - tempBpm = nums.value; - Conductor.mapBPMChanges(_song); - Conductor.forceBPM(nums.value); - } - else if (wname == 'note_susLength') - { - curSelectedNote.sustainLength = nums.value; - updateGrid(); - } - else if (wname == 'section_bpm') - { - SongLoad.getSong()[curSection].bpm = nums.value; - updateGrid(); - } - } - - // FlxG.log.add(id + " WEED " + sender + " WEED " + data + " WEED " + params); - } - - var updatedSection:Bool = false; - - /* this function got owned LOL - function lengthBpmBullshit():Float - { - if (SongLoad.getSong()[curSection].changeBPM) - return SongLoad.getSong()[curSection].lengthInSteps * (SongLoad.getSong()[curSection].bpm / _song.bpm); - else - return SongLoad.getSong()[curSection].lengthInSteps; - }*/ - /** - * Gets the start time of section, defaults to the curSection - * @param section - * @return position of the song in... either seconds or milliseconds.... woops - */ - function sectionStartTime(?funnySection:Int):Float - { - if (funnySection == null) - funnySection = curSection; - - var daBPM:Float = _song.bpm; - var daPos:Float = 0; - for (i in 0...funnySection) - { - if (SongLoad.getSong()[i].changeBPM) - { - daBPM = SongLoad.getSong()[i].bpm; - } - daPos += 4 * sectionCalc(daBPM); - } - return daPos; - } - - function measureStartTime():Float - { - var daBPM:Float = _song.bpm; - var daPos:Float = sectionStartTime(); - - daPos = Math.floor(FlxG.sound.music.time / sectionCalc(daBPM)) * sectionCalc(daBPM); - return daPos; - } - - function sectionCalc(bpm:Float) - { - return (1000 * 60 / bpm); - } - - var p1Muted:Bool = false; - var p2Muted:Bool = false; - - override function update(elapsed:Float) - { - // FlxG.camera.followLerp = CoolUtil.camLerpShit(0.05); - - FlxG.sound.music.pan = FlxMath.remapToRange(FlxG.mouse.screenX, 0, FlxG.width, -1, 1) * 10; - - // curStep = recalculateSteps(); - - Conductor.songPosition = FlxG.sound.music.time; - _song.song = typingShit.text; - - playheadTest.y = CoolUtil.coolLerp(playheadTest.y, FlxMath.remapToRange(Conductor.songPosition, 0, FlxG.sound.music.length, 0, FlxG.height), 0.5); - - var strumLinePos:Float = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * SongLoad.getSong()[curSection].lengthInSteps)); - - if (FlxG.sound.music != null) - { - if (FlxG.sound.music.playing) - strumLine.y = strumLinePos; - else - strumLine.y = CoolUtil.coolLerp(strumLine.y, strumLinePos, 0.5); - } - - /* if (FlxG.sound.music.playing) - { - var normalizedShitIDK:Int = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, FlxG.sound.music.length, 0, audioBuf.data.length)); - FlxG.watch.addQuick('WEIRD AUDIO SHIT LOL', audioBuf.data[normalizedShitIDK]); - // leftIcon.scale.x = FlxMath.remapToRange(audioBuf.data[normalizedShitIDK], 0, 255, 1, 2); - }*/ - - if (FlxG.keys.justPressed.X) - toggleAltAnimNote(); - - if (false) // (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1)) - { - // trace(curStep); - // trace((SongLoad.getSong()[curSection].lengthInSteps) * (curSection + 1)); - trace('DUMBSHIT'); - - if (SongLoad.getSong()[curSection + 1] == null) - { - addSection(); - } - - changeSection(curSection + 1, false); - } - - FlxG.watch.addQuick('daBeat', Conductor.currentBeat); - FlxG.watch.addQuick('daStep', Conductor.currentStep); - - if (FlxG.mouse.pressedMiddle && FlxG.mouse.overlaps(gridBG)) - { - if (FlxG.sound.music.playing) - { - FlxG.sound.music.pause(); - vocals.pause(); - } - - FlxG.sound.music.time = CoolUtil.coolLerp(FlxG.sound.music.time, getStrumTime(FlxG.mouse.y) + sectionStartTime(), 0.5); - vocals.time = FlxG.sound.music.time; - } - - if (FlxG.mouse.pressed) - { - if (FlxG.keys.pressed.ALT && FlxG.mouse.overlaps(gridBG)) // same shit as middle click / hold on grid - { - if (FlxG.sound.music.playing) - { - FlxG.sound.music.pause(); - vocals.pause(); - } - - FlxG.sound.music.time = getStrumTime(FlxG.mouse.y) + sectionStartTime(); - vocals.time = FlxG.sound.music.time; - } - else - { - if (FlxG.mouse.screenX <= 30 && FlxMath.inBounds(FlxG.mouse.screenY, 0, FlxG.height)) - { - if (FlxG.sound.music.playing) - { - FlxG.sound.music.pause(); - vocals.pause(); - } - - FlxG.sound.music.time = CoolUtil.coolLerp(FlxG.sound.music.time, - FlxMath.remapToRange(FlxG.mouse.screenY, 0, FlxG.height, 0, FlxG.sound.music.length), 0.5); - vocals.time = FlxG.sound.music.time; - } - if (FlxG.mouse.justPressed) - { - if (FlxG.mouse.overlaps(leftIcon)) - { - if (leftIcon.characterId == _song.player1) - { - p1Muted = !p1Muted; - leftIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; - } - else - { - p2Muted = !p2Muted; - - leftIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; - } - - vocals.members[0].volume = p1Muted ? 0 : 1; - - // null check jus in case using old shit? - if (vocals.members[1] != null) - vocals.members[1].volume = p2Muted ? 0 : 1; - } - - // sloppy copypaste lol deal with it! - if (FlxG.mouse.overlaps(rightIcon)) - { - if (rightIcon.characterId == _song.player1) - { - p1Muted = !p1Muted; - rightIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; - } - else - { - rightIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; - p2Muted = !p2Muted; - } - - vocals.members[0].volume = p1Muted ? 0 : 1; - - // null check jus in case using old shit? - if (vocals.members[1] != null) - vocals.members[1].volume = p2Muted ? 0 : 1; - } - - if (FlxG.mouse.overlaps(curRenderedNotes)) - { - curRenderedNotes.forEach(function(note:Note) - { - if (FlxG.mouse.overlaps(note)) - { - selectNote(note); - } - }); - } - else - { - if (FlxG.mouse.overlaps(gridBG)) - { - FlxG.log.add('added note'); - addNote(); - } - } - } - } - } - - if (FlxG.mouse.pressedRight) - { - if (FlxG.mouse.overlaps(curRenderedNotes)) - { - curRenderedNotes.forEach(function(note:Note) - { - if (FlxG.mouse.overlaps(note)) - { - trace('tryin to delete note...'); - deleteNote(note); - } - }); - } - } - - if (FlxG.mouse.justReleased) - justPlacedNote = false; - - if (FlxG.mouse.overlaps(gridBG)) - { - if (justPlacedNote && FlxG.mouse.pressed && FlxG.mouse.y > getYfromStrum(curSelectedNote.strumTime)) - { - var minusStuff:Float = FlxG.mouse.y - getYfromStrum(curSelectedNote.strumTime); - minusStuff -= GRID_SIZE; - minusStuff += GRID_SIZE / 2; - minusStuff = Math.floor(minusStuff / GRID_SIZE) * GRID_SIZE; - minusStuff = FlxMath.remapToRange(minusStuff, 0, 40, 0, Conductor.stepCrochet); - - curSelectedNote.sustainLength = minusStuff; - - updateNoteUI(); - updateGrid(); - } - - dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE; - if (FlxG.keys.pressed.SHIFT) - dummyArrow.y = FlxG.mouse.y; - else - dummyArrow.y = Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE; - } - - if (FlxG.keys.justPressed.ENTER) - { - autosaveSong(); - - lastSection = curSection; - - PlayState.currentSong = _song; - - // JUST FOR DEBUG DARNELL STUFF, GENERALIZE THIS FOR BETTER LOADING ELSEWHERE TOO! - PlayState.storyWeek = 8; - - FlxG.sound.music.stop(); - vocals.stop(); - LoadingState.loadAndSwitchState(new PlayState()); - // FlxG.switchState(new PlayState()); - } - - if (FlxG.keys.justPressed.E) - { - changeNoteSustain(Conductor.stepCrochet); - } - if (FlxG.keys.justPressed.Q) - { - changeNoteSustain(-Conductor.stepCrochet); - } - - if (FlxG.keys.justPressed.TAB) - { - if (FlxG.keys.pressed.SHIFT) - { - UI_box.selected_tab -= 1; - if (UI_box.selected_tab < 0) - UI_box.selected_tab = 2; - } - else - { - UI_box.selected_tab += 1; - if (UI_box.selected_tab >= 3) - UI_box.selected_tab = 0; - } - } - - if (!typingShit.hasFocus) - { - if (FlxG.keys.justPressed.SPACE) - { - if (FlxG.sound.music.playing) - { - FlxG.sound.music.pause(); - vocals.pause(); - } - else - { - vocals.play(); - FlxG.sound.music.play(); - } - } - - if (FlxG.keys.justPressed.R) - { - if (FlxG.keys.pressed.CONTROL) - resetSection(BEGINNING); - else if (FlxG.keys.pressed.SHIFT) - resetSection(MEASURE); - else - resetSection(SECTION); - } - - if (FlxG.mouse.wheel != 0) - { - FlxG.sound.music.pause(); - vocals.pause(); - - var ctrlMod:Float = FlxG.keys.pressed.CONTROL ? 0.1 : 1; - var shiftMod:Float = FlxG.keys.pressed.SHIFT ? 2 : 1; - - FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4 * ctrlMod * shiftMod); - vocals.time = FlxG.sound.music.time; - } - - if (FlxG.keys.justReleased.S) - { - FlxG.sound.music.pause(); - vocals.pause(); - - #if HAS_PITCH - FlxG.sound.music.pitch = 1; - vocals.pitch = 1; - #end - } - - if (!FlxG.keys.pressed.SHIFT) - { - if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) - { - var daTime:Float = 700 * elapsed; - - if (FlxG.keys.pressed.CONTROL) - daTime *= 0.2; - - if (FlxG.keys.pressed.W) - { - FlxG.sound.music.pause(); - vocals.pause(); - FlxG.sound.music.time -= daTime; - vocals.time = FlxG.sound.music.time; - } - else - { - if (FlxG.keys.justPressed.S) - { - FlxG.sound.music.play(); - vocals.play(); - - #if HAS_PITCH - FlxG.sound.music.pitch = 0.5; - vocals.pitch = 0.5; - #end - } - } - // FlxG.sound.music.time += daTime; - - // vocals.time = FlxG.sound.music.time; - } - } - else - { - if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S) - { - var daTime:Float = Conductor.stepCrochet * 2; - - if (FlxG.keys.justPressed.W) - { - FlxG.sound.music.pause(); - vocals.pause(); - - FlxG.sound.music.time -= daTime; - vocals.time = FlxG.sound.music.time; - } - else - { - if (FlxG.keys.justPressed.S) - { - // FlxG.sound.music.time += daTime; - - FlxG.sound.music.pause(); - vocals.pause(); - - FlxG.sound.music.time += daTime; - vocals.time = FlxG.sound.music.time; - - // FlxG.sound.music.play(); - // vocals.play(); - - #if HAS_PITCH - FlxG.sound.music.pitch = 0.2; - vocals.pitch = 0.2; - #end - } - } - } - } - } - - _song.bpm = tempBpm; - - /* if (FlxG.keys.justPressed.UP) - Conductor.bpm = Conductor.bpm + 1; - if (FlxG.keys.justPressed.DOWN) - Conductor.bpm = Conductor.bpm - 1; */ - - var shiftThing:Int = 1; - if (FlxG.keys.pressed.SHIFT) - shiftThing = 4; - if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D) - changeSection(curSection + shiftThing); - if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A) - changeSection(curSection - shiftThing); - - bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 3)) - + " / " - + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 3)) - + "\nSection: " - + curSection; - super.update(elapsed); - } - - function changeNoteSustain(value:Float):Void - { - if (curSelectedNote != null) - { - curSelectedNote.sustainLength += value; - curSelectedNote.sustainLength = Math.max(curSelectedNote.sustainLength, 0); - } - - updateNoteUI(); - updateGrid(); - } - - function toggleAltAnimNote():Void - { - if (curSelectedNote != null) - { - trace('ALT NOTE SHIT'); - curSelectedNote.noteKind = (curSelectedNote.noteKind == "alt") ? "" : "alt"; - trace(curSelectedNote.noteKind); - } - } - - function recalculateSteps():Float - { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } - for (i in 0...Conductor.bpmChangeMap.length) - { - if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; - } - - // curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet); - // updateBeat(); - - return Conductor.currentStep; - } - - function resetSection(songBeginning:SongResetType = SECTION):Void - { - updateGrid(); - - FlxG.sound.music.pause(); - vocals.pause(); - - switch (songBeginning) - { - case SECTION: - // Basically old shit from changeSection??? - FlxG.sound.music.time = sectionStartTime(); - case BEGINNING: - FlxG.sound.music.time = 0; - curSection = 0; - case MEASURE: - FlxG.sound.music.time = measureStartTime(); // Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE - default: - } - - vocals.time = FlxG.sound.music.time; - // updateCurStep(); - - updateGrid(); - updateSectionUI(); - } - - function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void - { - // trace('changing section' + sec); - - if (SongLoad.getSong()[sec] != null) - { - curSection = sec; - - updateGrid(); - - if (updateMusic) - { - FlxG.sound.music.pause(); - vocals.pause(); - - /*var daNum:Int = 0; - var daLength:Float = 0; - while (daNum <= sec) - { - daLength += lengthBpmBullshit(); - daNum++; - }*/ - - FlxG.sound.music.time = sectionStartTime(); - vocals.time = FlxG.sound.music.time; - // updateCurStep(); - } - - updateGrid(); - updateSectionUI(); - } - } - - function copySection(?sectionNum:Int = 1) - { - var daSec = FlxMath.maxInt(curSection, sectionNum); - - for (noteShit in SongLoad.getSong()[daSec - sectionNum].sectionNotes) - { - var strum = noteShit.strumTime + Conductor.stepCrochet * (SongLoad.getSong()[daSec].lengthInSteps * sectionNum); - - var copiedNote:Note = new Note(strum, noteShit.noteData); - copiedNote.data.sustainLength = noteShit.sustainLength; - SongLoad.getSong()[daSec].sectionNotes.push(copiedNote.data); - } - - updateGrid(); - } - - function updateSectionUI():Void - { - var sec = SongLoad.getSong()[curSection]; - - stepperLength.value = sec.lengthInSteps; - check_mustHitSection.checked = sec.mustHitSection; - check_altAnim.checked = sec.altAnim; - check_changeBPM.checked = sec.changeBPM; - stepperSectionBPM.value = sec.bpm; - - updateHeads(); - } - - function updateHeads():Void - { - if (check_mustHitSection.checked) - { - leftIcon.characterId = (_song.player1); - rightIcon.characterId = (_song.player2); - - // leftIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; - // rightIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; - - leftIcon.playAnimation(p1Muted ? LOSING : IDLE); - rightIcon.playAnimation(p2Muted ? LOSING : IDLE); - } - else - { - leftIcon.characterId = (_song.player2); - rightIcon.characterId = (_song.player1); - - leftIcon.playAnimation(p2Muted ? LOSING : IDLE); - rightIcon.playAnimation(p1Muted ? LOSING : IDLE); - - // leftIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; - // rightIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; - } - leftIcon.setGraphicSize(0, 45); - rightIcon.setGraphicSize(0, 45); - - leftIcon.height *= 0.6; - rightIcon.height *= 0.6; - } - - function updateNoteUI():Void - { - if (curSelectedNote != null) - stepperSusLength.value = curSelectedNote.sustainLength; - } - - function updateGrid():Void - { - // null if checks jus cuz i put updateGrid() in some weird places! - if (staticSpecGrp != null) - { - staticSpecGrp.forEach(function(spec) - { - if (spec != null) - spec.generateSection(sectionStartTime(), (Conductor.stepCrochet * 32) / 1000); - }); - } - - while (curRenderedNotes.members.length > 0) - { - curRenderedNotes.remove(curRenderedNotes.members[0], true); - } - - while (curRenderedSustains.members.length > 0) - { - curRenderedSustains.remove(curRenderedSustains.members[0], true); - } - - // generates the cool sidebar shit - if (sidePreview != null && sidePreview.active) - { - sidePreview.drawRect(0, 0, 40, FlxG.height, 0xFF444444); - - /* - var sectionsNeeded:Int = Std.int(FlxG.sound.music.length / (sectionCalc(_song.bpm) * 4)); - - while (sectionsNeeded > 0) - { - sidePreview.drawRect(0, sectionsNeeded * (FlxG.height / sectionsNeeded), 40, FlxG.height / sectionsNeeded, - (sectionsNeeded % 2 == 0 ? 0xFF000000 : 0xFFFFFFFF)); - - sectionsNeeded--; - } - */ - - for (secIndex => sideSection in SongLoad.getSong()) - { - for (notes in sideSection.sectionNotes) - { - var col:Int = Note.codeColors[notes.noteData % 4]; - - var noteFlip:Int = (sideSection.mustHitSection ? 1 : -1); - var noteX:Float = 5 * (((notes.noteData - 4) * noteFlip) + 4); - - sidePreview.drawRect(noteX, FlxMath.remapToRange(notes.strumTime, 0, FlxG.sound.music.length, 0, FlxG.height), 5, 1, col); - } - } - } - - var sectionInfo:Array = SongLoad.getSong()[curSection].sectionNotes; - - if (SongLoad.getSong()[curSection].changeBPM && SongLoad.getSong()[curSection].bpm > 0) - { - Conductor.forceBPM(SongLoad.getSong()[curSection].bpm); - FlxG.log.add('CHANGED BPM!'); - } - else - { - // get last bpm - var daBPM:Float = _song.bpm; - for (i in 0...curSection) - if (SongLoad.getSong()[i].changeBPM) - daBPM = SongLoad.getSong()[i].bpm; - Conductor.forceBPM(daBPM); - } - - /* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE - for (sec in 0...SongLoad.getSong().length) - { - for (notesse in 0...SongLoad.getSong()[sec].sectionNotes.length) - { - if (SongLoad.getSong()[sec].sectionNotes[notesse][2] == null) - { - trace('SUS NULL'); - SongLoad.getSong()[sec].sectionNotes[notesse][2] = 0; - } - } - } - */ - - for (i in sectionInfo) - { - var daNoteInfo = i.noteData; - var daStrumTime = i.strumTime; - var daSus = i.sustainLength; - - var note:Note = new Note(daStrumTime, daNoteInfo % 4); - note.data.sustainLength = daSus; - note.setGraphicSize(GRID_SIZE, GRID_SIZE); - note.updateHitbox(); - note.x = Math.floor(daNoteInfo * GRID_SIZE); - note.y = Math.floor(getYfromStrum((daStrumTime - sectionStartTime()) % (Conductor.stepCrochet * SongLoad.getSong()[curSection].lengthInSteps))); - - curRenderedNotes.add(note); - - if (daSus > 0) - { - var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2), - note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * 16, 0, gridBG.height))); - sustainVis.x -= sustainVis.width / 2; - sustainVis.color = Note.codeColors[note.data.noteData % 4]; - curRenderedSustains.add(sustainVis); - } - } - } - - private function addSection(lengthInSteps:Int = 16):Void - { - var sec:SwagSection = { - lengthInSteps: lengthInSteps, - bpm: _song.bpm, - changeBPM: false, - mustHitSection: true, - sectionNotes: [], - typeOfSection: 0, - altAnim: false - }; - - SongLoad.getSong().push(sec); - } - - function selectNote(note:Note):Void - { - var swagNum:Int = 0; - - for (i in SongLoad.getSong()[curSection].sectionNotes) - { - if (i.strumTime == note.data.strumTime && i.noteData % 4 == note.data.noteData) - { - curSelectedNote = SongLoad.getSong()[curSection].sectionNotes[swagNum]; - } - - swagNum += 1; - } - - updateGrid(); - updateNoteUI(); - } - - function deleteNote(note:Note):Void - { - for (i in SongLoad.getSong()[curSection].sectionNotes) - { - if (i.strumTime == note.data.strumTime && i.noteData % 4 == note.data.noteData) - { - var placeIDK:Int = Std.int(((Math.floor(dummyArrow.y / GRID_SIZE) * GRID_SIZE)) / 40); - - placeIDK = Std.int(Math.min(placeIDK, 15)); - placeIDK = Std.int(Math.max(placeIDK, 1)); - - trace(placeIDK); - FlxG.sound.play(Paths.sound('funnyNoise/funnyNoise-0' + placeIDK)); - - FlxG.log.add('FOUND EVIL NUMBER'); - SongLoad.getSong()[curSection].sectionNotes.remove(i); - } - } - - updateGrid(); - } - - function clearSection():Void - { - SongLoad.getSong()[curSection].sectionNotes = []; - - updateGrid(); - } - - function clearSong():Void - { - for (daSection in 0...SongLoad.getSong().length) - { - SongLoad.getSong()[daSection].sectionNotes = []; - } - - updateGrid(); - } - - /** - * Is true if clicked and placed a note, set reset to false when releasing mouse button! - */ - var justPlacedNote:Bool = false; - - private function addNote():Void - { - var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime(); - var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); - var noteSus = 0; - var noteKind = ""; - - justPlacedNote = true; - - // FlxG.sound.play(Paths.sound('pianoStuff/piano-00' + FlxG.random.int(1, 9)), FlxG.random.float(0.01, 0.3)); - - function makeAndPlayChord(soundsToPlay:Array) - { - var bullshit:Int = Std.int((Math.floor(dummyArrow.y / GRID_SIZE) * GRID_SIZE) / 40); - soundsToPlay.push('00' + Std.string((bullshit % 8) + 1)); - - for (key in soundsToPlay) - { - var snd:FlxSound = FlxG.sound.list.recycle(FlxSound).loadEmbedded(FlxG.sound.cache(Paths.sound("pianoStuff/piano-" + key))); - snd.autoDestroy = true; - FlxG.sound.list.add(snd); - snd.volume = FlxG.random.float(0.05, 0.7); - snd.pan = noteData - 2; // .... idk why tf panning doesnt work? (as of 2022/01/25) busted ass bullshit. I only went thru this fuss of creating FlxSound just for the panning! - - // snd.proximity(FlxG.mouse.x, FlxG.mouse.y, gridBG, gridBG.width / 2); - - snd.play(); - } - } - - switch (noteData) - { - case 0: - makeAndPlayChord(["015", "013", "009"]); - case 1: - makeAndPlayChord(["015", "012", "009"]); - case 2: - makeAndPlayChord(["015", "011", "009"]); - case 3: - makeAndPlayChord(["014", "011", "010"]); - } - - // trace('bullshit $bullshit'); // trace(Math.floor(dummyArrow.y / GRID_SIZE) * GRID_SIZE); - - var daNewNote:Note = new Note(noteStrum, noteData); - daNewNote.data.sustainLength = noteSus; - daNewNote.data.noteKind = noteKind; - SongLoad.getSong()[curSection].sectionNotes.push(daNewNote.data); - - curSelectedNote = SongLoad.getSong()[curSection].sectionNotes[SongLoad.getSong()[curSection].sectionNotes.length - 1]; - - if (FlxG.keys.pressed.CONTROL) - { - // SongLoad.getSong()[curSection].sectionNotes.push([noteStrum, (noteData + 4) % 8, noteSus, noteAlt]); - } - - trace(noteStrum); - trace(curSection); - - updateGrid(); - updateNoteUI(); - - autosaveSong(); - } - - function getStrumTime(yPos:Float):Float - { - return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet); - } - - function getYfromStrum(strumTime:Float):Float - { - return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height); - } - - /* - function calculateSectionLengths(?sec:SwagSection):Int - { - var daLength:Int = 0; - - for (i in SongLoad.getSong()) - { - var swagLength = i.lengthInSteps; - - if (i.typeOfSection == Section.COPYCAT) - swagLength * 2; - - daLength += swagLength; - - if (sec != null && sec == i) - { - trace('swag loop??'); - break; - } - } - - return daLength; - }*/ - private var daSpacing:Float = 0.3; - - function loadLevel():Void - { - trace(SongLoad.getSong()); - } - - function getNotes():Array - { - var noteData:Array = []; - - for (i in SongLoad.getSong()) - { - noteData.push(i.sectionNotes); - } - - return noteData; - } - - function loadJson(song:String):Void - { - PlayState.currentSong = SongLoad.loadFromJson(song.toLowerCase(), song.toLowerCase()); - LoadingState.loadAndSwitchState(new ChartingState()); - } - - function loadAutosave():Void - { - PlayState.currentSong = FlxG.save.data.autosave; - FlxG.resetState(); - } - - function autosaveSong():Void - { - FlxG.save.data.autosave = _song; - // trace(FlxG.save.data.autosave); - FlxG.save.flush(); - } - - private function saveLevel(?debugSavepath:Bool = false) - { - // Right now the note data is saved as a Note.NoteData typedef / object or whatev - // we want to format it to an ARRAY. We turn it back into the typedef / object at the end of this function hehe - - for (key in _song.noteMap.keys()) - SongLoad.castNoteDataToArray(_song.noteMap[key]); - - // SongLoad.castNoteDataToArray(_song.notes.easy); - // SongLoad.castNoteDataToArray(_song.notes.normal); - // SongLoad.castNoteDataToArray(_song.notes.hard); - - var json = {"song": _song}; - var data:String = Json.stringify(json, null, "\t"); - - #if sys - // quick workaround, since it easier to load into hashlink, thus quicker/nicer to test? - // should get this auto-saved into a file or somethin - var filename = _song.song.toLowerCase(); - - if (debugSavepath) - { - // file path to assumingly your assets folder in your SOURCE CODE assets folder!!! - // update this later so the save button ONLY appears when you compile in debug mode! - sys.io.File.saveContent('../../../../assets/preload/data/$filename/$filename.json', data); - } - else - sys.io.File.saveContent('./$filename.json', data); - #else - if ((data != null) && (data.length > 0)) - { - _file = new FileReference(); - _file.addEventListener(Event.COMPLETE, onSaveComplete); - _file.addEventListener(Event.CANCEL, onSaveCancel); - _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file.save(data.trim(), _song.song.toLowerCase() + ".json"); - } - #end - - for (key in _song.noteMap.keys()) - SongLoad.castArrayToNoteData(_song.noteMap[key]); - - // turn the array data back to Note.NoteData typedef - // SongLoad.castArrayToNoteData(_song.notes.easy); - // SongLoad.castArrayToNoteData(_song.notes.normal); - // SongLoad.castArrayToNoteData(_song.notes.hard); - } - - function onSaveComplete(_):Void - { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - FlxG.log.notice("Successfully saved LEVEL DATA."); - } - - /** - * Called when the save file dialog is cancelled. - */ - function onSaveCancel(_):Void - { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - } - - /** - * Called if there is an error while saving the gameplay recording. - */ - function onSaveError(_):Void - { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - FlxG.log.error("Problem saving Level data"); - } + function addSongUI():Void + { + var UI_songTitle = new FlxUIInputText(10, 10, 70, _song.song, 8); + typingShit = UI_songTitle; + + var check_voices = new FlxUICheckBox(10, 25, null, null, "Has voice track", 100); + check_voices.checked = _song.needsVoices; + // _song.needsVoices = check_voices.checked; + check_voices.callback = function() + { + _song.needsVoices = check_voices.checked; + trace('CHECKED!'); + }; + + var check_mute_inst = new FlxUICheckBox(10, 200, null, null, "Mute Instrumental (in editor)", 100); + check_mute_inst.checked = false; + check_mute_inst.callback = function() + { + var vol:Float = 1; + + if (check_mute_inst.checked) vol = 0; + + FlxG.sound.music.volume = vol; + }; + + var saveButton:FlxButton = new FlxButton(110, 8, "Save", function() + { + saveLevel(); + }); + + var saveCompiler:FlxButton = new FlxButton(110, 30, "Save compile", function() + { + saveLevel(true); + }); + + var reloadSong:FlxButton = new FlxButton(saveButton.x + saveButton.width + 10, saveButton.y, "Reload Audio", function() + { + loadSong(_song.song); + }); + + var reloadSongJson:FlxButton = new FlxButton(reloadSong.x, saveButton.y + 30, "Reload JSON", function() + { + FlxTransitionableState.skipNextTransIn = true; + FlxTransitionableState.skipNextTransOut = true; + loadJson(_song.song.toLowerCase()); + }); + + var loadAutosaveBtn:FlxButton = new FlxButton(reloadSongJson.x, reloadSongJson.y + 30, 'load autosave', loadAutosave); + + var stepperSpeed:FlxUINumericStepper = new FlxUINumericStepper(10, 80, 0.1, 1, 0.1, 10, 2); + stepperSpeed.value = SongLoad.getSpeed(); + // stepperSpeed.value = _song.speed[SongLoad.curDiff]; + stepperSpeed.name = 'song_speed'; + + var stepperBPM:FlxUINumericStepper = new FlxUINumericStepper(10, 65, 1, 100, 1, 999, 3); + stepperBPM.value = Conductor.bpm; + stepperBPM.name = 'song_bpm'; + + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); + + var player1DropDown = new FlxUIDropDownMenu(10, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) + { + _song.player1 = characters[Std.parseInt(character)]; + updateHeads(); + }); + player1DropDown.selectedLabel = _song.player1; + + var player2DropDown = new FlxUIDropDownMenu(140, 100, FlxUIDropDownMenu.makeStrIdLabelArray(characters, true), function(character:String) + { + _song.player2 = characters[Std.parseInt(character)]; + updateHeads(); + }); + player2DropDown.selectedLabel = _song.player2; + + var difficultyDropDown = new FlxUIDropDownMenu(10, 230, FlxUIDropDownMenu.makeStrIdLabelArray(_song.difficulties, true), function(diff:String) + { + SongLoad.curDiff = _song.difficulties[Std.parseInt(diff)]; + SongLoad.checkAndCreateNotemap(SongLoad.curDiff); + + while (SongLoad.getSong()[curSection] == null) + addSection(); + + updateGrid(); + }); + difficultyDropDown.selectedLabel = SongLoad.curDiff; + + var difficultyAdder = new FlxUIInputText(130, 230, 100, "", 12); + + var addDiff:FlxButton = new FlxButton(130, 250, "Add Difficulty", function() + { + difficultyAdder.text = ""; + // something to regenerate difficulties + }); + + var tab_group_song = new FlxUI(null, UI_box); + tab_group_song.name = "Song"; + tab_group_song.add(UI_songTitle); + + tab_group_song.add(check_voices); + tab_group_song.add(check_mute_inst); + tab_group_song.add(saveButton); + tab_group_song.add(saveCompiler); + tab_group_song.add(reloadSong); + tab_group_song.add(reloadSongJson); + tab_group_song.add(loadAutosaveBtn); + tab_group_song.add(stepperBPM); + tab_group_song.add(stepperSpeed); + tab_group_song.add(player1DropDown); + tab_group_song.add(player2DropDown); + tab_group_song.add(difficultyDropDown); + tab_group_song.add(difficultyAdder); + tab_group_song.add(addDiff); + + UI_box.addGroup(tab_group_song); + UI_box.scrollFactor.set(); + + FlxG.camera.focusOn(gridBG.getGraphicMidpoint()); + } + + var stepperLength:FlxUINumericStepper; + var check_mustHitSection:FlxUICheckBox; + var check_changeBPM:FlxUICheckBox; + var stepperSectionBPM:FlxUINumericStepper; + var check_altAnim:FlxUICheckBox; + + function addSectionUI():Void + { + var tab_group_section = new FlxUI(null, UI_box); + tab_group_section.name = 'Section'; + + stepperLength = new FlxUINumericStepper(10, 10, 4, 0, 0, 999, 0); + stepperLength.value = SongLoad.getSong()[curSection].lengthInSteps; + stepperLength.name = "section_length"; + + stepperSectionBPM = new FlxUINumericStepper(10, 80, 1, Conductor.bpm, 1, 999, 3); + stepperSectionBPM.value = Conductor.bpm; + stepperSectionBPM.name = 'section_bpm'; + + var stepperCopy:FlxUINumericStepper = new FlxUINumericStepper(110, 130, 1, 1, -999, 999, 0); + + var copyButton:FlxButton = new FlxButton(10, 130, "Copy last section", function() + { + copySection(Std.int(stepperCopy.value)); + }); + + var clearSectionButton:FlxButton = new FlxButton(10, 150, "Clear", clearSection); + + var swapSection:FlxButton = new FlxButton(10, 170, "Swap section", function() + { + for (i in 0...SongLoad.getSong()[curSection].sectionNotes.length) + { + var note:Note = new Note(0, 0); + note.data = SongLoad.getSong()[curSection].sectionNotes[i]; + note.data.noteData = (note.data.noteData + 4) % 8; + SongLoad.getSong()[curSection].sectionNotes[i] = note.data; + updateGrid(); + } + }); + + check_mustHitSection = new FlxUICheckBox(10, 30, null, null, "Must hit section", 100); + check_mustHitSection.name = 'check_mustHit'; + check_mustHitSection.checked = true; + // _song.needsVoices = check_mustHit.checked; + + check_altAnim = new FlxUICheckBox(10, 400, null, null, "Alt Animation", 100); + check_altAnim.name = 'check_altAnim'; + + check_changeBPM = new FlxUICheckBox(10, 60, null, null, 'Change BPM', 100); + check_changeBPM.name = 'check_changeBPM'; + + tab_group_section.add(stepperLength); + tab_group_section.add(stepperSectionBPM); + tab_group_section.add(stepperCopy); + tab_group_section.add(check_mustHitSection); + tab_group_section.add(check_altAnim); + tab_group_section.add(check_changeBPM); + tab_group_section.add(copyButton); + tab_group_section.add(clearSectionButton); + tab_group_section.add(swapSection); + + UI_box.addGroup(tab_group_section); + } + + var stepperSusLength:FlxUINumericStepper; + var stepperPerNoteSpeed:FlxUINumericStepper; + + function addNoteUI():Void + { + var tab_group_note = new FlxUI(null, UI_box); + tab_group_note.name = 'Note'; + + stepperSusLength = new FlxUINumericStepper(10, 10, Conductor.stepCrochet / 2, 0, 0, Conductor.stepCrochet * 16); + stepperSusLength.value = 0; + stepperSusLength.name = 'note_susLength'; + + stepperPerNoteSpeed = new FlxUINumericStepper(10, 40, 0.1, 1, 0.01, 100, 2); + stepperPerNoteSpeed.value = 1; + stepperPerNoteSpeed.name = "note_PerNoteSpeed"; + + var noteSpeedName:FlxText = new FlxText(40, stepperPerNoteSpeed.y, 0, "Note Speed Multiplier"); + + var applyLength:FlxButton = new FlxButton(100, 10, 'Apply'); + + tab_group_note.add(stepperSusLength); + tab_group_note.add(stepperPerNoteSpeed); + tab_group_note.add(noteSpeedName); + tab_group_note.add(applyLength); + + UI_box.addGroup(tab_group_note); + } + + // var spec:SpectogramSprite; + + function loadSong(daSong:String):Void + { + if (FlxG.sound.music != null) + { + FlxG.sound.music.stop(); + // vocals.stop(); + } + + var pathShit = Paths.inst(daSong); + + if (!openfl.utils.Assets.cache.hasSound(pathShit)) + { + var library = Assets.getLibrary("songs"); + var symbolPath = pathShit.split(":").pop(); + // @:privateAccess + // library.types.set(symbolPath, SOUND); + // @:privateAccess + // library.pathGroups.set(symbolPath, [library.__cacheBreak(symbolPath)]); + // var callback = callbacks.add("song:" + pathShit); + openfl.utils.Assets.loadSound(pathShit).onComplete(function(_) + { + // callback(); + }); + } + + FlxG.sound.playMusic(Paths.inst(daSong), 0.6); + + var musSpec:PolygonSpectogram = new PolygonSpectogram(FlxG.sound.music, FlxColor.RED, FlxG.height / 2, Math.floor(FlxG.height / 2)); + musSpec.x += 170; + musSpec.scrollFactor.set(); + musSpec.waveAmplitude = 50; + // musSpec.visType = FREQUENCIES; + add(musSpec); + + sidePreview = new FlxSprite(0, 0).makeGraphic(40, FlxG.height, FlxColor.GRAY); + sidePreview.scrollFactor.set(); + add(sidePreview); + + // trace(audioBuf.data.length); + playheadTest = new FlxSprite(0, 0).makeGraphic(30, 2, FlxColor.RED); + playheadTest.scrollFactor.set(); + playheadTest.alpha = 0.5; + add(playheadTest); + + // WONT WORK FOR TUTORIAL OR TEST SONG!!! REDO LATER + vocals = VoicesGroup.build(daSong, _song.voiceList); + // vocals = new FlxSound().loadEmbedded(Paths.voices(daSong)); + // FlxG.sound.list.add(vocals); + + staticSpecGrp = new FlxTypedGroup(); + add(staticSpecGrp); + + var aBoy:ABotVis = new ABotVis(FlxG.sound.music); + // add(aBoy); + + for (index => voc in vocals.members) + { + var vocalSpec:SpectogramSprite = new SpectogramSprite(voc, FlxG.random.color(0xFFAAAAAA, FlxColor.WHITE, 100), musSpec.daHeight, + Math.floor(FlxG.height / 2)); + vocalSpec.x = 70 - (50 * index); + // vocalSpec.visType = FREQUENCIES; + vocalSpec.daHeight = musSpec.daHeight; + vocalSpec.y = vocalSpec.daHeight; + vocalSpec.scrollFactor.set(); + add(vocalSpec); + + var staticVocal:SpectogramSprite = new SpectogramSprite(voc, FlxG.random.color(0xFFAAAAAA, FlxColor.WHITE, 100), GRID_SIZE * 16, GRID_SIZE * 8); + if (index == 0) staticVocal.x -= 150; + + if (index == 1) staticVocal.x = gridBG.width; + + staticVocal.visType = STATIC; + staticSpecGrp.add(staticVocal); + } + + FlxG.sound.music.pause(); + + vocals.pause(); + + FlxG.sound.music.onComplete = function() + { + vocals.pause(); + vocals.time = 0; + FlxG.sound.music.pause(); + FlxG.sound.music.time = 0; + changeSection(); + }; + } + + function generateUI():Void + { + while (bullshitUI.members.length > 0) + { + bullshitUI.remove(bullshitUI.members[0], true); + } + + // general shit + var title:FlxText = new FlxText(UI_box.x + 20, UI_box.y + 20, 0); + bullshitUI.add(title); + /* + var loopCheck = new FlxUICheckBox(UI_box.x + 10, UI_box.y + 50, null, null, "Loops", 100, ['loop check']); + loopCheck.checked = notes[0]elected.doesLoop; + tooltips.add(loopCheck, {title: 'Section looping', body: "Whether or not it's a simon says style section", style: tooltipType}); + bullshitUI.add(loopCheck); + + */ + } + + override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) + { + if (id == FlxUICheckBox.CLICK_EVENT) + { + var check:FlxUICheckBox = cast sender; + var label = check.getLabel().text; + switch (label) + { + case 'Must hit section': + SongLoad.getSong()[curSection].mustHitSection = check.checked; + + updateHeads(); + + case 'Change BPM': + SongLoad.getSong()[curSection].changeBPM = check.checked; + FlxG.log.add('changed bpm shit'); + case "Alt Animation": + SongLoad.getSong()[curSection].altAnim = check.checked; + } + } + else if (id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) + { + var nums:FlxUINumericStepper = cast sender; + var wname = nums.name; + FlxG.log.add(wname); + if (wname == 'section_length') + { + SongLoad.getSong()[curSection].lengthInSteps = Std.int(nums.value); + updateGrid(); + } + else if (wname == 'song_speed') + { + // _song.speed[SongLoad.curDiff] = nums.value; + _song.speed.normal = nums.value; + } + else if (wname == 'song_bpm') + { + tempBpm = nums.value; + Conductor.mapBPMChanges(_song); + Conductor.forceBPM(nums.value); + } + else if (wname == 'note_susLength') + { + curSelectedNote.sustainLength = nums.value; + updateGrid(); + } + else if (wname == 'section_bpm') + { + SongLoad.getSong()[curSection].bpm = nums.value; + updateGrid(); + } + } + + // FlxG.log.add(id + " WEED " + sender + " WEED " + data + " WEED " + params); + } + + var updatedSection:Bool = false; + + /* this function got owned LOL + function lengthBpmBullshit():Float + { + if (SongLoad.getSong()[curSection].changeBPM) + return SongLoad.getSong()[curSection].lengthInSteps * (SongLoad.getSong()[curSection].bpm / _song.bpm); + else + return SongLoad.getSong()[curSection].lengthInSteps; + }*/ + /** + * Gets the start time of section, defaults to the curSection + * @param section + * @return position of the song in... either seconds or milliseconds.... woops + */ + function sectionStartTime(?funnySection:Int):Float + { + if (funnySection == null) funnySection = curSection; + + var daBPM:Float = _song.bpm; + var daPos:Float = 0; + for (i in 0...funnySection) + { + if (SongLoad.getSong()[i].changeBPM) + { + daBPM = SongLoad.getSong()[i].bpm; + } + daPos += 4 * sectionCalc(daBPM); + } + return daPos; + } + + function measureStartTime():Float + { + var daBPM:Float = _song.bpm; + var daPos:Float = sectionStartTime(); + + daPos = Math.floor(FlxG.sound.music.time / sectionCalc(daBPM)) * sectionCalc(daBPM); + return daPos; + } + + function sectionCalc(bpm:Float) + { + return (1000 * 60 / bpm); + } + + var p1Muted:Bool = false; + var p2Muted:Bool = false; + + override function update(elapsed:Float) + { + // FlxG.camera.followLerp = CoolUtil.camLerpShit(0.05); + + FlxG.sound.music.pan = FlxMath.remapToRange(FlxG.mouse.screenX, 0, FlxG.width, -1, 1) * 10; + + // curStep = recalculateSteps(); + + Conductor.songPosition = FlxG.sound.music.time; + _song.song = typingShit.text; + + playheadTest.y = CoolUtil.coolLerp(playheadTest.y, FlxMath.remapToRange(Conductor.songPosition, 0, FlxG.sound.music.length, 0, FlxG.height), 0.5); + + var strumLinePos:Float = getYfromStrum((Conductor.songPosition - sectionStartTime()) % (Conductor.stepCrochet * SongLoad.getSong()[curSection].lengthInSteps)); + + if (FlxG.sound.music != null) + { + if (FlxG.sound.music.playing) strumLine.y = strumLinePos; + else + strumLine.y = CoolUtil.coolLerp(strumLine.y, strumLinePos, 0.5); + } + + /* if (FlxG.sound.music.playing) + { + var normalizedShitIDK:Int = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, FlxG.sound.music.length, 0, audioBuf.data.length)); + FlxG.watch.addQuick('WEIRD AUDIO SHIT LOL', audioBuf.data[normalizedShitIDK]); + // leftIcon.scale.x = FlxMath.remapToRange(audioBuf.data[normalizedShitIDK], 0, 255, 1, 2); + }*/ + + if (FlxG.keys.justPressed.X) toggleAltAnimNote(); + + if (false) // (curBeat % 4 == 0 && curStep >= 16 * (curSection + 1)) + { + // trace(curStep); + // trace((SongLoad.getSong()[curSection].lengthInSteps) * (curSection + 1)); + trace('DUMBSHIT'); + + if (SongLoad.getSong()[curSection + 1] == null) + { + addSection(); + } + + changeSection(curSection + 1, false); + } + + FlxG.watch.addQuick('daBeat', Conductor.currentBeat); + FlxG.watch.addQuick('daStep', Conductor.currentStep); + + if (FlxG.mouse.pressedMiddle && FlxG.mouse.overlaps(gridBG)) + { + if (FlxG.sound.music.playing) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + + FlxG.sound.music.time = CoolUtil.coolLerp(FlxG.sound.music.time, getStrumTime(FlxG.mouse.y) + sectionStartTime(), 0.5); + vocals.time = FlxG.sound.music.time; + } + + if (FlxG.mouse.pressed) + { + if (FlxG.keys.pressed.ALT && FlxG.mouse.overlaps(gridBG)) // same shit as middle click / hold on grid + { + if (FlxG.sound.music.playing) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + + FlxG.sound.music.time = getStrumTime(FlxG.mouse.y) + sectionStartTime(); + vocals.time = FlxG.sound.music.time; + } + else + { + if (FlxG.mouse.screenX <= 30 && FlxMath.inBounds(FlxG.mouse.screenY, 0, FlxG.height)) + { + if (FlxG.sound.music.playing) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + + FlxG.sound.music.time = CoolUtil.coolLerp(FlxG.sound.music.time, + FlxMath.remapToRange(FlxG.mouse.screenY, 0, FlxG.height, 0, FlxG.sound.music.length), 0.5); + vocals.time = FlxG.sound.music.time; + } + if (FlxG.mouse.justPressed) + { + if (FlxG.mouse.overlaps(leftIcon)) + { + if (leftIcon.characterId == _song.player1) + { + p1Muted = !p1Muted; + leftIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; + } + else + { + p2Muted = !p2Muted; + + leftIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; + } + + vocals.members[0].volume = p1Muted ? 0 : 1; + + // null check jus in case using old shit? + if (vocals.members[1] != null) vocals.members[1].volume = p2Muted ? 0 : 1; + } + + // sloppy copypaste lol deal with it! + if (FlxG.mouse.overlaps(rightIcon)) + { + if (rightIcon.characterId == _song.player1) + { + p1Muted = !p1Muted; + rightIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; + } + else + { + rightIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; + p2Muted = !p2Muted; + } + + vocals.members[0].volume = p1Muted ? 0 : 1; + + // null check jus in case using old shit? + if (vocals.members[1] != null) vocals.members[1].volume = p2Muted ? 0 : 1; + } + + if (FlxG.mouse.overlaps(curRenderedNotes)) + { + curRenderedNotes.forEach(function(note:Note) + { + if (FlxG.mouse.overlaps(note)) + { + selectNote(note); + } + }); + } + else + { + if (FlxG.mouse.overlaps(gridBG)) + { + FlxG.log.add('added note'); + addNote(); + } + } + } + } + } + + if (FlxG.mouse.pressedRight) + { + if (FlxG.mouse.overlaps(curRenderedNotes)) + { + curRenderedNotes.forEach(function(note:Note) + { + if (FlxG.mouse.overlaps(note)) + { + trace('tryin to delete note...'); + deleteNote(note); + } + }); + } + } + + if (FlxG.mouse.justReleased) justPlacedNote = false; + + if (FlxG.mouse.overlaps(gridBG)) + { + if (justPlacedNote && FlxG.mouse.pressed && FlxG.mouse.y > getYfromStrum(curSelectedNote.strumTime)) + { + var minusStuff:Float = FlxG.mouse.y - getYfromStrum(curSelectedNote.strumTime); + minusStuff -= GRID_SIZE; + minusStuff += GRID_SIZE / 2; + minusStuff = Math.floor(minusStuff / GRID_SIZE) * GRID_SIZE; + minusStuff = FlxMath.remapToRange(minusStuff, 0, 40, 0, Conductor.stepCrochet); + + curSelectedNote.sustainLength = minusStuff; + + updateNoteUI(); + updateGrid(); + } + + dummyArrow.x = Math.floor(FlxG.mouse.x / GRID_SIZE) * GRID_SIZE; + if (FlxG.keys.pressed.SHIFT) dummyArrow.y = FlxG.mouse.y; + else + dummyArrow.y = Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE; + } + + if (FlxG.keys.justPressed.ENTER) + { + autosaveSong(); + + lastSection = curSection; + + PlayState.currentSong = _song; + + // JUST FOR DEBUG DARNELL STUFF, GENERALIZE THIS FOR BETTER LOADING ELSEWHERE TOO! + PlayState.storyWeek = 8; + + FlxG.sound.music.stop(); + vocals.stop(); + LoadingState.loadAndSwitchState(new PlayState()); + // FlxG.switchState(new PlayState()); + } + + if (FlxG.keys.justPressed.E) + { + changeNoteSustain(Conductor.stepCrochet); + } + if (FlxG.keys.justPressed.Q) + { + changeNoteSustain(-Conductor.stepCrochet); + } + + if (FlxG.keys.justPressed.TAB) + { + if (FlxG.keys.pressed.SHIFT) + { + UI_box.selected_tab -= 1; + if (UI_box.selected_tab < 0) UI_box.selected_tab = 2; + } + else + { + UI_box.selected_tab += 1; + if (UI_box.selected_tab >= 3) UI_box.selected_tab = 0; + } + } + + if (!typingShit.hasFocus) + { + if (FlxG.keys.justPressed.SPACE) + { + if (FlxG.sound.music.playing) + { + FlxG.sound.music.pause(); + vocals.pause(); + } + else + { + vocals.play(); + FlxG.sound.music.play(); + } + } + + if (FlxG.keys.justPressed.R) + { + if (FlxG.keys.pressed.CONTROL) resetSection(BEGINNING); + else if (FlxG.keys.pressed.SHIFT) resetSection(MEASURE); + else + resetSection(SECTION); + } + + if (FlxG.mouse.wheel != 0) + { + FlxG.sound.music.pause(); + vocals.pause(); + + var ctrlMod:Float = FlxG.keys.pressed.CONTROL ? 0.1 : 1; + var shiftMod:Float = FlxG.keys.pressed.SHIFT ? 2 : 1; + + FlxG.sound.music.time -= (FlxG.mouse.wheel * Conductor.stepCrochet * 0.4 * ctrlMod * shiftMod); + vocals.time = FlxG.sound.music.time; + } + + if (FlxG.keys.justReleased.S) + { + FlxG.sound.music.pause(); + vocals.pause(); + + #if HAS_PITCH + FlxG.sound.music.pitch = 1; + vocals.pitch = 1; + #end + } + + if (!FlxG.keys.pressed.SHIFT) + { + if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) + { + var daTime:Float = 700 * elapsed; + + if (FlxG.keys.pressed.CONTROL) daTime *= 0.2; + + if (FlxG.keys.pressed.W) + { + FlxG.sound.music.pause(); + vocals.pause(); + FlxG.sound.music.time -= daTime; + vocals.time = FlxG.sound.music.time; + } + else + { + if (FlxG.keys.justPressed.S) + { + FlxG.sound.music.play(); + vocals.play(); + + #if HAS_PITCH + FlxG.sound.music.pitch = 0.5; + vocals.pitch = 0.5; + #end + } + } + // FlxG.sound.music.time += daTime; + + // vocals.time = FlxG.sound.music.time; + } + } + else + { + if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S) + { + var daTime:Float = Conductor.stepCrochet * 2; + + if (FlxG.keys.justPressed.W) + { + FlxG.sound.music.pause(); + vocals.pause(); + + FlxG.sound.music.time -= daTime; + vocals.time = FlxG.sound.music.time; + } + else + { + if (FlxG.keys.justPressed.S) + { + // FlxG.sound.music.time += daTime; + + FlxG.sound.music.pause(); + vocals.pause(); + + FlxG.sound.music.time += daTime; + vocals.time = FlxG.sound.music.time; + + // FlxG.sound.music.play(); + // vocals.play(); + + #if HAS_PITCH + FlxG.sound.music.pitch = 0.2; + vocals.pitch = 0.2; + #end + } + } + } + } + } + + _song.bpm = tempBpm; + + /* if (FlxG.keys.justPressed.UP) + Conductor.bpm = Conductor.bpm + 1; + if (FlxG.keys.justPressed.DOWN) + Conductor.bpm = Conductor.bpm - 1; */ + + var shiftThing:Int = 1; + if (FlxG.keys.pressed.SHIFT) shiftThing = 4; + if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.D) changeSection(curSection + shiftThing); + if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.A) changeSection(curSection - shiftThing); + + bpmTxt.text = bpmTxt.text = Std.string(FlxMath.roundDecimal(Conductor.songPosition / 1000, 3)) + + " / " + + Std.string(FlxMath.roundDecimal(FlxG.sound.music.length / 1000, 3)) + + "\nSection: " + + curSection; + super.update(elapsed); + } + + function changeNoteSustain(value:Float):Void + { + if (curSelectedNote != null) + { + curSelectedNote.sustainLength += value; + curSelectedNote.sustainLength = Math.max(curSelectedNote.sustainLength, 0); + } + + updateNoteUI(); + updateGrid(); + } + + function toggleAltAnimNote():Void + { + if (curSelectedNote != null) + { + trace('ALT NOTE SHIT'); + curSelectedNote.noteKind = (curSelectedNote.noteKind == "alt") ? "" : "alt"; + trace(curSelectedNote.noteKind); + } + } + + function recalculateSteps():Float + { + var lastChange:BPMChangeEvent = + { + stepTime: 0, + songTime: 0, + bpm: 0 + } + for (i in 0...Conductor.bpmChangeMap.length) + { + if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime) lastChange = Conductor.bpmChangeMap[i]; + } + + // curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet); + // updateBeat(); + + return Conductor.currentStep; + } + + function resetSection(songBeginning:SongResetType = SECTION):Void + { + updateGrid(); + + FlxG.sound.music.pause(); + vocals.pause(); + + switch (songBeginning) + { + case SECTION: + // Basically old shit from changeSection??? + FlxG.sound.music.time = sectionStartTime(); + case BEGINNING: + FlxG.sound.music.time = 0; + curSection = 0; + case MEASURE: + FlxG.sound.music.time = measureStartTime(); // Math.floor(FlxG.mouse.y / GRID_SIZE) * GRID_SIZE + default: + } + + vocals.time = FlxG.sound.music.time; + // updateCurStep(); + + updateGrid(); + updateSectionUI(); + } + + function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void + { + // trace('changing section' + sec); + + if (SongLoad.getSong()[sec] != null) + { + curSection = sec; + + updateGrid(); + + if (updateMusic) + { + FlxG.sound.music.pause(); + vocals.pause(); + + /*var daNum:Int = 0; + var daLength:Float = 0; + while (daNum <= sec) + { + daLength += lengthBpmBullshit(); + daNum++; + }*/ + + FlxG.sound.music.time = sectionStartTime(); + vocals.time = FlxG.sound.music.time; + // updateCurStep(); + } + + updateGrid(); + updateSectionUI(); + } + } + + function copySection(?sectionNum:Int = 1) + { + var daSec = FlxMath.maxInt(curSection, sectionNum); + + for (noteShit in SongLoad.getSong()[daSec - sectionNum].sectionNotes) + { + var strum = noteShit.strumTime + Conductor.stepCrochet * (SongLoad.getSong()[daSec].lengthInSteps * sectionNum); + + var copiedNote:Note = new Note(strum, noteShit.noteData); + copiedNote.data.sustainLength = noteShit.sustainLength; + SongLoad.getSong()[daSec].sectionNotes.push(copiedNote.data); + } + + updateGrid(); + } + + function updateSectionUI():Void + { + var sec = SongLoad.getSong()[curSection]; + + stepperLength.value = sec.lengthInSteps; + check_mustHitSection.checked = sec.mustHitSection; + check_altAnim.checked = sec.altAnim; + check_changeBPM.checked = sec.changeBPM; + stepperSectionBPM.value = sec.bpm; + + updateHeads(); + } + + function updateHeads():Void + { + if (check_mustHitSection.checked) + { + leftIcon.characterId = (_song.player1); + rightIcon.characterId = (_song.player2); + + // leftIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; + // rightIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; + + leftIcon.playAnimation(p1Muted ? LOSING : IDLE); + rightIcon.playAnimation(p2Muted ? LOSING : IDLE); + } + else + { + leftIcon.characterId = (_song.player2); + rightIcon.characterId = (_song.player1); + + leftIcon.playAnimation(p2Muted ? LOSING : IDLE); + rightIcon.playAnimation(p1Muted ? LOSING : IDLE); + + // leftIcon.animation.curAnim.curFrame = p2Muted ? 1 : 0; + // rightIcon.animation.curAnim.curFrame = p1Muted ? 1 : 0; + } + leftIcon.setGraphicSize(0, 45); + rightIcon.setGraphicSize(0, 45); + + leftIcon.height *= 0.6; + rightIcon.height *= 0.6; + } + + function updateNoteUI():Void + { + if (curSelectedNote != null) stepperSusLength.value = curSelectedNote.sustainLength; + } + + function updateGrid():Void + { + // null if checks jus cuz i put updateGrid() in some weird places! + if (staticSpecGrp != null) + { + staticSpecGrp.forEach(function(spec) + { + if (spec != null) spec.generateSection(sectionStartTime(), (Conductor.stepCrochet * 32) / 1000); + }); + } + + while (curRenderedNotes.members.length > 0) + { + curRenderedNotes.remove(curRenderedNotes.members[0], true); + } + + while (curRenderedSustains.members.length > 0) + { + curRenderedSustains.remove(curRenderedSustains.members[0], true); + } + + // generates the cool sidebar shit + if (sidePreview != null && sidePreview.active) + { + sidePreview.drawRect(0, 0, 40, FlxG.height, 0xFF444444); + + /* + var sectionsNeeded:Int = Std.int(FlxG.sound.music.length / (sectionCalc(_song.bpm) * 4)); + + while (sectionsNeeded > 0) + { + sidePreview.drawRect(0, sectionsNeeded * (FlxG.height / sectionsNeeded), 40, FlxG.height / sectionsNeeded, + (sectionsNeeded % 2 == 0 ? 0xFF000000 : 0xFFFFFFFF)); + + sectionsNeeded--; + } + */ + + for (secIndex => sideSection in SongLoad.getSong()) + { + for (notes in sideSection.sectionNotes) + { + var col:Int = Note.codeColors[notes.noteData % 4]; + + var noteFlip:Int = (sideSection.mustHitSection ? 1 : -1); + var noteX:Float = 5 * (((notes.noteData - 4) * noteFlip) + 4); + + sidePreview.drawRect(noteX, FlxMath.remapToRange(notes.strumTime, 0, FlxG.sound.music.length, 0, FlxG.height), 5, 1, col); + } + } + } + + var sectionInfo:Array = SongLoad.getSong()[curSection].sectionNotes; + + if (SongLoad.getSong()[curSection].changeBPM && SongLoad.getSong()[curSection].bpm > 0) + { + Conductor.forceBPM(SongLoad.getSong()[curSection].bpm); + FlxG.log.add('CHANGED BPM!'); + } + else + { + // get last bpm + var daBPM:Float = _song.bpm; + for (i in 0...curSection) + if (SongLoad.getSong()[i].changeBPM) daBPM = SongLoad.getSong()[i].bpm; + Conductor.forceBPM(daBPM); + } + + /* // PORT BULLSHIT, INCASE THERE'S NO SUSTAIN DATA FOR A NOTE + for (sec in 0...SongLoad.getSong().length) + { + for (notesse in 0...SongLoad.getSong()[sec].sectionNotes.length) + { + if (SongLoad.getSong()[sec].sectionNotes[notesse][2] == null) + { + trace('SUS NULL'); + SongLoad.getSong()[sec].sectionNotes[notesse][2] = 0; + } + } + } + */ + + for (i in sectionInfo) + { + var daNoteInfo = i.noteData; + var daStrumTime = i.strumTime; + var daSus = i.sustainLength; + + var note:Note = new Note(daStrumTime, daNoteInfo % 4); + note.data.sustainLength = daSus; + note.setGraphicSize(GRID_SIZE, GRID_SIZE); + note.updateHitbox(); + note.x = Math.floor(daNoteInfo * GRID_SIZE); + note.y = Math.floor(getYfromStrum((daStrumTime - sectionStartTime()) % (Conductor.stepCrochet * SongLoad.getSong()[curSection].lengthInSteps))); + + curRenderedNotes.add(note); + + if (daSus > 0) + { + var sustainVis:FlxSprite = new FlxSprite(note.x + (GRID_SIZE / 2), + note.y + GRID_SIZE).makeGraphic(8, Math.floor(FlxMath.remapToRange(daSus, 0, Conductor.stepCrochet * 16, 0, gridBG.height))); + sustainVis.x -= sustainVis.width / 2; + sustainVis.color = Note.codeColors[note.data.noteData % 4]; + curRenderedSustains.add(sustainVis); + } + } + } + + function addSection(lengthInSteps:Int = 16):Void + { + var sec:SwagSection = + { + lengthInSteps: lengthInSteps, + bpm: _song.bpm, + changeBPM: false, + mustHitSection: true, + sectionNotes: [], + typeOfSection: 0, + altAnim: false + }; + + SongLoad.getSong().push(sec); + } + + function selectNote(note:Note):Void + { + var swagNum:Int = 0; + + for (i in SongLoad.getSong()[curSection].sectionNotes) + { + if (i.strumTime == note.data.strumTime && i.noteData % 4 == note.data.noteData) + { + curSelectedNote = SongLoad.getSong()[curSection].sectionNotes[swagNum]; + } + + swagNum += 1; + } + + updateGrid(); + updateNoteUI(); + } + + function deleteNote(note:Note):Void + { + for (i in SongLoad.getSong()[curSection].sectionNotes) + { + if (i.strumTime == note.data.strumTime && i.noteData % 4 == note.data.noteData) + { + var placeIDK:Int = Std.int(((Math.floor(dummyArrow.y / GRID_SIZE) * GRID_SIZE)) / 40); + + placeIDK = Std.int(Math.min(placeIDK, 15)); + placeIDK = Std.int(Math.max(placeIDK, 1)); + + trace(placeIDK); + FlxG.sound.play(Paths.sound('funnyNoise/funnyNoise-0' + placeIDK)); + + FlxG.log.add('FOUND EVIL NUMBER'); + SongLoad.getSong()[curSection].sectionNotes.remove(i); + } + } + + updateGrid(); + } + + function clearSection():Void + { + SongLoad.getSong()[curSection].sectionNotes = []; + + updateGrid(); + } + + function clearSong():Void + { + for (daSection in 0...SongLoad.getSong().length) + { + SongLoad.getSong()[daSection].sectionNotes = []; + } + + updateGrid(); + } + + /** + * Is true if clicked and placed a note, set reset to false when releasing mouse button! + */ + var justPlacedNote:Bool = false; + + function addNote():Void + { + var noteStrum = getStrumTime(dummyArrow.y) + sectionStartTime(); + var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); + var noteSus = 0; + var noteKind = ""; + + justPlacedNote = true; + + // FlxG.sound.play(Paths.sound('pianoStuff/piano-00' + FlxG.random.int(1, 9)), FlxG.random.float(0.01, 0.3)); + + function makeAndPlayChord(soundsToPlay:Array) + { + var bullshit:Int = Std.int((Math.floor(dummyArrow.y / GRID_SIZE) * GRID_SIZE) / 40); + soundsToPlay.push('00' + Std.string((bullshit % 8) + 1)); + + for (key in soundsToPlay) + { + var snd:FlxSound = FlxG.sound.list.recycle(FlxSound).loadEmbedded(FlxG.sound.cache(Paths.sound("pianoStuff/piano-" + key))); + snd.autoDestroy = true; + FlxG.sound.list.add(snd); + snd.volume = FlxG.random.float(0.05, 0.7); + snd.pan = noteData - 2; // .... idk why tf panning doesnt work? (as of 2022/01/25) busted ass bullshit. I only went thru this fuss of creating FlxSound just for the panning! + + // snd.proximity(FlxG.mouse.x, FlxG.mouse.y, gridBG, gridBG.width / 2); + + snd.play(); + } + } + + switch (noteData) + { + case 0: + makeAndPlayChord(["015", "013", "009"]); + case 1: + makeAndPlayChord(["015", "012", "009"]); + case 2: + makeAndPlayChord(["015", "011", "009"]); + case 3: + makeAndPlayChord(["014", "011", "010"]); + } + + // trace('bullshit $bullshit'); // trace(Math.floor(dummyArrow.y / GRID_SIZE) * GRID_SIZE); + + var daNewNote:Note = new Note(noteStrum, noteData); + daNewNote.data.sustainLength = noteSus; + daNewNote.data.noteKind = noteKind; + SongLoad.getSong()[curSection].sectionNotes.push(daNewNote.data); + + curSelectedNote = SongLoad.getSong()[curSection].sectionNotes[SongLoad.getSong()[curSection].sectionNotes.length - 1]; + + if (FlxG.keys.pressed.CONTROL) + { + // SongLoad.getSong()[curSection].sectionNotes.push([noteStrum, (noteData + 4) % 8, noteSus, noteAlt]); + } + + trace(noteStrum); + trace(curSection); + + updateGrid(); + updateNoteUI(); + + autosaveSong(); + } + + function getStrumTime(yPos:Float):Float + { + return FlxMath.remapToRange(yPos, gridBG.y, gridBG.y + gridBG.height, 0, 16 * Conductor.stepCrochet); + } + + function getYfromStrum(strumTime:Float):Float + { + return FlxMath.remapToRange(strumTime, 0, 16 * Conductor.stepCrochet, gridBG.y, gridBG.y + gridBG.height); + } + + /* + function calculateSectionLengths(?sec:SwagSection):Int + { + var daLength:Int = 0; + + for (i in SongLoad.getSong()) + { + var swagLength = i.lengthInSteps; + + if (i.typeOfSection == Section.COPYCAT) + swagLength * 2; + + daLength += swagLength; + + if (sec != null && sec == i) + { + trace('swag loop??'); + break; + } + } + + return daLength; + }*/ + var daSpacing:Float = 0.3; + + function loadLevel():Void + { + trace(SongLoad.getSong()); + } + + function getNotes():Array + { + var noteData:Array = []; + + for (i in SongLoad.getSong()) + { + noteData.push(i.sectionNotes); + } + + return noteData; + } + + function loadJson(song:String):Void + { + PlayState.currentSong = SongLoad.loadFromJson(song.toLowerCase(), song.toLowerCase()); + LoadingState.loadAndSwitchState(new ChartingState()); + } + + function loadAutosave():Void + { + PlayState.currentSong = FlxG.save.data.autosave; + FlxG.resetState(); + } + + function autosaveSong():Void + { + FlxG.save.data.autosave = _song; + // trace(FlxG.save.data.autosave); + FlxG.save.flush(); + } + + function saveLevel(?debugSavepath:Bool = false) + { + // Right now the note data is saved as a Note.NoteData typedef / object or whatev + // we want to format it to an ARRAY. We turn it back into the typedef / object at the end of this function hehe + + for (key in _song.noteMap.keys()) + SongLoad.castNoteDataToArray(_song.noteMap[key]); + + // SongLoad.castNoteDataToArray(_song.notes.easy); + // SongLoad.castNoteDataToArray(_song.notes.normal); + // SongLoad.castNoteDataToArray(_song.notes.hard); + + var json = {"song": _song}; + var data:String = Json.stringify(json, null, "\t"); + + #if sys + // quick workaround, since it easier to load into hashlink, thus quicker/nicer to test? + // should get this auto-saved into a file or somethin + var filename = _song.song.toLowerCase(); + + if (debugSavepath) + { + // file path to assumingly your assets folder in your SOURCE CODE assets folder!!! + // update this later so the save button ONLY appears when you compile in debug mode! + sys.io.File.saveContent('../../../../assets/preload/data/$filename/$filename.json', data); + } + else + sys.io.File.saveContent('./$filename.json', data); + #else + if ((data != null) && (data.length > 0)) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file.save(data.trim(), _song.song.toLowerCase() + ".json"); + } + #end + + for (key in _song.noteMap.keys()) + SongLoad.castArrayToNoteData(_song.noteMap[key]); + + // turn the array data back to Note.NoteData typedef + // SongLoad.castArrayToNoteData(_song.notes.easy); + // SongLoad.castArrayToNoteData(_song.notes.normal); + // SongLoad.castArrayToNoteData(_song.notes.hard); + } + + function onSaveComplete(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.notice("Successfully saved LEVEL DATA."); + } + + /** + * Called when the save file dialog is cancelled. + */ + function onSaveCancel(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + } + + /** + * Called if there is an error while saving the gameplay recording. + */ + function onSaveError(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.error("Problem saving Level data"); + } } enum SongResetType { - BEGINNING; - MEASURE; // not sure if measure is 1/4 of a "SECTION" which is definitely a... bar.. right? its nerd shit whatever - SECTION; + BEGINNING; + MEASURE; // not sure if measure is 1/4 of a "SECTION" which is definitely a... bar.. right? its nerd shit whatever + SECTION; } diff --git a/source/funkin/freeplayStuff/BGScrollingText.hx b/source/funkin/freeplayStuff/BGScrollingText.hx index dcdd206bc..1091afbe9 100644 --- a/source/funkin/freeplayStuff/BGScrollingText.hx +++ b/source/funkin/freeplayStuff/BGScrollingText.hx @@ -11,83 +11,83 @@ import flixel.util.FlxSort; // its kinda like marqeee html lol! class BGScrollingText extends FlxSpriteGroup { - var grpTexts:FlxTypedSpriteGroup; + var grpTexts:FlxTypedSpriteGroup; - public var widthShit:Float = FlxG.width; - public var placementOffset:Float = 20; - public var speed:Float = 1; + public var widthShit:Float = FlxG.width; + public var placementOffset:Float = 20; + public var speed:Float = 1; - public var funnyColor(default, set):Int = 0xFFFFFFFF; + public var funnyColor(default, set):Int = 0xFFFFFFFF; - public function new(x:Float, y:Float, text:String, widthShit:Float = 100) - { - super(x, y); + public function new(x:Float, y:Float, text:String, widthShit:Float = 100) + { + super(x, y); - this.widthShit = widthShit; + this.widthShit = widthShit; - grpTexts = new FlxTypedSpriteGroup(); - add(grpTexts); + grpTexts = new FlxTypedSpriteGroup(); + add(grpTexts); - var testText:FlxText = new FlxText(0, 0, 0, text, 48); - testText.font = "5by7"; - testText.updateHitbox(); - grpTexts.add(testText); + var testText:FlxText = new FlxText(0, 0, 0, text, 48); + testText.font = "5by7"; + testText.updateHitbox(); + grpTexts.add(testText); - var needed:Int = Math.ceil(widthShit / testText.frameWidth); + var needed:Int = Math.ceil(widthShit / testText.frameWidth); - for (i in 0...needed) - { - var lmfao:Int = i + 1; + for (i in 0...needed) + { + var lmfao:Int = i + 1; - var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, 48); - coolText.font = "5by7"; - coolText.updateHitbox(); - grpTexts.add(coolText); - } - } + var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, 48); + coolText.font = "5by7"; + coolText.updateHitbox(); + grpTexts.add(coolText); + } + } - function set_funnyColor(col:Int):Int - { - grpTexts.forEach(function(txt) - { - txt.color = col; - }); + function set_funnyColor(col:Int):Int + { + grpTexts.forEach(function(txt) + { + txt.color = col; + }); - return col; - } + return col; + } - override function update(elapsed:Float) - { - for (txt in grpTexts.group) - { - txt.x -= 1 * (speed * (elapsed / (1 / 60))); + override function update(elapsed:Float) + { + for (txt in grpTexts.group) + { + txt.x -= 1 * (speed * (elapsed / (1 / 60))); - if (speed > 0) - { - if (txt.x < -txt.frameWidth) - { - txt.x = grpTexts.group.members[grpTexts.length - 1].x + grpTexts.group.members[grpTexts.length - 1].frameWidth + placementOffset; - sortTextShit(); - } - } - else - { - if (txt.x > widthShit) - { - txt.x = grpTexts.group.members[0].x - grpTexts.group.members[0].frameWidth - placementOffset; - sortTextShit(); - } - } - } + if (speed > 0) + { + if (txt.x < -txt.frameWidth) + { + txt.x = grpTexts.group.members[grpTexts.length - 1].x + grpTexts.group.members[grpTexts.length - 1].frameWidth + placementOffset; + sortTextShit(); + } + } + else + { + if (txt.x > widthShit) + { + txt.x = grpTexts.group.members[0].x - grpTexts.group.members[0].frameWidth - placementOffset; + sortTextShit(); + } + } + } - super.update(elapsed); - } + super.update(elapsed); + } - function sortTextShit():Void - { - grpTexts.sort(function(Order:Int, Obj1:FlxObject, Obj2:FlxObject) - { - return FlxSort.byValues(Order, Obj1.x, Obj2.x); - }); - } + function sortTextShit():Void + { + grpTexts.sort(function(Order:Int, Obj1:FlxObject, Obj2:FlxObject) + { + return FlxSort.byValues(Order, Obj1.x, Obj2.x); + }); + } } diff --git a/source/funkin/freeplayStuff/DJBoyfriend.hx b/source/funkin/freeplayStuff/DJBoyfriend.hx index a4afb9753..b109fb03f 100644 --- a/source/funkin/freeplayStuff/DJBoyfriend.hx +++ b/source/funkin/freeplayStuff/DJBoyfriend.hx @@ -65,8 +65,7 @@ class DJBoyfriend extends FlxSprite { case Intro: // Play the intro animation then leave this state immediately. - if (getCurrentAnimation() != 'intro') - playAnimation('intro', true); + if (getCurrentAnimation() != 'intro') playAnimation('intro', true); timeSinceSpook = 0; case Idle: // We are in this state the majority of the time. @@ -83,8 +82,7 @@ class DJBoyfriend extends FlxSprite } timeSinceSpook += elapsed; case Confirm: - if (getCurrentAnimation() != 'confirm') - playAnimation('confirm', false); + if (getCurrentAnimation() != 'confirm') playAnimation('confirm', false); timeSinceSpook = 0; case Spook: if (getCurrentAnimation() != 'spook') @@ -150,8 +148,7 @@ class DJBoyfriend extends FlxSprite public function getCurrentAnimation():String { - if (this.animation == null || this.animation.curAnim == null) - return ""; + if (this.animation == null || this.animation.curAnim == null) return ""; return this.animation.curAnim.name; } diff --git a/source/funkin/freeplayStuff/FreeplayScore.hx b/source/funkin/freeplayStuff/FreeplayScore.hx index 0a2d475ee..d22dd2276 100644 --- a/source/funkin/freeplayStuff/FreeplayScore.hx +++ b/source/funkin/freeplayStuff/FreeplayScore.hx @@ -5,122 +5,121 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; class FreeplayScore extends FlxTypedSpriteGroup { - public var scoreShit(default, set):Int = 0; + public var scoreShit(default, set):Int = 0; - function set_scoreShit(val):Int - { - if (group == null || group.members == null) - return val; - var loopNum:Int = group.members.length - 1; - var dumbNumb = Std.parseInt(Std.string(val)); - var prevNum:ScoreNum; + function set_scoreShit(val):Int + { + if (group == null || group.members == null) return val; + var loopNum:Int = group.members.length - 1; + var dumbNumb = Std.parseInt(Std.string(val)); + var prevNum:ScoreNum; - while (dumbNumb > 0) - { - group.members[loopNum].digit = dumbNumb % 10; + while (dumbNumb > 0) + { + group.members[loopNum].digit = dumbNumb % 10; - // var funnyNum = group.members[loopNum]; - // prevNum = group.members[loopNum + 1]; + // var funnyNum = group.members[loopNum]; + // prevNum = group.members[loopNum + 1]; - // if (prevNum != null) - // { - // funnyNum.x = prevNum.x - (funnyNum.width * 0.7); - // } + // if (prevNum != null) + // { + // funnyNum.x = prevNum.x - (funnyNum.width * 0.7); + // } - // funnyNum.y = (funnyNum.baseY - (funnyNum.height / 2)) + 73; - // funnyNum.x = (funnyNum.baseX - (funnyNum.width / 2)) + 450; // this plus value is hand picked lol! + // funnyNum.y = (funnyNum.baseY - (funnyNum.height / 2)) + 73; + // funnyNum.x = (funnyNum.baseX - (funnyNum.width / 2)) + 450; // this plus value is hand picked lol! - dumbNumb = Math.floor(dumbNumb / 10); - loopNum--; - } + dumbNumb = Math.floor(dumbNumb / 10); + loopNum--; + } - while (loopNum > 0) - { - group.members[loopNum].digit = 0; - loopNum--; - } + while (loopNum > 0) + { + group.members[loopNum].digit = 0; + loopNum--; + } - return val; - } + return val; + } - public function new(x:Float, y:Float, scoreShit:Int = 100) - { - super(x, y); + public function new(x:Float, y:Float, scoreShit:Int = 100) + { + super(x, y); - for (i in 0...7) - { - add(new ScoreNum(x + (45 * i), y, 0)); - } + for (i in 0...7) + { + add(new ScoreNum(x + (45 * i), y, 0)); + } - this.scoreShit = scoreShit; - } + this.scoreShit = scoreShit; + } - public function updateScore(scoreNew:Int) - { - scoreShit = scoreNew; - } + public function updateScore(scoreNew:Int) + { + scoreShit = scoreNew; + } } class ScoreNum extends FlxSprite { - public var digit(default, set):Int = 0; + public var digit(default, set):Int = 0; - function set_digit(val):Int - { - if (animation.curAnim != null && animation.curAnim.name != numToString[val]) - { - animation.play(numToString[val], true, false, 0); - updateHitbox(); + function set_digit(val):Int + { + if (animation.curAnim != null && animation.curAnim.name != numToString[val]) + { + animation.play(numToString[val], true, false, 0); + updateHitbox(); - switch (val) - { - case 1: - offset.x -= 15; - case 5: - // set offsets - // offset.x += 0; - // offset.y += 10; + switch (val) + { + case 1: + offset.x -= 15; + case 5: + // set offsets + // offset.x += 0; + // offset.y += 10; - case 7: - // offset.y += 6; - case 4: - // offset.y += 5; - case 9: - // offset.y += 5; - default: - centerOffsets(false); - } - } + case 7: + // offset.y += 6; + case 4: + // offset.y += 5; + case 9: + // offset.y += 5; + default: + centerOffsets(false); + } + } - return val; - } + return val; + } - public var baseY:Float = 0; - public var baseX:Float = 0; + public var baseY:Float = 0; + public var baseX:Float = 0; - var numToString:Array = ["ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]; + var numToString:Array = ["ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]; - public function new(x:Float, y:Float, ?initDigit:Int = 0) - { - super(x, y); + public function new(x:Float, y:Float, ?initDigit:Int = 0) + { + super(x, y); - baseY = y; - baseX = x; + baseY = y; + baseX = x; - frames = Paths.getSparrowAtlas('digital_numbers'); + frames = Paths.getSparrowAtlas('digital_numbers'); - for (i in 0...10) - { - var stringNum:String = numToString[i]; - animation.addByPrefix(stringNum, stringNum, 24, false); - } + for (i in 0...10) + { + var stringNum:String = numToString[i]; + animation.addByPrefix(stringNum, stringNum, 24, false); + } - this.digit = initDigit; + this.digit = initDigit; - animation.play(numToString[digit], true); - antialiasing = true; + animation.play(numToString[digit], true); + antialiasing = true; - setGraphicSize(Std.int(width * 0.4)); - updateHitbox(); - } + setGraphicSize(Std.int(width * 0.4)); + updateHitbox(); + } } diff --git a/source/funkin/freeplayStuff/LetterSort.hx b/source/funkin/freeplayStuff/LetterSort.hx index b263bc357..c3b22f973 100644 --- a/source/funkin/freeplayStuff/LetterSort.hx +++ b/source/funkin/freeplayStuff/LetterSort.hx @@ -7,100 +7,94 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; class LetterSort extends FlxTypedSpriteGroup { - public var letters:Array = []; + public var letters:Array = []; - var curSelection:Int = 0; + var curSelection:Int = 0; - public var changeSelectionCallback:String->Void; + public var changeSelectionCallback:String->Void; - public function new(x, y) - { - super(x, y); + public function new(x, y) + { + super(x, y); - var leftArrow:FreeplayLetter = new FreeplayLetter(-20, 0); - leftArrow.animation.play("arrow"); - add(leftArrow); + var leftArrow:FreeplayLetter = new FreeplayLetter(-20, 0); + leftArrow.animation.play("arrow"); + add(leftArrow); - for (i in 0...6) - { - var letter:FreeplayLetter = new FreeplayLetter(i * 80, 0, i); - add(letter); + for (i in 0...6) + { + var letter:FreeplayLetter = new FreeplayLetter(i * 80, 0, i); + add(letter); - letters.push(letter); + letters.push(letter); - if (i == 3) - letter.alpha = 0.6; + if (i == 3) letter.alpha = 0.6; - var sep:FreeplayLetter = new FreeplayLetter((i * 80) + 50, 0); - sep.animation.play("seperator"); - add(sep); - } + var sep:FreeplayLetter = new FreeplayLetter((i * 80) + 50, 0); + sep.animation.play("seperator"); + add(sep); + } - // changeSelection(-3); - } + // changeSelection(-3); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (FlxG.keys.justPressed.E) - changeSelection(1); - if (FlxG.keys.justPressed.Q) - changeSelection(-1); - } + if (FlxG.keys.justPressed.E) changeSelection(1); + if (FlxG.keys.justPressed.Q) changeSelection(-1); + } - public function changeSelection(diff:Int = 0) - { - for (letter in letters) - letter.changeLetter(diff); + public function changeSelection(diff:Int = 0) + { + for (letter in letters) + letter.changeLetter(diff); - if (changeSelectionCallback != null) - changeSelectionCallback(letters[3].arr[letters[3].curLetter]); // bullshit and long lol! - } + if (changeSelectionCallback != null) changeSelectionCallback(letters[3].arr[letters[3].curLetter]); // bullshit and long lol! + } } class FreeplayLetter extends FlxSprite { - public var arr:Array = []; + public var arr:Array = []; - public var curLetter:Int = 0; + public var curLetter:Int = 0; - public function new(x:Float, y:Float, ?letterInd:Int) - { - super(x, y); + public function new(x:Float, y:Float, ?letterInd:Int) + { + super(x, y); - frames = Paths.getSparrowAtlas("freeplay/letterStuff"); + frames = Paths.getSparrowAtlas("freeplay/letterStuff"); - var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; - arr = alphabet.split(""); - arr.insert(0, "#"); - arr.insert(0, "ALL"); - arr.insert(0, "fav"); + var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; + arr = alphabet.split(""); + arr.insert(0, "#"); + arr.insert(0, "ALL"); + arr.insert(0, "fav"); - for (str in arr) - { - animation.addByPrefix(str, str + " "); // string followed by a space! intentional! - } + for (str in arr) + { + animation.addByPrefix(str, str + " "); // string followed by a space! intentional! + } - animation.addByPrefix("arrow", "mini arrow"); - animation.addByPrefix("seperator", "seperator"); + animation.addByPrefix("arrow", "mini arrow"); + animation.addByPrefix("seperator", "seperator"); - if (letterInd != null) - { - animation.play(arr[letterInd]); - curLetter = letterInd; - } - } + if (letterInd != null) + { + animation.play(arr[letterInd]); + curLetter = letterInd; + } + } - public function changeLetter(diff:Int = 0) - { - curLetter += diff; + public function changeLetter(diff:Int = 0) + { + curLetter += diff; - if (curLetter < 0) - curLetter = arr.length - 1; - if (curLetter >= arr.length) - curLetter = 0; + if (curLetter < 0) curLetter = arr.length - 1; + if (curLetter >= arr.length) curLetter = 0; - animation.play(arr[curLetter]); - } + animation.play(arr[curLetter]); + } } diff --git a/source/funkin/freeplayStuff/SongMenuItem.hx b/source/funkin/freeplayStuff/SongMenuItem.hx index d98668937..6ed3ae57d 100644 --- a/source/funkin/freeplayStuff/SongMenuItem.hx +++ b/source/funkin/freeplayStuff/SongMenuItem.hx @@ -10,94 +10,92 @@ import flixel.text.FlxText; class SongMenuItem extends FlxSpriteGroup { - var capsule:FlxSprite; + var capsule:FlxSprite; - public var selected(default, set):Bool = false; + public var selected(default, set):Bool = false; - public var songTitle:String = "Test"; + public var songTitle:String = "Test"; - public var songText:FlxText; - public var favIcon:FlxSprite; + public var songText:FlxText; + public var favIcon:FlxSprite; - public var targetPos:FlxPoint = new FlxPoint(); - public var doLerp:Bool = false; - public var doJumpIn:Bool = false; + public var targetPos:FlxPoint = new FlxPoint(); + public var doLerp:Bool = false; + public var doJumpIn:Bool = false; - public function new(x:Float, y:Float, song:String) - { - super(x, y); + public function new(x:Float, y:Float, song:String) + { + super(x, y); - this.songTitle = song; + this.songTitle = song; - capsule = new FlxSprite(); - capsule.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule'); - capsule.animation.addByPrefix('selected', 'mp3 capsule w backing0', 24); - capsule.animation.addByPrefix('unselected', 'mp3 capsule w backing NOT SELECTED', 24); - // capsule.animation - add(capsule); + capsule = new FlxSprite(); + capsule.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule'); + capsule.animation.addByPrefix('selected', 'mp3 capsule w backing0', 24); + capsule.animation.addByPrefix('unselected', 'mp3 capsule w backing NOT SELECTED', 24); + // capsule.animation + add(capsule); - songText = new FlxText(120, 40, 0, songTitle, 40); - songText.font = "5by7"; - songText.color = 0xFF43C1EA; - add(songText); + songText = new FlxText(120, 40, 0, songTitle, 40); + songText.font = "5by7"; + songText.color = 0xFF43C1EA; + add(songText); - favIcon = new FlxSprite(440, 40); - favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart'); - favIcon.animation.addByPrefix('fav', "favorite heart", 24, false); - favIcon.animation.play('fav'); - favIcon.antialiasing = true; - favIcon.setGraphicSize(60, 60); - add(favIcon); + favIcon = new FlxSprite(440, 40); + favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart'); + favIcon.animation.addByPrefix('fav', "favorite heart", 24, false); + favIcon.animation.play('fav'); + favIcon.antialiasing = true; + favIcon.setGraphicSize(60, 60); + add(favIcon); - selected = selected; // just to kickstart the set_selected - } + selected = selected; // just to kickstart the set_selected + } - var frameTicker:Float = 0; - var frameTypeBeat:Int = 0; + var frameTicker:Float = 0; + var frameTypeBeat:Int = 0; - var xFrames:Array = [1.7, 1.8, 0.85, 0.85, 0.97, 0.97, 1]; - var xPosLerpLol:Array = [0.9, 0.4, 0.16, 0.16, 0.22, 0.22, 0.245]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER + var xFrames:Array = [1.7, 1.8, 0.85, 0.85, 0.97, 0.97, 1]; + var xPosLerpLol:Array = [0.9, 0.4, 0.16, 0.16, 0.22, 0.22, 0.245]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER - override function update(elapsed:Float) - { - if (doJumpIn) - { - frameTicker += elapsed; + override function update(elapsed:Float) + { + if (doJumpIn) + { + frameTicker += elapsed; - if (frameTicker >= 1 / 24 && frameTypeBeat < xFrames.length) - { - frameTicker = 0; + if (frameTicker >= 1 / 24 && frameTypeBeat < xFrames.length) + { + frameTicker = 0; - scale.x = xFrames[frameTypeBeat]; - scale.y = 1 / xFrames[frameTypeBeat]; - x = FlxG.width * xPosLerpLol[Std.int(Math.min(frameTypeBeat, xPosLerpLol.length - 1))]; + scale.x = xFrames[frameTypeBeat]; + scale.y = 1 / xFrames[frameTypeBeat]; + x = FlxG.width * xPosLerpLol[Std.int(Math.min(frameTypeBeat, xPosLerpLol.length - 1))]; - frameTypeBeat += 1; - } - } + frameTypeBeat += 1; + } + } - if (doLerp) - { - x = CoolUtil.coolLerp(x, targetPos.x, 0.3); - y = CoolUtil.coolLerp(y, targetPos.y, 0.4); - } + if (doLerp) + { + x = CoolUtil.coolLerp(x, targetPos.x, 0.3); + y = CoolUtil.coolLerp(y, targetPos.y, 0.4); + } - if (FlxG.keys.justPressed.ALT) - selected = false; - if (FlxG.keys.justPressed.CONTROL) - selected = true; + if (FlxG.keys.justPressed.ALT) selected = false; + if (FlxG.keys.justPressed.CONTROL) selected = true; - super.update(elapsed); - } + super.update(elapsed); + } - function set_selected(value:Bool):Bool - { - // trace(value); + function set_selected(value:Bool):Bool + { + // trace(value); - // cute one liners, lol! - songText.alpha = value ? 1 : 0.6; - capsule.offset.x = value ? 0 : -5; - capsule.animation.play(value ? "selected" : "unselected"); - return value; - } + // cute one liners, lol! + songText.alpha = value ? 1 : 0.6; + capsule.offset.x = value ? 0 : -5; + capsule.animation.play(value ? "selected" : "unselected"); + return value; + } } diff --git a/source/funkin/graphics/rendering/MeshRender.hx b/source/funkin/graphics/rendering/MeshRender.hx index 1f88c1868..39402808a 100644 --- a/source/funkin/graphics/rendering/MeshRender.hx +++ b/source/funkin/graphics/rendering/MeshRender.hx @@ -9,76 +9,76 @@ import flixel.util.FlxColor; */ class MeshRender extends FlxStrip { - public var vertex_count(default, null):Int = 0; - public var index_count(default, null):Int = 0; + public var vertex_count(default, null):Int = 0; + public var index_count(default, null):Int = 0; - var tri_offset:Int = 0; + var tri_offset:Int = 0; - public function new(x, y, ?col:FlxColor = FlxColor.WHITE) - { - super(x, y); - makeGraphic(1, 1, col); - } + public function new(x, y, ?col:FlxColor = FlxColor.WHITE) + { + super(x, y); + makeGraphic(1, 1, col); + } - public inline function start() - { - tri_offset = vertex_count; - } + public inline function start() + { + tri_offset = vertex_count; + } - public inline function add_vertex(x:Float, y:Float, u:Float = 0, v:Float = 0) - { - final pos = vertex_count << 1; + public inline function add_vertex(x:Float, y:Float, u:Float = 0, v:Float = 0) + { + final pos = vertex_count << 1; - vertices[pos] = x; - vertices[pos + 1] = y; + vertices[pos] = x; + vertices[pos + 1] = y; - uvtData[pos] = u; - uvtData[pos + 1] = v; + uvtData[pos] = u; + uvtData[pos + 1] = v; - vertex_count++; - } + vertex_count++; + } - public function add_tri(a:Int, b:Int, c:Int) - { - indices[index_count] = a + tri_offset; - indices[index_count + 1] = b + tri_offset; - indices[index_count + 2] = c + tri_offset; + public function add_tri(a:Int, b:Int, c:Int) + { + indices[index_count] = a + tri_offset; + indices[index_count + 1] = b + tri_offset; + indices[index_count + 2] = c + tri_offset; - index_count += 3; - } + index_count += 3; + } - /** - * - * top left - a - * - * top right - b - * - * bottom left - c - * - * bottom right - d - */ - public function add_quad(ax:Float, ay:Float, bx:Float, by:Float, cx:Float, cy:Float, dx:Float, dy:Float, au:Float = 0, av:Float = 0, bu:Float = 0, - bv:Float = 0, cu:Float = 0, cv:Float = 0, du:Float = 0, dv:Float = 0) - { - start(); - // top left - add_vertex(bx, by, bu, bv); - // top right - add_vertex(ax, ay, au, av); - // bottom left - add_vertex(cx, cy, cu, cv); - // bottom right - add_vertex(dx, dy, du, dv); + /** + * + * top left - a + * + * top right - b + * + * bottom left - c + * + * bottom right - d + */ + public function add_quad(ax:Float, ay:Float, bx:Float, by:Float, cx:Float, cy:Float, dx:Float, dy:Float, au:Float = 0, av:Float = 0, bu:Float = 0, + bv:Float = 0, cu:Float = 0, cv:Float = 0, du:Float = 0, dv:Float = 0) + { + start(); + // top left + add_vertex(bx, by, bu, bv); + // top right + add_vertex(ax, ay, au, av); + // bottom left + add_vertex(cx, cy, cu, cv); + // bottom right + add_vertex(dx, dy, du, dv); - add_tri(0, 1, 2); - add_tri(0, 2, 3); - } + add_tri(0, 1, 2); + add_tri(0, 2, 3); + } - public function clear() - { - vertices.length = 0; - indices.length = 0; - vertex_count = 0; - index_count = 0; - } + public function clear() + { + vertices.length = 0; + indices.length = 0; + vertex_count = 0; + index_count = 0; + } } diff --git a/source/funkin/graphics/rendering/SustainTrail.hx b/source/funkin/graphics/rendering/SustainTrail.hx index 0eeffccf7..80625b419 100644 --- a/source/funkin/graphics/rendering/SustainTrail.hx +++ b/source/funkin/graphics/rendering/SustainTrail.hx @@ -15,224 +15,219 @@ import flixel.math.FlxMath; */ class SustainTrail extends FlxSprite { - /** - * Used to determine which note color/direction to draw for the sustain. - */ - public var noteData:Int = 0; + /** + * Used to determine which note color/direction to draw for the sustain. + */ + public var noteData:Int = 0; - /** - * The zoom level to render the sustain at. - * Defaults to 1.0, increased to 6.0 for pixel notes. - */ - public var zoom(default, set):Float = 1; + /** + * The zoom level to render the sustain at. + * Defaults to 1.0, increased to 6.0 for pixel notes. + */ + public var zoom(default, set):Float = 1; - /** - * The strumtime of the note, in milliseconds. - */ - public var strumTime:Float = 0; // millis + /** + * The strumtime of the note, in milliseconds. + */ + public var strumTime:Float = 0; // millis - /** - * The sustain length of the note, in milliseconds. - */ - public var sustainLength(default, set):Float = 0; // millis + /** + * The sustain length of the note, in milliseconds. + */ + public var sustainLength(default, set):Float = 0; // millis - /** - * The scroll speed of the note, as a multiplier. - */ - public var scrollSpeed(default, set):Float = 1.0; // stand-in for PlayState scroll speed + /** + * The scroll speed of the note, as a multiplier. + */ + public var scrollSpeed(default, set):Float = 1.0; // stand-in for PlayState scroll speed - /** - * Whether the note was missed. - */ - public var missed:Bool = false; // maybe BlendMode.MULTIPLY if missed somehow, drawTriangles does not support! + /** + * Whether the note was missed. + */ + public var missed:Bool = false; // maybe BlendMode.MULTIPLY if missed somehow, drawTriangles does not support! - /** - * A `Vector` of floats where each pair of numbers is treated as a coordinate location (an x, y pair). - */ - private var vertices:DrawData = new DrawData(); + /** + * A `Vector` of floats where each pair of numbers is treated as a coordinate location (an x, y pair). + */ + var vertices:DrawData = new DrawData(); - /** - * A `Vector` of integers or indexes, where every three indexes define a triangle. - */ - private var indices:DrawData = new DrawData(); + /** + * A `Vector` of integers or indexes, where every three indexes define a triangle. + */ + var indices:DrawData = new DrawData(); - /** - * A `Vector` of normalized coordinates used to apply texture mapping. - */ - private var uvtData:DrawData = new DrawData(); + /** + * A `Vector` of normalized coordinates used to apply texture mapping. + */ + var uvtData:DrawData = new DrawData(); - private var processedGraphic:FlxGraphic; + var processedGraphic:FlxGraphic; - /** - * What part of the trail's end actually represents the end of the note. - * This can be used to have a little bit sticking out. - */ - public var endOffset:Float = 0.5; // 0.73 is roughly the bottom of the sprite in the normal graphic! + /** + * What part of the trail's end actually represents the end of the note. + * This can be used to have a little bit sticking out. + */ + public var endOffset:Float = 0.5; // 0.73 is roughly the bottom of the sprite in the normal graphic! - /** - * At what point the bottom for the trail's end should be clipped off. - * Used in cases where there's an extra bit of the graphic on the bottom to avoid antialiasing issues with overflow. - */ - public var bottomClip:Float = 0.9; + /** + * At what point the bottom for the trail's end should be clipped off. + * Used in cases where there's an extra bit of the graphic on the bottom to avoid antialiasing issues with overflow. + */ + public var bottomClip:Float = 0.9; - /** - * Normally you would take strumTime:Float, noteData:Int, sustainLength:Float, parentNote:Note (?) - * @param NoteData - * @param SustainLength - * @param FileName - */ - public function new(NoteData:Int, SustainLength:Float, Path:String, ?Alpha:Float = 0.6, ?Pixel:Bool = false) - { - super(0, 0, Path); + /** + * Normally you would take strumTime:Float, noteData:Int, sustainLength:Float, parentNote:Note (?) + * @param NoteData + * @param SustainLength + * @param FileName + */ + public function new(NoteData:Int, SustainLength:Float, Path:String, ?Alpha:Float = 0.6, ?Pixel:Bool = false) + { + super(0, 0, Path); - // BASIC SETUP - this.sustainLength = SustainLength; - this.noteData = NoteData; + // BASIC SETUP + this.sustainLength = SustainLength; + this.noteData = NoteData; - // CALCULATE SIZE - if (Pixel) - { - this.endOffset = bottomClip = 1; - this.antialiasing = false; - this.zoom = 6.0; - } - else - { - this.antialiasing = true; - this.zoom = 1.0; - } - // width = graphic.width / 8 * zoom; // amount of notes * 2 - height = sustainHeight(sustainLength, scrollSpeed); - // instead of scrollSpeed, PlayState.SONG.speed + // CALCULATE SIZE + if (Pixel) + { + this.endOffset = bottomClip = 1; + this.antialiasing = false; + this.zoom = 6.0; + } + else + { + this.antialiasing = true; + this.zoom = 1.0; + } + // width = graphic.width / 8 * zoom; // amount of notes * 2 + height = sustainHeight(sustainLength, scrollSpeed); + // instead of scrollSpeed, PlayState.SONG.speed - alpha = Alpha; // setting alpha calls updateColorTransform(), which initializes processedGraphic! + alpha = Alpha; // setting alpha calls updateColorTransform(), which initializes processedGraphic! - updateClipping(); - indices = new DrawData(12, true, [0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4]); - } + updateClipping(); + indices = new DrawData(12, true, [0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4]); + } - /** - * Calculates height of a sustain note for a given length (milliseconds) and scroll speed. - * @param susLength The length of the sustain note in milliseconds. - * @param scroll The current scroll speed. - */ - public static inline function sustainHeight(susLength:Float, scroll:Float) - { - return (susLength * 0.45 * scroll); - } + /** + * Calculates height of a sustain note for a given length (milliseconds) and scroll speed. + * @param susLength The length of the sustain note in milliseconds. + * @param scroll The current scroll speed. + */ + public static inline function sustainHeight(susLength:Float, scroll:Float) + { + return (susLength * 0.45 * scroll); + } - function set_zoom(z:Float) - { - this.zoom = z; - width = graphic.width / 8 * z; - updateClipping(); - return this.zoom; - } + function set_zoom(z:Float) + { + this.zoom = z; + width = graphic.width / 8 * z; + updateClipping(); + return this.zoom; + } - function set_sustainLength(s:Float) - { - height = sustainHeight(s, scrollSpeed); - return sustainLength = s; - } + function set_sustainLength(s:Float) + { + height = sustainHeight(s, scrollSpeed); + return sustainLength = s; + } - function set_scrollSpeed(s:Float) - { - height = sustainHeight(sustainLength, s); - return scrollSpeed = s; - } + function set_scrollSpeed(s:Float) + { + height = sustainHeight(sustainLength, s); + return scrollSpeed = s; + } - /** - * Sets up new vertex and UV data to clip the trail. - * If flipY is true, top and bottom bounds swap places. - * @param songTime The time to clip the note at, in milliseconds. - */ - public function updateClipping(songTime:Float = 0):Void - { - var clipHeight:Float = FlxMath.bound(sustainHeight(sustainLength - (songTime - strumTime), scrollSpeed), 0, height); - if (clipHeight == 0) - { - visible = false; - return; - } - else - visible = true; - var bottomHeight:Float = graphic.height * zoom * endOffset; - var partHeight:Float = clipHeight - bottomHeight; - // == HOLD == // - // left bound - vertices[6] = vertices[0] = 0.0; - // top bound - vertices[3] = vertices[1] = flipY ? clipHeight : height - clipHeight; - // right bound - vertices[4] = vertices[2] = width; - // bottom bound (also top bound for hold ends) - if (partHeight > 0) - vertices[7] = vertices[5] = flipY ? 0.0 + bottomHeight : vertices[1] + partHeight; - else - vertices[7] = vertices[5] = vertices[1]; + /** + * Sets up new vertex and UV data to clip the trail. + * If flipY is true, top and bottom bounds swap places. + * @param songTime The time to clip the note at, in milliseconds. + */ + public function updateClipping(songTime:Float = 0):Void + { + var clipHeight:Float = FlxMath.bound(sustainHeight(sustainLength - (songTime - strumTime), scrollSpeed), 0, height); + if (clipHeight == 0) + { + visible = false; + return; + } + else + visible = true; + var bottomHeight:Float = graphic.height * zoom * endOffset; + var partHeight:Float = clipHeight - bottomHeight; + // == HOLD == // + // left bound + vertices[6] = vertices[0] = 0.0; + // top bound + vertices[3] = vertices[1] = flipY ? clipHeight : height - clipHeight; + // right bound + vertices[4] = vertices[2] = width; + // bottom bound (also top bound for hold ends) + if (partHeight > 0) vertices[7] = vertices[5] = flipY ? 0.0 + bottomHeight : vertices[1] + partHeight; + else + vertices[7] = vertices[5] = vertices[1]; - // same shit with da bounds, just in relation to the texture - uvtData[6] = uvtData[0] = 1 / 4 * (noteData % 4); - // height overflows past image bounds so wraps around, looping the texture - // flipY bounds are not swapped for UV data, so the graphic is actually flipped - // top bound - uvtData[3] = uvtData[1] = (-partHeight) / graphic.height / zoom; - uvtData[4] = uvtData[2] = uvtData[0] + 1 / 8; // 1 - // bottom bound - uvtData[7] = uvtData[5] = 0.0; + // same shit with da bounds, just in relation to the texture + uvtData[6] = uvtData[0] = 1 / 4 * (noteData % 4); + // height overflows past image bounds so wraps around, looping the texture + // flipY bounds are not swapped for UV data, so the graphic is actually flipped + // top bound + uvtData[3] = uvtData[1] = (-partHeight) / graphic.height / zoom; + uvtData[4] = uvtData[2] = uvtData[0] + 1 / 8; // 1 + // bottom bound + uvtData[7] = uvtData[5] = 0.0; - // == HOLD ENDS == // - // left bound - vertices[14] = vertices[8] = vertices[0]; - // top bound - vertices[11] = vertices[9] = vertices[5]; - // right bound - vertices[12] = vertices[10] = vertices[2]; - // bottom bound, mind the bottomClip because it clips off bottom of graphic!! - vertices[15] = vertices[13] = flipY ? graphic.height * (-bottomClip + endOffset) : height + graphic.height * (bottomClip - endOffset); + // == HOLD ENDS == // + // left bound + vertices[14] = vertices[8] = vertices[0]; + // top bound + vertices[11] = vertices[9] = vertices[5]; + // right bound + vertices[12] = vertices[10] = vertices[2]; + // bottom bound, mind the bottomClip because it clips off bottom of graphic!! + vertices[15] = vertices[13] = flipY ? graphic.height * (-bottomClip + endOffset) : height + graphic.height * (bottomClip - endOffset); - uvtData[14] = uvtData[8] = uvtData[2]; - if (partHeight > 0) - uvtData[11] = uvtData[9] = 0.0; - else - uvtData[11] = uvtData[9] = (bottomHeight - clipHeight) / zoom / graphic.height; - uvtData[12] = uvtData[10] = uvtData[8] + 1 / 8; - // again, clips off bottom !! - uvtData[15] = uvtData[13] = bottomClip; - } + uvtData[14] = uvtData[8] = uvtData[2]; + if (partHeight > 0) uvtData[11] = uvtData[9] = 0.0; + else + uvtData[11] = uvtData[9] = (bottomHeight - clipHeight) / zoom / graphic.height; + uvtData[12] = uvtData[10] = uvtData[8] + 1 / 8; + // again, clips off bottom !! + uvtData[15] = uvtData[13] = bottomClip; + } - @:access(flixel.FlxCamera) - override public function draw():Void - { - if (alpha == 0 || graphic == null || vertices == null) - return; + @:access(flixel.FlxCamera) + override public function draw():Void + { + if (alpha == 0 || graphic == null || vertices == null) return; - for (camera in cameras) - { - if (!camera.visible || !camera.exists || !isOnScreen(camera)) - continue; + for (camera in cameras) + { + if (!camera.visible || !camera.exists || !isOnScreen(camera)) continue; - getScreenPosition(_point, camera).subtractPoint(offset); - camera.drawTriangles(processedGraphic, vertices, indices, uvtData, null, _point, blend, true, antialiasing); - } - } + getScreenPosition(_point, camera).subtractPoint(offset); + camera.drawTriangles(processedGraphic, vertices, indices, uvtData, null, _point, blend, true, antialiasing); + } + } - override public function destroy():Void - { - vertices = null; - indices = null; - uvtData = null; - processedGraphic.destroy(); + override public function destroy():Void + { + vertices = null; + indices = null; + uvtData = null; + processedGraphic.destroy(); - super.destroy(); - } + super.destroy(); + } - override function updateColorTransform():Void - { - super.updateColorTransform(); - if (processedGraphic != null) - processedGraphic.destroy(); - processedGraphic = FlxGraphic.fromGraphic(graphic, true); - processedGraphic.bitmap.colorTransform(processedGraphic.bitmap.rect, colorTransform); - } + override function updateColorTransform():Void + { + super.updateColorTransform(); + if (processedGraphic != null) processedGraphic.destroy(); + processedGraphic = FlxGraphic.fromGraphic(graphic, true); + processedGraphic.bitmap.colorTransform(processedGraphic.bitmap.rect, colorTransform); + } } diff --git a/source/funkin/import.hx b/source/funkin/import.hx index 56b6aa4d3..397758103 100644 --- a/source/funkin/import.hx +++ b/source/funkin/import.hx @@ -1,3 +1,5 @@ +package; + #if !macro // Only import these when we aren't in a macro. import funkin.Paths; diff --git a/source/funkin/input/Cursor.hx b/source/funkin/input/Cursor.hx index 50cdad079..e965165f3 100644 --- a/source/funkin/input/Cursor.hx +++ b/source/funkin/input/Cursor.hx @@ -6,268 +6,277 @@ import openfl.display.BitmapData; class Cursor { - public static var cursorMode(default, set):CursorMode; + public static var cursorMode(default, set):CursorMode; - static final CURSOR_DEFAULT_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-default.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorDefault:BitmapData = null; + static final CURSOR_DEFAULT_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-default.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorDefault:BitmapData = null; - static final CURSOR_CROSS_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-cross.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorCross:BitmapData = null; + static final CURSOR_CROSS_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-cross.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorCross:BitmapData = null; - static final CURSOR_ERASER_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-eraser.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorEraser:BitmapData = null; + static final CURSOR_ERASER_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-eraser.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorEraser:BitmapData = null; - static final CURSOR_GRABBING_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-grabbing.png", - scale: 1.0, - offsetX: 32, - offsetY: 0, - }; - static var assetCursorGrabbing:BitmapData = null; + static final CURSOR_GRABBING_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-grabbing.png", + scale: 1.0, + offsetX: 32, + offsetY: 0, + }; + static var assetCursorGrabbing:BitmapData = null; - static final CURSOR_HOURGLASS_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-hourglass.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorHourglass:BitmapData = null; + static final CURSOR_HOURGLASS_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-hourglass.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorHourglass:BitmapData = null; - static final CURSOR_POINTER_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-pointer.png", - scale: 1.0, - offsetX: 8, - offsetY: 0, - }; - static var assetCursorPointer:BitmapData = null; + static final CURSOR_POINTER_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-pointer.png", + scale: 1.0, + offsetX: 8, + offsetY: 0, + }; + static var assetCursorPointer:BitmapData = null; - static final CURSOR_TEXT_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-text.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorText:BitmapData = null; + static final CURSOR_TEXT_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-text.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorText:BitmapData = null; - static final CURSOR_ZOOM_IN_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-zoom-in.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorZoomIn:BitmapData = null; + static final CURSOR_ZOOM_IN_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-zoom-in.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorZoomIn:BitmapData = null; - static final CURSOR_ZOOM_OUT_PARAMS:CursorParams = { - graphic: "assets/images/cursor/cursor-zoom-out.png", - scale: 1.0, - offsetX: 0, - offsetY: 0, - }; - static var assetCursorZoomOut:BitmapData = null; + static final CURSOR_ZOOM_OUT_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-zoom-out.png", + scale: 1.0, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorZoomOut:BitmapData = null; - static function set_cursorMode(value:CursorMode):CursorMode - { - if (cursorMode != value) - { - cursorMode = value; - setCursorGraphic(cursorMode); - } - return cursorMode; - } + static function set_cursorMode(value:CursorMode):CursorMode + { + if (cursorMode != value) + { + cursorMode = value; + setCursorGraphic(cursorMode); + } + return cursorMode; + } - public static inline function show():Void - { - FlxG.mouse.visible = true; - } + public static inline function show():Void + { + FlxG.mouse.visible = true; + } - public static inline function hide():Void - { - FlxG.mouse.visible = false; - } + public static inline function hide():Void + { + FlxG.mouse.visible = false; + } - static function setCursorGraphic(?value:CursorMode = null):Void - { - if (value == null) - { - FlxG.mouse.unload(); - return; - } + static function setCursorGraphic(?value:CursorMode = null):Void + { + if (value == null) + { + FlxG.mouse.unload(); + return; + } - switch (value) - { - case Default: - if (assetCursorDefault == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_DEFAULT_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorDefault = bitmapData; - applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); - } + switch (value) + { + case Default: + if (assetCursorDefault == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_DEFAULT_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorDefault = bitmapData; + applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); + } - case Cross: - if (assetCursorCross == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_CROSS_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorCross = bitmapData; - applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); - } + case Cross: + if (assetCursorCross == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_CROSS_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorCross = bitmapData; + applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); + } - case Eraser: - if (assetCursorEraser == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_ERASER_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorEraser = bitmapData; - applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); - } + case Eraser: + if (assetCursorEraser == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_ERASER_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorEraser = bitmapData; + applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); + } - case Grabbing: - if (assetCursorGrabbing == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_GRABBING_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorGrabbing = bitmapData; - applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); - } + case Grabbing: + if (assetCursorGrabbing == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_GRABBING_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorGrabbing = bitmapData; + applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); + } - case Hourglass: - if (assetCursorHourglass == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_HOURGLASS_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorHourglass = bitmapData; - applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); - } + case Hourglass: + if (assetCursorHourglass == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_HOURGLASS_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorHourglass = bitmapData; + applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); + } - case Pointer: - if (assetCursorPointer == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_POINTER_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorPointer = bitmapData; - applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); - } + case Pointer: + if (assetCursorPointer == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_POINTER_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorPointer = bitmapData; + applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); + } - case Text: - if (assetCursorText == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_TEXT_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorText = bitmapData; - applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); - } + case Text: + if (assetCursorText == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_TEXT_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorText = bitmapData; + applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); + } - case ZoomIn: - if (assetCursorZoomIn == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_ZOOM_IN_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorZoomIn = bitmapData; - applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); - } + case ZoomIn: + if (assetCursorZoomIn == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_ZOOM_IN_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorZoomIn = bitmapData; + applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); + } - case ZoomOut: - if (assetCursorZoomOut == null) - { - var future:Future = Assets.loadBitmapData(CURSOR_ZOOM_OUT_PARAMS.graphic); - future.onComplete(function(bitmapData:BitmapData) - { - assetCursorZoomOut = bitmapData; - applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); - }); - } - else - { - applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); - } + case ZoomOut: + if (assetCursorZoomOut == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_ZOOM_OUT_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) + { + assetCursorZoomOut = bitmapData; + applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); + }); + } + else + { + applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); + } - default: - setCursorGraphic(null); - } - } + default: + setCursorGraphic(null); + } + } - static inline function applyCursorParams(graphic:BitmapData, params:CursorParams):Void - { - FlxG.mouse.load(graphic, params.scale, params.offsetX, params.offsetY); - } + static inline function applyCursorParams(graphic:BitmapData, params:CursorParams):Void + { + FlxG.mouse.load(graphic, params.scale, params.offsetX, params.offsetY); + } } // https://developer.mozilla.org/en-US/docs/Web/CSS/cursor enum CursorMode { - Default; - Cross; - Eraser; - Grabbing; - Hourglass; - Pointer; - Text; - ZoomIn; - ZoomOut; + Default; + Cross; + Eraser; + Grabbing; + Hourglass; + Pointer; + Text; + ZoomIn; + ZoomOut; } /** @@ -275,8 +284,8 @@ enum CursorMode */ typedef CursorParams = { - graphic:String, - scale:Float, - offsetX:Int, - offsetY:Int, + graphic:String, + scale:Float, + offsetX:Int, + offsetY:Int, } diff --git a/source/funkin/modding/IScriptedClass.hx b/source/funkin/modding/IScriptedClass.hx index fe2e983b3..d6a5e3300 100644 --- a/source/funkin/modding/IScriptedClass.hx +++ b/source/funkin/modding/IScriptedClass.hx @@ -9,11 +9,11 @@ import funkin.modding.events.ScriptEvent; */ interface IScriptedClass { - public function onScriptEvent(event:ScriptEvent):Void; + public function onScriptEvent(event:ScriptEvent):Void; - public function onCreate(event:ScriptEvent):Void; - public function onDestroy(event:ScriptEvent):Void; - public function onUpdate(event:UpdateScriptEvent):Void; + public function onCreate(event:ScriptEvent):Void; + public function onDestroy(event:ScriptEvent):Void; + public function onUpdate(event:UpdateScriptEvent):Void; } /** @@ -21,13 +21,13 @@ interface IScriptedClass */ interface IStateChangingScriptedClass extends IScriptedClass { - public function onStateChangeBegin(event:StateChangeScriptEvent):Void; - public function onStateChangeEnd(event:StateChangeScriptEvent):Void; + public function onStateChangeBegin(event:StateChangeScriptEvent):Void; + public function onStateChangeEnd(event:StateChangeScriptEvent):Void; - public function onSubstateOpenBegin(event:SubStateScriptEvent):Void; - public function onSubstateOpenEnd(event:SubStateScriptEvent):Void; - public function onSubstateCloseBegin(event:SubStateScriptEvent):Void; - public function onSubstateCloseEnd(event:SubStateScriptEvent):Void; + public function onSubstateOpenBegin(event:SubStateScriptEvent):Void; + public function onSubstateOpenEnd(event:SubStateScriptEvent):Void; + public function onSubstateCloseBegin(event:SubStateScriptEvent):Void; + public function onSubstateCloseEnd(event:SubStateScriptEvent):Void; } /** @@ -35,8 +35,8 @@ interface IStateChangingScriptedClass extends IScriptedClass */ interface INoteScriptedClass extends IScriptedClass { - public function onNoteHit(event:NoteScriptEvent):Void; - public function onNoteMiss(event:NoteScriptEvent):Void; + public function onNoteHit(event:NoteScriptEvent):Void; + public function onNoteMiss(event:NoteScriptEvent):Void; } /** @@ -54,87 +54,87 @@ interface INoteScriptedClass extends IScriptedClass */ interface IPlayStateScriptedClass extends IScriptedClass { - /** - * Called when the game is paused. - * Has properties to set whether the pause easter egg will happen, - * and can be cancelled by scripts. - */ - public function onPause(event:PauseScriptEvent):Void; + /** + * Called when the game is paused. + * Has properties to set whether the pause easter egg will happen, + * and can be cancelled by scripts. + */ + public function onPause(event:PauseScriptEvent):Void; - /** - * Called when the game is unpaused. - */ - public function onResume(event:ScriptEvent):Void; + /** + * Called when the game is unpaused. + */ + public function onResume(event:ScriptEvent):Void; - /** - * Called when the song has been parsed, before notes have been placed. - * Use this to mutate the chart. - */ - public function onSongLoaded(event:SongLoadScriptEvent):Void; + /** + * Called when the song has been parsed, before notes have been placed. + * Use this to mutate the chart. + */ + public function onSongLoaded(event:SongLoadScriptEvent):Void; - /** - * Called when the song starts (conductor time is 0 seconds). - */ - public function onSongStart(event:ScriptEvent):Void; + /** + * Called when the song starts (conductor time is 0 seconds). + */ + public function onSongStart(event:ScriptEvent):Void; - /** - * Called when the song ends and the song is about to be unloaded. - */ - public function onSongEnd(event:ScriptEvent):Void; + /** + * Called when the song ends and the song is about to be unloaded. + */ + public function onSongEnd(event:ScriptEvent):Void; - /** - * Called as the player runs out of health just before the game over substate is entered. - */ - public function onGameOver(event:ScriptEvent):Void; + /** + * Called as the player runs out of health just before the game over substate is entered. + */ + public function onGameOver(event:ScriptEvent):Void; - /** - * Called when the player restarts the song, either via pause menu or restarting after a game over. - */ - public function onSongRetry(event:ScriptEvent):Void; + /** + * Called when the player restarts the song, either via pause menu or restarting after a game over. + */ + public function onSongRetry(event:ScriptEvent):Void; - /** - * Called when EITHER player hits a note. - * Query the note attached to the event to determine if it was hit by the player or CPU. - */ - public function onNoteHit(event:NoteScriptEvent):Void; + /** + * Called when EITHER player hits a note. + * Query the note attached to the event to determine if it was hit by the player or CPU. + */ + public function onNoteHit(event:NoteScriptEvent):Void; - /** - * Called when EITHER player (usually the player) misses a note. - */ - public function onNoteMiss(event:NoteScriptEvent):Void; + /** + * Called when EITHER player (usually the player) misses a note. + */ + public function onNoteMiss(event:NoteScriptEvent):Void; - /** - * Called when the player presses a key when no note is on the strumline. - */ - public function onNoteGhostMiss(event:GhostMissNoteScriptEvent):Void; + /** + * Called when the player presses a key when no note is on the strumline. + */ + public function onNoteGhostMiss(event:GhostMissNoteScriptEvent):Void; - /** - * Called when the song reaches an event. - */ - public function onSongEvent(event:SongEventScriptEvent):Void; + /** + * Called when the song reaches an event. + */ + public function onSongEvent(event:SongEventScriptEvent):Void; - /** - * Called once every step of the song. - */ - public function onStepHit(event:SongTimeScriptEvent):Void; + /** + * Called once every step of the song. + */ + public function onStepHit(event:SongTimeScriptEvent):Void; - /** - * Called once every beat of the song. - */ - public function onBeatHit(event:SongTimeScriptEvent):Void; + /** + * Called once every beat of the song. + */ + public function onBeatHit(event:SongTimeScriptEvent):Void; - /** - * Called when the countdown of the song starts. - */ - public function onCountdownStart(event:CountdownScriptEvent):Void; + /** + * Called when the countdown of the song starts. + */ + public function onCountdownStart(event:CountdownScriptEvent):Void; - /** - * Called when the a part of the countdown happens. - */ - public function onCountdownStep(event:CountdownScriptEvent):Void; + /** + * Called when the a part of the countdown happens. + */ + public function onCountdownStep(event:CountdownScriptEvent):Void; - /** - * Called when the countdown of the song ends. - */ - public function onCountdownEnd(event:CountdownScriptEvent):Void; + /** + * Called when the countdown of the song ends. + */ + public function onCountdownEnd(event:CountdownScriptEvent):Void; } diff --git a/source/funkin/modding/PolymodHandler.hx b/source/funkin/modding/PolymodHandler.hx index 9586d6f46..73a4de6e7 100644 --- a/source/funkin/modding/PolymodHandler.hx +++ b/source/funkin/modding/PolymodHandler.hx @@ -79,33 +79,34 @@ class PolymodHandler buildImports(); - var loadedModList = polymod.Polymod.init({ - // Root directory for all mods. - modRoot: MOD_FOLDER, - // The directories for one or more mods to load. - dirs: ids, - // Framework being used to load assets. - framework: OPENFL, - // The current version of our API. - apiVersionRule: API_VERSION, - // Call this function any time an error occurs. - errorCallback: PolymodErrorHandler.onPolymodError, - // Enforce semantic version patterns for each mod. - // modVersions: null, - // A map telling Polymod what the asset type is for unfamiliar file extensions. - // extensionMap: [], + var loadedModList = polymod.Polymod.init( + { + // Root directory for all mods. + modRoot: MOD_FOLDER, + // The directories for one or more mods to load. + dirs: ids, + // Framework being used to load assets. + framework: OPENFL, + // The current version of our API. + apiVersionRule: API_VERSION, + // Call this function any time an error occurs. + errorCallback: PolymodErrorHandler.onPolymodError, + // Enforce semantic version patterns for each mod. + // modVersions: null, + // A map telling Polymod what the asset type is for unfamiliar file extensions. + // extensionMap: [], - frameworkParams: buildFrameworkParams(), + frameworkParams: buildFrameworkParams(), - // List of filenames to ignore in mods. Use the default list to ignore the metadata file, etc. - ignoredFiles: Polymod.getDefaultIgnoreList(), + // List of filenames to ignore in mods. Use the default list to ignore the metadata file, etc. + ignoredFiles: Polymod.getDefaultIgnoreList(), - // Parsing rules for various data formats. - parseRules: buildParseRules(), + // Parsing rules for various data formats. + parseRules: buildParseRules(), - // Parse hxc files and register the scripted classes in them. - useScriptedClasses: true, - }); + // Parse hxc files and register the scripted classes in them. + useScriptedClasses: true, + }); if (loadedModList == null) { @@ -202,11 +203,12 @@ class PolymodHandler public static function getAllMods():Array { trace('Scanning the mods folder...'); - var modMetadata = Polymod.scan({ - modRoot: MOD_FOLDER, - apiVersionRule: API_VERSION, - errorCallback: PolymodErrorHandler.onPolymodError - }); + var modMetadata = Polymod.scan( + { + modRoot: MOD_FOLDER, + apiVersionRule: API_VERSION, + errorCallback: PolymodErrorHandler.onPolymodError + }); trace('Found ${modMetadata.length} mods when scanning.'); return modMetadata; } diff --git a/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx b/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx index 4d17638bb..0ef058d8a 100644 --- a/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx +++ b/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxRuntimeShader. + * Create a scripted class that extends FlxRuntimeShader to use this. + */ @:hscriptClass -class ScriptedFlxRuntimeShader extends flixel.addons.display.FlxRuntimeShader implements HScriptedClass -{ -} +class ScriptedFlxRuntimeShader extends flixel.addons.display.FlxRuntimeShader implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxSprite.hx b/source/funkin/modding/base/ScriptedFlxSprite.hx index 036f16c00..0bd2e9dab 100644 --- a/source/funkin/modding/base/ScriptedFlxSprite.hx +++ b/source/funkin/modding/base/ScriptedFlxSprite.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxSprite. + * Create a scripted class that extends FlxSprite to use this. + */ @:hscriptClass -class ScriptedFlxSprite extends flixel.FlxSprite implements HScriptedClass -{ -} +class ScriptedFlxSprite extends flixel.FlxSprite implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx b/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx index 049c2b668..e3acc6348 100644 --- a/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx +++ b/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxSpriteGroup. + * Create a scripted class that extends FlxSpriteGroup to use this. + */ @:hscriptClass -class ScriptedFlxSpriteGroup extends flixel.group.FlxSpriteGroup implements HScriptedClass -{ -} +class ScriptedFlxSpriteGroup extends flixel.group.FlxSpriteGroup implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxState.hx b/source/funkin/modding/base/ScriptedFlxState.hx index 4069a33eb..8b659328a 100644 --- a/source/funkin/modding/base/ScriptedFlxState.hx +++ b/source/funkin/modding/base/ScriptedFlxState.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxState. + * Create a scripted class that extends FlxState to use this. + */ @:hscriptClass -class ScriptedFlxState extends flixel.FlxState implements HScriptedClass -{ -} +class ScriptedFlxState extends flixel.FlxState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxSubState.hx b/source/funkin/modding/base/ScriptedFlxSubState.hx index e5b85b26d..a9812c10d 100644 --- a/source/funkin/modding/base/ScriptedFlxSubState.hx +++ b/source/funkin/modding/base/ScriptedFlxSubState.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxSubState. + * Create a scripted class that extends FlxSubState to use this. + */ @:hscriptClass -class ScriptedFlxSubState extends flixel.FlxSubState implements HScriptedClass -{ -} +class ScriptedFlxSubState extends flixel.FlxSubState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxTransitionableState.hx b/source/funkin/modding/base/ScriptedFlxTransitionableState.hx index 4bc310222..2452b93a6 100644 --- a/source/funkin/modding/base/ScriptedFlxTransitionableState.hx +++ b/source/funkin/modding/base/ScriptedFlxTransitionableState.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxTransitionableState. + * Create a scripted class that extends FlxTransitionableState to use this. + */ @:hscriptClass -class ScriptedFlxTransitionableState extends flixel.addons.transition.FlxTransitionableState implements HScriptedClass -{ -} +class ScriptedFlxTransitionableState extends flixel.addons.transition.FlxTransitionableState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxUIState.hx b/source/funkin/modding/base/ScriptedFlxUIState.hx index 4260850ad..c58fc294f 100644 --- a/source/funkin/modding/base/ScriptedFlxUIState.hx +++ b/source/funkin/modding/base/ScriptedFlxUIState.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to an FlxUIState. + * Create a scripted class that extends FlxUIState to use this. + */ @:hscriptClass -class ScriptedFlxUIState extends flixel.addons.ui.FlxUIState implements HScriptedClass -{ -} +class ScriptedFlxUIState extends flixel.addons.ui.FlxUIState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedMusicBeatState.hx b/source/funkin/modding/base/ScriptedMusicBeatState.hx index 236df3911..782e4d0b8 100644 --- a/source/funkin/modding/base/ScriptedMusicBeatState.hx +++ b/source/funkin/modding/base/ScriptedMusicBeatState.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to a MusicBeatState. + * Create a scripted class that extends MusicBeatState to use this. + */ @:hscriptClass -class ScriptedMusicBeatState extends funkin.MusicBeatState implements HScriptedClass -{ -} +class ScriptedMusicBeatState extends funkin.MusicBeatState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx b/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx index c56776ea8..d0d764aeb 100644 --- a/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx +++ b/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx @@ -1,6 +1,8 @@ package funkin.modding.base; +/** + * A script that can be tied to a MusicBeatSubstate. + * Create a scripted class that extends MusicBeatSubstate to use this. + */ @:hscriptClass -class ScriptedMusicBeatSubstate extends funkin.MusicBeatSubstate implements HScriptedClass -{ -} +class ScriptedMusicBeatSubstate extends funkin.MusicBeatSubstate implements HScriptedClass {} diff --git a/source/funkin/modding/events/ScriptEventDispatcher.hx b/source/funkin/modding/events/ScriptEventDispatcher.hx index 474d1a18c..dda3ead00 100644 --- a/source/funkin/modding/events/ScriptEventDispatcher.hx +++ b/source/funkin/modding/events/ScriptEventDispatcher.hx @@ -8,145 +8,141 @@ import funkin.modding.IScriptedClass; */ class ScriptEventDispatcher { - public static function callEvent(target:IScriptedClass, event:ScriptEvent):Void - { - if (target == null || event == null) - return; + public static function callEvent(target:IScriptedClass, event:ScriptEvent):Void + { + if (target == null || event == null) return; - target.onScriptEvent(event); + target.onScriptEvent(event); - // If one target says to stop propagation, stop. - if (!event.shouldPropagate) - { - return; - } + // If one target says to stop propagation, stop. + if (!event.shouldPropagate) + { + return; + } - // IScriptedClass - switch (event.type) - { - case ScriptEvent.CREATE: - target.onCreate(event); - return; - case ScriptEvent.DESTROY: - target.onDestroy(event); - return; - case ScriptEvent.UPDATE: - target.onUpdate(cast event); - return; - } + // IScriptedClass + switch (event.type) + { + case ScriptEvent.CREATE: + target.onCreate(event); + return; + case ScriptEvent.DESTROY: + target.onDestroy(event); + return; + case ScriptEvent.UPDATE: + target.onUpdate(cast event); + return; + } - if (Std.isOfType(target, IPlayStateScriptedClass)) - { - var t = cast(target, IPlayStateScriptedClass); - switch (event.type) - { - case ScriptEvent.NOTE_HIT: - t.onNoteHit(cast event); - return; - case ScriptEvent.NOTE_MISS: - t.onNoteMiss(cast event); - return; - case ScriptEvent.NOTE_GHOST_MISS: - t.onNoteGhostMiss(cast event); - return; - case ScriptEvent.SONG_BEAT_HIT: - t.onBeatHit(cast event); - return; - case ScriptEvent.SONG_STEP_HIT: - t.onStepHit(cast event); - return; - case ScriptEvent.SONG_START: - t.onSongStart(event); - return; - case ScriptEvent.SONG_END: - t.onSongEnd(event); - return; - case ScriptEvent.SONG_RETRY: - t.onSongRetry(event); - return; - case ScriptEvent.GAME_OVER: - t.onGameOver(event); - return; - case ScriptEvent.PAUSE: - t.onPause(cast event); - return; - case ScriptEvent.RESUME: - t.onResume(event); - return; - case ScriptEvent.COUNTDOWN_START: - t.onCountdownStart(cast event); - return; - case ScriptEvent.COUNTDOWN_STEP: - t.onCountdownStep(cast event); - return; - case ScriptEvent.COUNTDOWN_END: - t.onCountdownEnd(cast event); - return; - case ScriptEvent.SONG_LOADED: - t.onSongLoaded(cast event); - return; - } - } + if (Std.isOfType(target, IPlayStateScriptedClass)) + { + var t = cast(target, IPlayStateScriptedClass); + switch (event.type) + { + case ScriptEvent.NOTE_HIT: + t.onNoteHit(cast event); + return; + case ScriptEvent.NOTE_MISS: + t.onNoteMiss(cast event); + return; + case ScriptEvent.NOTE_GHOST_MISS: + t.onNoteGhostMiss(cast event); + return; + case ScriptEvent.SONG_BEAT_HIT: + t.onBeatHit(cast event); + return; + case ScriptEvent.SONG_STEP_HIT: + t.onStepHit(cast event); + return; + case ScriptEvent.SONG_START: + t.onSongStart(event); + return; + case ScriptEvent.SONG_END: + t.onSongEnd(event); + return; + case ScriptEvent.SONG_RETRY: + t.onSongRetry(event); + return; + case ScriptEvent.GAME_OVER: + t.onGameOver(event); + return; + case ScriptEvent.PAUSE: + t.onPause(cast event); + return; + case ScriptEvent.RESUME: + t.onResume(event); + return; + case ScriptEvent.COUNTDOWN_START: + t.onCountdownStart(cast event); + return; + case ScriptEvent.COUNTDOWN_STEP: + t.onCountdownStep(cast event); + return; + case ScriptEvent.COUNTDOWN_END: + t.onCountdownEnd(cast event); + return; + case ScriptEvent.SONG_LOADED: + t.onSongLoaded(cast event); + return; + } + } - if (Std.isOfType(target, IStateChangingScriptedClass)) - { - var t = cast(target, IStateChangingScriptedClass); - switch (event.type) - { - case ScriptEvent.STATE_CHANGE_BEGIN: - t.onStateChangeBegin(cast event); - return; - case ScriptEvent.STATE_CHANGE_END: - t.onStateChangeEnd(cast event); - return; - case ScriptEvent.SUBSTATE_OPEN_BEGIN: - t.onSubstateOpenBegin(cast event); - return; - case ScriptEvent.SUBSTATE_OPEN_END: - t.onSubstateOpenEnd(cast event); - return; - case ScriptEvent.SUBSTATE_CLOSE_BEGIN: - t.onSubstateCloseBegin(cast event); - return; - case ScriptEvent.SUBSTATE_CLOSE_END: - t.onSubstateCloseEnd(cast event); - return; - } - } - else - { - // Prevent "NO HELPER error." - return; - } + if (Std.isOfType(target, IStateChangingScriptedClass)) + { + var t = cast(target, IStateChangingScriptedClass); + switch (event.type) + { + case ScriptEvent.STATE_CHANGE_BEGIN: + t.onStateChangeBegin(cast event); + return; + case ScriptEvent.STATE_CHANGE_END: + t.onStateChangeEnd(cast event); + return; + case ScriptEvent.SUBSTATE_OPEN_BEGIN: + t.onSubstateOpenBegin(cast event); + return; + case ScriptEvent.SUBSTATE_OPEN_END: + t.onSubstateOpenEnd(cast event); + return; + case ScriptEvent.SUBSTATE_CLOSE_BEGIN: + t.onSubstateCloseBegin(cast event); + return; + case ScriptEvent.SUBSTATE_CLOSE_END: + t.onSubstateCloseEnd(cast event); + return; + } + } + else + { + // Prevent "NO HELPER error." + return; + } - throw "No function called for event type: " + event.type; - } + throw "No function called for event type: " + event.type; + } - public static function callEventOnAllTargets(targets:Iterator, event:ScriptEvent):Void - { - if (targets == null || event == null) - return; + public static function callEventOnAllTargets(targets:Iterator, event:ScriptEvent):Void + { + if (targets == null || event == null) return; - if (Std.isOfType(targets, Array)) - { - var t = cast(targets, Array); - if (t.length == 0) - return; - } + if (Std.isOfType(targets, Array)) + { + var t = cast(targets, Array); + if (t.length == 0) return; + } - for (target in targets) - { - var t:IScriptedClass = cast target; - if (t == null) - continue; + for (target in targets) + { + var t:IScriptedClass = cast target; + if (t == null) continue; - callEvent(t, event); + callEvent(t, event); - // If one target says to stop propagation, stop. - if (!event.shouldPropagate) - { - return; - } - } - } + // If one target says to stop propagation, stop. + if (!event.shouldPropagate) + { + return; + } + } + } } diff --git a/source/funkin/modding/module/ScriptedModule.hx b/source/funkin/modding/module/ScriptedModule.hx index acb2ce031..3517bb9a1 100644 --- a/source/funkin/modding/module/ScriptedModule.hx +++ b/source/funkin/modding/module/ScriptedModule.hx @@ -2,5 +2,9 @@ package funkin.modding.module; import polymod.hscript.HScriptedClass; +/** + * A script that can be tied to a Module, which persists across states. + * Create a scripted class that extends Module to use this. + */ @:hscriptClass class ScriptedModule extends Module implements HScriptedClass {} diff --git a/source/funkin/noteStuff/NoteBasic.hx b/source/funkin/noteStuff/NoteBasic.hx index c264df52a..c1900710f 100644 --- a/source/funkin/noteStuff/NoteBasic.hx +++ b/source/funkin/noteStuff/NoteBasic.hx @@ -5,192 +5,193 @@ import flixel.text.FlxText; typedef RawNoteData = { - var strumTime:Float; - var noteData:NoteType; - var sustainLength:Float; - var altNote:String; - var noteKind:NoteKind; + var strumTime:Float; + var noteData:NoteType; + var sustainLength:Float; + var altNote:String; + var noteKind:NoteKind; } @:forward abstract NoteData(RawNoteData) { - public function new(strumTime = 0.0, noteData:NoteType = 0, sustainLength = 0.0, altNote = "", noteKind = NORMAL) - { - this = { - strumTime: strumTime, - noteData: noteData, - sustainLength: sustainLength, - altNote: altNote, - noteKind: noteKind - } - } + public function new(strumTime = 0.0, noteData:NoteType = 0, sustainLength = 0.0, altNote = "", noteKind = NORMAL) + { + this = + { + strumTime: strumTime, + noteData: noteData, + sustainLength: sustainLength, + altNote: altNote, + noteKind: noteKind + } + } - public var note(get, never):NoteType; + public var note(get, never):NoteType; - inline function get_note() - return this.noteData.value; + inline function get_note() + return this.noteData.value; - public var int(get, never):Int; + public var int(get, never):Int; - inline function get_int() - return this.noteData.int; + inline function get_int() + return this.noteData.int; - public var dir(get, never):NoteDir; + public var dir(get, never):NoteDir; - inline function get_dir() - return this.noteData.value; + inline function get_dir() + return this.noteData.value; - public var dirName(get, never):String; + public var dirName(get, never):String; - inline function get_dirName() - return dir.name; + inline function get_dirName() + return dir.name; - public var dirNameUpper(get, never):String; + public var dirNameUpper(get, never):String; - inline function get_dirNameUpper() - return dir.nameUpper; + inline function get_dirNameUpper() + return dir.nameUpper; - public var color(get, never):NoteColor; + public var color(get, never):NoteColor; - inline function get_color() - return this.noteData.value; + inline function get_color() + return this.noteData.value; - public var colorName(get, never):String; + public var colorName(get, never):String; - inline function get_colorName() - return color.name; + inline function get_colorName() + return color.name; - public var colorNameUpper(get, never):String; + public var colorNameUpper(get, never):String; - inline function get_colorNameUpper() - return color.nameUpper; + inline function get_colorNameUpper() + return color.nameUpper; - public var highStakes(get, never):Bool; + public var highStakes(get, never):Bool; - inline function get_highStakes() - return this.noteData.highStakes; + inline function get_highStakes() + return this.noteData.highStakes; - public var lowStakes(get, never):Bool; + public var lowStakes(get, never):Bool; - inline function get_lowStakes() - return this.noteData.lowStakes; + inline function get_lowStakes() + return this.noteData.lowStakes; } enum abstract NoteType(Int) from Int to Int { - // public var raw(get, never):Int; - // inline function get_raw() return this; - public var int(get, never):Int; + // public var raw(get, never):Int; + // inline function get_raw() return this; + public var int(get, never):Int; - inline function get_int() - return this < 0 ? -this : this % 4; + inline function get_int() + return this < 0 ? -this : this % 4; - public var value(get, never):NoteType; + public var value(get, never):NoteType; - inline function get_value() - return int; + inline function get_value() + return int; - public var highStakes(get, never):Bool; + public var highStakes(get, never):Bool; - inline function get_highStakes() - return this > 3; + inline function get_highStakes() + return this > 3; - public var lowStakes(get, never):Bool; + public var lowStakes(get, never):Bool; - inline function get_lowStakes() - return this < 0; + inline function get_lowStakes() + return this < 0; } @:forward enum abstract NoteDir(NoteType) from Int to Int from NoteType { - var LEFT = 0; - var DOWN = 1; - var UP = 2; - var RIGHT = 3; - var value(get, never):NoteDir; + var LEFT = 0; + var DOWN = 1; + var UP = 2; + var RIGHT = 3; + var value(get, never):NoteDir; - inline function get_value() - return this.value; + inline function get_value() + return this.value; - public var name(get, never):String; + public var name(get, never):String; - function get_name() - { - return switch (value) - { - case LEFT: "left"; - case DOWN: "down"; - case UP: "up"; - case RIGHT: "right"; - } - } + function get_name() + { + return switch (value) + { + case LEFT: "left"; + case DOWN: "down"; + case UP: "up"; + case RIGHT: "right"; + } + } - public var nameUpper(get, never):String; + public var nameUpper(get, never):String; - function get_nameUpper() - { - return switch (value) - { - case LEFT: "LEFT"; - case DOWN: "DOWN"; - case UP: "UP"; - case RIGHT: "RIGHT"; - } - } + function get_nameUpper() + { + return switch (value) + { + case LEFT: "LEFT"; + case DOWN: "DOWN"; + case UP: "UP"; + case RIGHT: "RIGHT"; + } + } } @:forward enum abstract NoteColor(NoteType) from Int to Int from NoteType { - var PURPLE = 0; - var BLUE = 1; - var GREEN = 2; - var RED = 3; - var value(get, never):NoteColor; + var PURPLE = 0; + var BLUE = 1; + var GREEN = 2; + var RED = 3; + var value(get, never):NoteColor; - inline function get_value() - return this.value; + inline function get_value() + return this.value; - public var name(get, never):String; + public var name(get, never):String; - function get_name() - { - return switch (value) - { - case PURPLE: "purple"; - case BLUE: "blue"; - case GREEN: "green"; - case RED: "red"; - } - } + function get_name() + { + return switch (value) + { + case PURPLE: "purple"; + case BLUE: "blue"; + case GREEN: "green"; + case RED: "red"; + } + } - public var nameUpper(get, never):String; + public var nameUpper(get, never):String; - function get_nameUpper() - { - return switch (value) - { - case PURPLE: "PURPLE"; - case BLUE: "BLUE"; - case GREEN: "GREEN"; - case RED: "RED"; - } - } + function get_nameUpper() + { + return switch (value) + { + case PURPLE: "PURPLE"; + case BLUE: "BLUE"; + case GREEN: "GREEN"; + case RED: "RED"; + } + } } enum abstract NoteKind(String) from String to String { - /** - * The default note type. - */ - var NORMAL = "normal"; + /** + * The default note type. + */ + var NORMAL = "normal"; - // Testing shiz - var PYRO_LIGHT = "pyro_light"; - var PYRO_KICK = "pyro_kick"; - var PYRO_TOSS = "pyro_toss"; - var PYRO_COCK = "pyro_cock"; // lol - var PYRO_SHOOT = "pyro_shoot"; + // Testing shiz + var PYRO_LIGHT = "pyro_light"; + var PYRO_KICK = "pyro_kick"; + var PYRO_TOSS = "pyro_toss"; + var PYRO_COCK = "pyro_cock"; // lol + var PYRO_SHOOT = "pyro_shoot"; } diff --git a/source/funkin/noteStuff/NoteEvent.hx b/source/funkin/noteStuff/NoteEvent.hx index 1446f2b2d..2d0c60073 100644 --- a/source/funkin/noteStuff/NoteEvent.hx +++ b/source/funkin/noteStuff/NoteEvent.hx @@ -5,8 +5,8 @@ import funkin.play.Strumline.StrumlineStyle; class NoteEvent extends Note { - public function new(strumTime:Float = 0, noteData:NoteType, ?prevNote:Note, ?sustainNote:Bool = false, ?style:StrumlineStyle = NORMAL) - { - super(strumTime, noteData, prevNote, sustainNote, style); - } + public function new(strumTime:Float = 0, noteData:NoteType, ?prevNote:Note, ?sustainNote:Bool = false, ?style:StrumlineStyle = NORMAL) + { + super(strumTime, noteData, prevNote, sustainNote, style); + } } diff --git a/source/funkin/noteStuff/NoteUtil.hx b/source/funkin/noteStuff/NoteUtil.hx index c4d552b8b..610f82a09 100644 --- a/source/funkin/noteStuff/NoteUtil.hx +++ b/source/funkin/noteStuff/NoteUtil.hx @@ -43,8 +43,7 @@ class NoteUtil for (songEvent in songEvents) { trace(songEvent); - if (songData[songEvent.t] == null) - songData[songEvent.t] = []; + if (songData[songEvent.t] == null) songData[songEvent.t] = []; songData[songEvent.t].push({songEventType: songEvent.e, value: songEvent.v, activated: false}); } diff --git a/source/funkin/play/AnimationData.hx b/source/funkin/play/AnimationData.hx index 597495345..87bc10102 100644 --- a/source/funkin/play/AnimationData.hx +++ b/source/funkin/play/AnimationData.hx @@ -2,62 +2,62 @@ package funkin.play; typedef AnimationData = { - /** - * The name for the animation. - * This should match the animation name queried by the game; - * for example, characters need animations with names `idle`, `singDOWN`, `singUPmiss`, etc. - */ - var name:String; + /** + * The name for the animation. + * This should match the animation name queried by the game; + * for example, characters need animations with names `idle`, `singDOWN`, `singUPmiss`, etc. + */ + var name:String; - /** - * The prefix for the frames of the animation as defined by the XML file. - * This will may or may not differ from the `name` of the animation, - * depending on how your animator organized their FLA or whatever. - */ - var prefix:String; + /** + * The prefix for the frames of the animation as defined by the XML file. + * This will may or may not differ from the `name` of the animation, + * depending on how your animator organized their FLA or whatever. + */ + var prefix:String; - /** - * Optionally specify an asset path to use for this specific animation. - * ONLY for use by MultiSparrow characters. - * @default The assetPath of the parent sprite - */ - var assetPath:Null; + /** + * Optionally specify an asset path to use for this specific animation. + * ONLY for use by MultiSparrow characters. + * @default The assetPath of the parent sprite + */ + var assetPath:Null; - /** - * Offset the character's position by this amount when playing this animation. - * @default [0, 0] - */ - var offsets:Null>; + /** + * Offset the character's position by this amount when playing this animation. + * @default [0, 0] + */ + var offsets:Null>; - /** - * Whether the animation should loop when it finishes. - * @default false - */ - var looped:Null; + /** + * Whether the animation should loop when it finishes. + * @default false + */ + var looped:Null; - /** - * Whether the animation's sprites should be flipped horizontally. - * @default false - */ - var flipX:Null; + /** + * Whether the animation's sprites should be flipped horizontally. + * @default false + */ + var flipX:Null; - /** - * Whether the animation's sprites should be flipped vertically. - * @default false - */ - var flipY:Null; + /** + * Whether the animation's sprites should be flipped vertically. + * @default false + */ + var flipY:Null; - /** - * The frame rate of the animation. - * @default 24 - */ - var frameRate:Null; + /** + * The frame rate of the animation. + * @default 24 + */ + var frameRate:Null; - /** - * If you want this animation to use only certain frames of an animation with a given prefix, - * select them here. - * @example [0, 1, 2, 3] (use only the first four frames) - * @default [] (all frames) - */ - var frameIndices:Null>; + /** + * If you want this animation to use only certain frames of an animation with a given prefix, + * select them here. + * @example [0, 1, 2, 3] (use only the first four frames) + * @default [] (all frames) + */ + var frameIndices:Null>; } diff --git a/source/funkin/play/Countdown.hx b/source/funkin/play/Countdown.hx index 5d722bbef..0af098dbd 100644 --- a/source/funkin/play/Countdown.hx +++ b/source/funkin/play/Countdown.hx @@ -12,290 +12,286 @@ import flixel.util.FlxTimer; class Countdown { - /** - * The current step of the countdown. - */ - public static var countdownStep(default, null):CountdownStep = BEFORE; + /** + * The current step of the countdown. + */ + public static var countdownStep(default, null):CountdownStep = BEFORE; - /** - * The currently running countdown. This will be null if there is no countdown running. - */ - static var countdownTimer:FlxTimer = null; + /** + * The currently running countdown. This will be null if there is no countdown running. + */ + static var countdownTimer:FlxTimer = null; - /** - * Performs the countdown. - * Pauses the song, plays the countdown graphics/sound, and then starts the song. - * This will automatically stop and restart the countdown if it is already running. - * @returns `false` if the countdown was cancelled by a script. - */ - public static function performCountdown(isPixelStyle:Bool):Bool - { - countdownStep = BEFORE; - var cancelled:Bool = propagateCountdownEvent(countdownStep); - if (cancelled) - return false; + /** + * Performs the countdown. + * Pauses the song, plays the countdown graphics/sound, and then starts the song. + * This will automatically stop and restart the countdown if it is already running. + * @returns `false` if the countdown was cancelled by a script. + */ + public static function performCountdown(isPixelStyle:Bool):Bool + { + countdownStep = BEFORE; + var cancelled:Bool = propagateCountdownEvent(countdownStep); + if (cancelled) return false; - // Stop any existing countdown. - stopCountdown(); + // Stop any existing countdown. + stopCountdown(); - PlayState.isInCountdown = true; - Conductor.songPosition = Conductor.crochet * -5; - // Handle onBeatHit events manually - @:privateAccess - PlayState.instance.dispatchEvent(new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, 0, 0)); + PlayState.isInCountdown = true; + Conductor.songPosition = Conductor.crochet * -5; + // Handle onBeatHit events manually + @:privateAccess + PlayState.instance.dispatchEvent(new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, 0, 0)); - // The timer function gets called based on the beat of the song. - countdownTimer = new FlxTimer(); + // The timer function gets called based on the beat of the song. + countdownTimer = new FlxTimer(); - countdownTimer.start(Conductor.crochet / 1000, function(tmr:FlxTimer) - { - countdownStep = decrement(countdownStep); + countdownTimer.start(Conductor.crochet / 1000, function(tmr:FlxTimer) + { + countdownStep = decrement(countdownStep); - // Handle onBeatHit events manually - @:privateAccess - PlayState.instance.dispatchEvent(new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, 0, 0)); + // Handle onBeatHit events manually + @:privateAccess + PlayState.instance.dispatchEvent(new SongTimeScriptEvent(ScriptEvent.SONG_BEAT_HIT, 0, 0)); - // Countdown graphic. - showCountdownGraphic(countdownStep, isPixelStyle); + // Countdown graphic. + showCountdownGraphic(countdownStep, isPixelStyle); - // Countdown sound. - playCountdownSound(countdownStep, isPixelStyle); + // Countdown sound. + playCountdownSound(countdownStep, isPixelStyle); - // Event handling bullshit. - var cancelled:Bool = propagateCountdownEvent(countdownStep); + // Event handling bullshit. + var cancelled:Bool = propagateCountdownEvent(countdownStep); - if (cancelled) - pauseCountdown(); + if (cancelled) pauseCountdown(); - if (countdownStep == AFTER) - { - stopCountdown(); - } - }, 5); // Before, 3, 2, 1, GO!, After + if (countdownStep == AFTER) + { + stopCountdown(); + } + }, 5); // Before, 3, 2, 1, GO!, After - return true; - } + return true; + } - /** - * @return TRUE if the event was cancelled. - */ - static function propagateCountdownEvent(index:CountdownStep):Bool - { - var event:ScriptEvent; + /** + * @return TRUE if the event was cancelled. + */ + static function propagateCountdownEvent(index:CountdownStep):Bool + { + var event:ScriptEvent; - switch (index) - { - case BEFORE: - event = new CountdownScriptEvent(ScriptEvent.COUNTDOWN_START, index); - case THREE | TWO | ONE | GO: // I didn't know you could use `|` in a switch/case block! - event = new CountdownScriptEvent(ScriptEvent.COUNTDOWN_STEP, index); - case AFTER: - event = new CountdownScriptEvent(ScriptEvent.COUNTDOWN_END, index, false); - default: - return true; - } + switch (index) + { + case BEFORE: + event = new CountdownScriptEvent(ScriptEvent.COUNTDOWN_START, index); + case THREE | TWO | ONE | GO: // I didn't know you could use `|` in a switch/case block! + event = new CountdownScriptEvent(ScriptEvent.COUNTDOWN_STEP, index); + case AFTER: + event = new CountdownScriptEvent(ScriptEvent.COUNTDOWN_END, index, false); + default: + return true; + } - // Modules, stages, characters. - @:privateAccess - PlayState.instance.dispatchEvent(event); + // Modules, stages, characters. + @:privateAccess + PlayState.instance.dispatchEvent(event); - return event.eventCanceled; - } + return event.eventCanceled; + } - /** - * Pauses the countdown at the current step. You can start it up again later by calling resumeCountdown(). - * - * If you want to call this from a module, it's better to use the event system and cancel the onCountdownStep event. - */ - public static function pauseCountdown() - { - if (countdownTimer != null && !countdownTimer.finished) - { - countdownTimer.active = false; - } - } + /** + * Pauses the countdown at the current step. You can start it up again later by calling resumeCountdown(). + * + * If you want to call this from a module, it's better to use the event system and cancel the onCountdownStep event. + */ + public static function pauseCountdown() + { + if (countdownTimer != null && !countdownTimer.finished) + { + countdownTimer.active = false; + } + } - /** - * Resumes the countdown at the current step. Only makes sense if you called pauseCountdown() first. - * - * If you want to call this from a module, it's better to use the event system and cancel the onCountdownStep event. - */ - public static function resumeCountdown() - { - if (countdownTimer != null && !countdownTimer.finished) - { - countdownTimer.active = true; - } - } + /** + * Resumes the countdown at the current step. Only makes sense if you called pauseCountdown() first. + * + * If you want to call this from a module, it's better to use the event system and cancel the onCountdownStep event. + */ + public static function resumeCountdown() + { + if (countdownTimer != null && !countdownTimer.finished) + { + countdownTimer.active = true; + } + } - /** - * Stops the countdown at the current step. You will have to restart it again later. - * - * If you want to call this from a module, it's better to use the event system and cancel the onCountdownStart event. - */ - public static function stopCountdown() - { - if (countdownTimer != null) - { - countdownTimer.cancel(); - countdownTimer.destroy(); - countdownTimer = null; - } - } + /** + * Stops the countdown at the current step. You will have to restart it again later. + * + * If you want to call this from a module, it's better to use the event system and cancel the onCountdownStart event. + */ + public static function stopCountdown() + { + if (countdownTimer != null) + { + countdownTimer.cancel(); + countdownTimer.destroy(); + countdownTimer = null; + } + } - /** - * Stops the current countdown, then starts the song for you. - */ - public static function skipCountdown() - { - stopCountdown(); - // This will trigger PlayState.startSong() - Conductor.songPosition = 0; - // PlayState.isInCountdown = false; - } + /** + * Stops the current countdown, then starts the song for you. + */ + public static function skipCountdown() + { + stopCountdown(); + // This will trigger PlayState.startSong() + Conductor.songPosition = 0; + // PlayState.isInCountdown = false; + } - /** - * Resets the countdown. Only works if it's already running. - */ - public static function resetCountdown() - { - if (countdownTimer != null) - { - countdownTimer.reset(); - } - } + /** + * Resets the countdown. Only works if it's already running. + */ + public static function resetCountdown() + { + if (countdownTimer != null) + { + countdownTimer.reset(); + } + } - /** - * Retrieves the graphic to use for this step of the countdown. - * TODO: Make this less dumb. Unhardcode it? Use modules? Use notestyles? - * - * This is public so modules can do lol funny shit. - */ - public static function showCountdownGraphic(index:CountdownStep, isPixelStyle:Bool):Void - { - var spritePath:String = null; + /** + * Retrieves the graphic to use for this step of the countdown. + * TODO: Make this less dumb. Unhardcode it? Use modules? Use notestyles? + * + * This is public so modules can do lol funny shit. + */ + public static function showCountdownGraphic(index:CountdownStep, isPixelStyle:Bool):Void + { + var spritePath:String = null; - if (isPixelStyle) - { - switch (index) - { - case TWO: - spritePath = 'weeb/pixelUI/ready-pixel'; - case ONE: - spritePath = 'weeb/pixelUI/set-pixel'; - case GO: - spritePath = 'weeb/pixelUI/date-pixel'; - default: - // null - } - } - else - { - switch (index) - { - case TWO: - spritePath = 'ready'; - case ONE: - spritePath = 'set'; - case GO: - spritePath = 'go'; - default: - // null - } - } + if (isPixelStyle) + { + switch (index) + { + case TWO: + spritePath = 'weeb/pixelUI/ready-pixel'; + case ONE: + spritePath = 'weeb/pixelUI/set-pixel'; + case GO: + spritePath = 'weeb/pixelUI/date-pixel'; + default: + // null + } + } + else + { + switch (index) + { + case TWO: + spritePath = 'ready'; + case ONE: + spritePath = 'set'; + case GO: + spritePath = 'go'; + default: + // null + } + } - if (spritePath == null) - return; + if (spritePath == null) return; - var countdownSprite:FlxSprite = new FlxSprite(0, 0).loadGraphic(Paths.image(spritePath)); - countdownSprite.scrollFactor.set(0, 0); + var countdownSprite:FlxSprite = new FlxSprite(0, 0).loadGraphic(Paths.image(spritePath)); + countdownSprite.scrollFactor.set(0, 0); - if (isPixelStyle) - countdownSprite.setGraphicSize(Std.int(countdownSprite.width * Constants.PIXEL_ART_SCALE)); + if (isPixelStyle) countdownSprite.setGraphicSize(Std.int(countdownSprite.width * Constants.PIXEL_ART_SCALE)); - countdownSprite.updateHitbox(); - countdownSprite.screenCenter(); + countdownSprite.updateHitbox(); + countdownSprite.screenCenter(); - // Fade sprite in, then out, then destroy it. - FlxTween.tween(countdownSprite, {y: countdownSprite.y += 100, alpha: 0}, Conductor.crochet / 1000, { - ease: FlxEase.cubeInOut, - onComplete: function(twn:FlxTween) - { - countdownSprite.destroy(); - } - }); + // Fade sprite in, then out, then destroy it. + FlxTween.tween(countdownSprite, {y: countdownSprite.y += 100, alpha: 0}, Conductor.crochet / 1000, + { + ease: FlxEase.cubeInOut, + onComplete: function(twn:FlxTween) + { + countdownSprite.destroy(); + } + }); - PlayState.instance.add(countdownSprite); - } + PlayState.instance.add(countdownSprite); + } - /** - * Retrieves the sound file to use for this step of the countdown. - * TODO: Make this less dumb. Unhardcode it? Use modules? Use notestyles? - * - * This is public so modules can do lol funny shit. - */ - public static function playCountdownSound(index:CountdownStep, isPixelStyle:Bool):Void - { - var soundPath:String = null; + /** + * Retrieves the sound file to use for this step of the countdown. + * TODO: Make this less dumb. Unhardcode it? Use modules? Use notestyles? + * + * This is public so modules can do lol funny shit. + */ + public static function playCountdownSound(index:CountdownStep, isPixelStyle:Bool):Void + { + var soundPath:String = null; - if (isPixelStyle) - { - switch (index) - { - case THREE: - soundPath = 'intro3-pixel'; - case TWO: - soundPath = 'intro2-pixel'; - case ONE: - soundPath = 'intro1-pixel'; - case GO: - soundPath = 'introGo-pixel'; - default: - // null - } - } - else - { - switch (index) - { - case THREE: - soundPath = 'intro3'; - case TWO: - soundPath = 'intro2'; - case ONE: - soundPath = 'intro1'; - case GO: - soundPath = 'introGo'; - default: - // null - } - } + if (isPixelStyle) + { + switch (index) + { + case THREE: + soundPath = 'intro3-pixel'; + case TWO: + soundPath = 'intro2-pixel'; + case ONE: + soundPath = 'intro1-pixel'; + case GO: + soundPath = 'introGo-pixel'; + default: + // null + } + } + else + { + switch (index) + { + case THREE: + soundPath = 'intro3'; + case TWO: + soundPath = 'intro2'; + case ONE: + soundPath = 'intro1'; + case GO: + soundPath = 'introGo'; + default: + // null + } + } - if (soundPath == null) - return; + if (soundPath == null) return; - FlxG.sound.play(Paths.sound(soundPath), Constants.COUNTDOWN_VOLUME); - } + FlxG.sound.play(Paths.sound(soundPath), Constants.COUNTDOWN_VOLUME); + } - public static function decrement(step:CountdownStep):CountdownStep - { - switch (step) - { - case BEFORE: - return THREE; - case THREE: - return TWO; - case TWO: - return ONE; - case ONE: - return GO; - case GO: - return AFTER; + public static function decrement(step:CountdownStep):CountdownStep + { + switch (step) + { + case BEFORE: + return THREE; + case THREE: + return TWO; + case TWO: + return ONE; + case ONE: + return GO; + case GO: + return AFTER; - default: - return AFTER; - } - } + default: + return AFTER; + } + } } /** @@ -304,10 +300,10 @@ class Countdown */ enum CountdownStep { - BEFORE; - THREE; - TWO; - ONE; - GO; - AFTER; + BEFORE; + THREE; + TWO; + ONE; + GO; + AFTER; } diff --git a/source/funkin/play/Fighter.hx b/source/funkin/play/Fighter.hx index 6a25283ba..42e044874 100644 --- a/source/funkin/play/Fighter.hx +++ b/source/funkin/play/Fighter.hx @@ -5,66 +5,65 @@ import flixel.FlxSprite; class Fighter extends BaseCharacter { - public function new(?x:Float = 0, ?y:Float = 0, ?char:String = "pico-fighter") - { - super(char); - this.x = x; - this.y = y; + public function new(?x:Float = 0, ?y:Float = 0, ?char:String = "pico-fighter") + { + super(char); + this.x = x; + this.y = y; - animation.finishCallback = function(anim:String) - { - switch anim - { - case "punch low" | "punch high" | "block" | 'dodge': - dance(true); - } - }; - } + animation.finishCallback = function(anim:String) + { + switch anim + { + case "punch low" | "punch high" | "block" | 'dodge': + dance(true); + } + }; + } - public var actions:Array = [PUNCH, BLOCK, DODGE]; + public var actions:Array = [PUNCH, BLOCK, DODGE]; - public function doSomething(?forceAction:ACTIONS) - { - var daAction:ACTIONS = FlxG.random.getObject(actions); + public function doSomething(?forceAction:ACTIONS) + { + var daAction:ACTIONS = FlxG.random.getObject(actions); - if (forceAction != null) - daAction = forceAction; + if (forceAction != null) daAction = forceAction; - switch (daAction) - { - case PUNCH: - punch(); - case BLOCK: - block(); - case DODGE: - dodge(); - } - } + switch (daAction) + { + case PUNCH: + punch(); + case BLOCK: + block(); + case DODGE: + dodge(); + } + } - public var curAction:ACTIONS = DODGE; + public var curAction:ACTIONS = DODGE; - function dodge() - { - playAnimation('dodge'); - curAction = DODGE; - } + function dodge() + { + playAnimation('dodge'); + curAction = DODGE; + } - public function block() - { - playAnimation('block'); - curAction = BLOCK; - } + public function block() + { + playAnimation('block'); + curAction = BLOCK; + } - public function punch() - { - curAction = PUNCH; - playAnimation('punch ' + (FlxG.random.bool() ? "low" : "high")); - } + public function punch() + { + curAction = PUNCH; + playAnimation('punch ' + (FlxG.random.bool() ? "low" : "high")); + } } enum ACTIONS { - DODGE; - BLOCK; - PUNCH; + DODGE; + BLOCK; + PUNCH; } diff --git a/source/funkin/play/GameOverSubstate.hx b/source/funkin/play/GameOverSubstate.hx index 0cf5f7379..ddedf257c 100644 --- a/source/funkin/play/GameOverSubstate.hx +++ b/source/funkin/play/GameOverSubstate.hx @@ -19,272 +19,270 @@ import funkin.ui.PreferencesMenu; */ class GameOverSubstate extends MusicBeatSubstate { - /** - * Which alternate animation on the character to use. - * You can set this via script. - * For example, playing a different animation when BF dies in Week 4 - * or Pico dies in Weekend 1. - */ - public static var animationSuffix:String = ""; + /** + * Which alternate animation on the character to use. + * You can set this via script. + * For example, playing a different animation when BF dies in Week 4 + * or Pico dies in Weekend 1. + */ + public static var animationSuffix:String = ""; - /** - * Which alternate game over music to use. - * You can set this via script. - * For example, the bf-pixel script sets this to `-pixel` - * and the pico-playable script sets this to `Pico`. - */ - public static var musicSuffix:String = ""; + /** + * Which alternate game over music to use. + * You can set this via script. + * For example, the bf-pixel script sets this to `-pixel` + * and the pico-playable script sets this to `Pico`. + */ + public static var musicSuffix:String = ""; - /** - * Which alternate "blue ball" sound effect to use. - */ - public static var blueBallSuffix:String = ""; + /** + * Which alternate "blue ball" sound effect to use. + */ + public static var blueBallSuffix:String = ""; - /** - * The boyfriend character. - */ - var boyfriend:BaseCharacter; + /** + * The boyfriend character. + */ + var boyfriend:BaseCharacter; - /** - * The invisible object in the scene which the camera focuses on. - */ - var cameraFollowPoint:FlxObject; + /** + * The invisible object in the scene which the camera focuses on. + */ + var cameraFollowPoint:FlxObject; - /** - * The music playing in the background of the state. - */ - var gameOverMusic:FlxSound = new FlxSound(); + /** + * The music playing in the background of the state. + */ + var gameOverMusic:FlxSound = new FlxSound(); - /** - * Whether the player has confirmed and prepared to restart the level. - * This means the animation and transition have already started. - */ - var isEnding:Bool = false; + /** + * Whether the player has confirmed and prepared to restart the level. + * This means the animation and transition have already started. + */ + var isEnding:Bool = false; - public function new() - { - super(); - } + public function new() + { + super(); + } - /** - * Reset the game over configuration to the default. - */ - public static function reset() - { - animationSuffix = ""; - musicSuffix = ""; - } + /** + * Reset the game over configuration to the default. + */ + public static function reset() + { + animationSuffix = ""; + musicSuffix = ""; + } - override public function create() - { - super.create(); + override public function create() + { + super.create(); - // - // Set up the visuals - // + // + // Set up the visuals + // - // Add a black background to the screen. - // We make this transparent so that we can see the stage underneath during debugging. - var bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); - bg.alpha = 0.25; - bg.scrollFactor.set(); - add(bg); + // Add a black background to the screen. + // We make this transparent so that we can see the stage underneath during debugging. + var bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + bg.alpha = 0.25; + bg.scrollFactor.set(); + add(bg); - // Pluck Boyfriend from the PlayState and place him (in the same position) in the GameOverSubstate. - // We can then play the character's `firstDeath` animation. - boyfriend = PlayState.instance.currentStage.getBoyfriend(true); - boyfriend.isDead = true; - add(boyfriend); - boyfriend.resetCharacter(); - boyfriend.playAnimation('firstDeath', true, true); + // Pluck Boyfriend from the PlayState and place him (in the same position) in the GameOverSubstate. + // We can then play the character's `firstDeath` animation. + boyfriend = PlayState.instance.currentStage.getBoyfriend(true); + boyfriend.isDead = true; + add(boyfriend); + boyfriend.resetCharacter(); + boyfriend.playAnimation('firstDeath', true, true); - // Assign a camera follow point to the boyfriend's position. - cameraFollowPoint = new FlxObject(PlayState.instance.cameraFollowPoint.x, PlayState.instance.cameraFollowPoint.y, 1, 1); - cameraFollowPoint.x = boyfriend.getGraphicMidpoint().x; - cameraFollowPoint.y = boyfriend.getGraphicMidpoint().y; - add(cameraFollowPoint); + // Assign a camera follow point to the boyfriend's position. + cameraFollowPoint = new FlxObject(PlayState.instance.cameraFollowPoint.x, PlayState.instance.cameraFollowPoint.y, 1, 1); + cameraFollowPoint.x = boyfriend.getGraphicMidpoint().x; + cameraFollowPoint.y = boyfriend.getGraphicMidpoint().y; + add(cameraFollowPoint); - FlxG.camera.target = null; - FlxG.camera.follow(cameraFollowPoint, LOCKON, 0.01); + FlxG.camera.target = null; + FlxG.camera.follow(cameraFollowPoint, LOCKON, 0.01); - // - // Set up the audio - // + // + // Set up the audio + // - // Prepare the game over music. - FlxG.sound.list.add(gameOverMusic); - gameOverMusic.stop(); + // Prepare the game over music. + FlxG.sound.list.add(gameOverMusic); + gameOverMusic.stop(); - // The conductor now represents the BPM of the game over music. - Conductor.songPosition = 0; + // The conductor now represents the BPM of the game over music. + Conductor.songPosition = 0; - // Play the "blue balled" sound. May play a variant if one has been assigned. - playBlueBalledSFX(); - } + // Play the "blue balled" sound. May play a variant if one has been assigned. + playBlueBalledSFX(); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - // - // Handle user inputs. - // + // + // Handle user inputs. + // - // MOBILE ONLY: Restart the level when tapping Boyfriend. - if (FlxG.onMobile) - { - var touch = FlxG.touches.getFirst(); - if (touch != null) - { - if (touch.overlaps(boyfriend)) - { - confirmDeath(); - } - } - } + // MOBILE ONLY: Restart the level when tapping Boyfriend. + if (FlxG.onMobile) + { + var touch = FlxG.touches.getFirst(); + if (touch != null) + { + if (touch.overlaps(boyfriend)) + { + confirmDeath(); + } + } + } - // KEYBOARD ONLY: Restart the level when pressing the assigned key. - if (controls.ACCEPT) - { - confirmDeath(); - } + // KEYBOARD ONLY: Restart the level when pressing the assigned key. + if (controls.ACCEPT) + { + confirmDeath(); + } - // KEYBOARD ONLY: Return to the menu when pressing the assigned key. - if (controls.BACK) - { - PlayState.deathCounter = 0; - PlayState.seenCutscene = false; - gameOverMusic.stop(); + // KEYBOARD ONLY: Return to the menu when pressing the assigned key. + if (controls.BACK) + { + PlayState.deathCounter = 0; + PlayState.seenCutscene = false; + gameOverMusic.stop(); - if (PlayState.isStoryMode) - FlxG.switchState(new StoryMenuState()); - else - FlxG.switchState(new FreeplayState()); - } + if (PlayState.isStoryMode) FlxG.switchState(new StoryMenuState()); + else + FlxG.switchState(new FreeplayState()); + } - if (gameOverMusic.playing) - { - // Match the conductor to the music. - // This enables the stepHit and beatHit events. - Conductor.songPosition = gameOverMusic.time; - } - else - { - // Music hasn't started yet. - switch (PlayState.storyWeek) - { - // TODO: Make the behavior for playing Jeff's voicelines generic or un-hardcoded. - // This will simplify the class and make it easier for mods to add death quotes. - case 7: - if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished() && !playingJeffQuote) - { - playingJeffQuote = true; - playJeffQuote(); - // Start music at lower volume - startDeathMusic(0.2, false); - } - default: - // Start music at normal volume once the initial death animation finishes. - if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished()) - { - startDeathMusic(1.0, false); - } - } - } + if (gameOverMusic.playing) + { + // Match the conductor to the music. + // This enables the stepHit and beatHit events. + Conductor.songPosition = gameOverMusic.time; + } + else + { + // Music hasn't started yet. + switch (PlayState.storyWeek) + { + // TODO: Make the behavior for playing Jeff's voicelines generic or un-hardcoded. + // This will simplify the class and make it easier for mods to add death quotes. + case 7: + if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished() && !playingJeffQuote) + { + playingJeffQuote = true; + playJeffQuote(); + // Start music at lower volume + startDeathMusic(0.2, false); + } + default: + // Start music at normal volume once the initial death animation finishes. + if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished()) + { + startDeathMusic(1.0, false); + } + } + } - // Dispatch the onUpdate event. - dispatchEvent(new UpdateScriptEvent(elapsed)); - } + // Dispatch the onUpdate event. + dispatchEvent(new UpdateScriptEvent(elapsed)); + } - /** - * Do behavior which occurs when you confirm and move to restart the level. - */ - function confirmDeath():Void - { - if (!isEnding) - { - isEnding = true; - startDeathMusic(1.0, true); // isEnding changes this function's behavior. + /** + * Do behavior which occurs when you confirm and move to restart the level. + */ + function confirmDeath():Void + { + if (!isEnding) + { + isEnding = true; + startDeathMusic(1.0, true); // isEnding changes this function's behavior. - boyfriend.playAnimation('deathConfirm' + animationSuffix, true); + boyfriend.playAnimation('deathConfirm' + animationSuffix, true); - // After the animation finishes... - new FlxTimer().start(0.7, function(tmr:FlxTimer) - { - // ...fade out the graphics. Then after that happens... - FlxG.camera.fade(FlxColor.BLACK, 2, false, function() - { - // ...close the GameOverSubstate. - FlxG.camera.fade(FlxColor.BLACK, 1, true, null, true); - PlayState.needsReset = true; + // After the animation finishes... + new FlxTimer().start(0.7, function(tmr:FlxTimer) + { + // ...fade out the graphics. Then after that happens... + FlxG.camera.fade(FlxColor.BLACK, 2, false, function() + { + // ...close the GameOverSubstate. + FlxG.camera.fade(FlxColor.BLACK, 1, true, null, true); + PlayState.needsReset = true; - // Readd Boyfriend to the stage. - boyfriend.isDead = false; - remove(boyfriend); - PlayState.instance.currentStage.addCharacter(boyfriend, BF); + // Readd Boyfriend to the stage. + boyfriend.isDead = false; + remove(boyfriend); + PlayState.instance.currentStage.addCharacter(boyfriend, BF); - // Close the substate. - close(); - }); - }); - } - } + // Close the substate. + close(); + }); + }); + } + } - override function dispatchEvent(event:ScriptEvent) - { - super.dispatchEvent(event); + override function dispatchEvent(event:ScriptEvent) + { + super.dispatchEvent(event); - ScriptEventDispatcher.callEvent(boyfriend, event); - } + ScriptEventDispatcher.callEvent(boyfriend, event); + } - /** - * Starts the death music at the appropriate volume. - * @param startingVolume - */ - function startDeathMusic(?startingVolume:Float = 1, ?force:Bool = false):Void - { - var musicPath = Paths.music('gameOver' + musicSuffix); - if (isEnding) - { - musicPath = Paths.music('gameOverEnd' + musicSuffix); - } - if (!gameOverMusic.playing || force) - { - gameOverMusic.loadEmbedded(musicPath); - gameOverMusic.volume = startingVolume; - gameOverMusic.play(); - } - } + /** + * Starts the death music at the appropriate volume. + * @param startingVolume + */ + function startDeathMusic(?startingVolume:Float = 1, ?force:Bool = false):Void + { + var musicPath = Paths.music('gameOver' + musicSuffix); + if (isEnding) + { + musicPath = Paths.music('gameOverEnd' + musicSuffix); + } + if (!gameOverMusic.playing || force) + { + gameOverMusic.loadEmbedded(musicPath); + gameOverMusic.volume = startingVolume; + gameOverMusic.play(); + } + } - /** - * Play the sound effect that occurs when - * boyfriend's testicles get utterly annihilated. - */ - function playBlueBalledSFX() - { - FlxG.sound.play(Paths.sound('fnf_loss_sfx' + blueBallSuffix)); - } + /** + * Play the sound effect that occurs when + * boyfriend's testicles get utterly annihilated. + */ + function playBlueBalledSFX() + { + FlxG.sound.play(Paths.sound('fnf_loss_sfx' + blueBallSuffix)); + } - var playingJeffQuote:Bool = false; + var playingJeffQuote:Bool = false; - /** - * Week 7-specific hardcoded behavior, to play a custom death quote. - * TODO: Make this a module somehow. - */ - function playJeffQuote() - { - var randomCensor:Array = []; + /** + * Week 7-specific hardcoded behavior, to play a custom death quote. + * TODO: Make this a module somehow. + */ + function playJeffQuote() + { + var randomCensor:Array = []; - if (PreferencesMenu.getPref('censor-naughty')) - randomCensor = [1, 3, 8, 13, 17, 21]; + if (PreferencesMenu.getPref('censor-naughty')) randomCensor = [1, 3, 8, 13, 17, 21]; - FlxG.sound.play(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, randomCensor)), 1, false, null, true, function() - { - // Once the quote ends, fade in the game over music. - if (!isEnding && gameOverMusic != null) - { - gameOverMusic.fadeIn(4, 0.2, 1); - } - }); - } + FlxG.sound.play(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, randomCensor)), 1, false, null, true, function() + { + // Once the quote ends, fade in the game over music. + if (!isEnding && gameOverMusic != null) + { + gameOverMusic.fadeIn(4, 0.2, 1); + } + }); + } } diff --git a/source/funkin/play/HealthIcon.hx b/source/funkin/play/HealthIcon.hx index d86788e2b..0f8e161d1 100644 --- a/source/funkin/play/HealthIcon.hx +++ b/source/funkin/play/HealthIcon.hx @@ -25,411 +25,400 @@ import openfl.utils.Assets; */ class HealthIcon extends FlxSprite { - /** - * The character this icon is representing. - * Setting this variable will automatically update the graphic. - */ - public var characterId(default, set):String; + /** + * The character this icon is representing. + * Setting this variable will automatically update the graphic. + */ + public var characterId(default, set):String; - /** - * Whether this health icon should automatically update its state based on the character's health. - * Note that turning this off means you have to manually do the following: - * - Bumping the icon on the beat. - * - Switching between winning/losing/idle animations. - * - Repositioning the icon as health changes. - */ - public var autoUpdate:Bool = true; + /** + * Whether this health icon should automatically update its state based on the character's health. + * Note that turning this off means you have to manually do the following: + * - Bumping the icon on the beat. + * - Switching between winning/losing/idle animations. + * - Repositioning the icon as health changes. + */ + public var autoUpdate:Bool = true; - /** - * Since the `scale` of the sprite dynamically changes over time, - * this value allows you to set a relative scale for the icon. - * @default 1x scale = 150px width and height. - */ - public var size:FlxPoint = new FlxPoint(1, 1); + /** + * Since the `scale` of the sprite dynamically changes over time, + * this value allows you to set a relative scale for the icon. + * @default 1x scale = 150px width and height. + */ + public var size:FlxPoint = new FlxPoint(1, 1); - /** - * Apply the "bump" animation once every X steps. - */ - public var bumpEvery:Int = 4; + /** + * Apply the "bump" animation once every X steps. + */ + public var bumpEvery:Int = 4; - /** - * The player the health icon is attached to. - */ - var playerId:Int = 0; + /** + * The player the health icon is attached to. + */ + var playerId:Int = 0; - /** - * Whether the sprite is pixel art or not. - * Calculated when loading an icon. - */ - var isPixel:Bool = false; + /** + * Whether the sprite is pixel art or not. + * Calculated when loading an icon. + */ + var isPixel:Bool = false; - /** - * Whether this is a legacy icon or not. - */ - var isLegacyStyle:Bool = false; + /** + * Whether this is a legacy icon or not. + */ + var isLegacyStyle:Bool = false; - /** - * At this amount of health, play the Winning animation instead of the idle. - */ - static final WINNING_THRESHOLD = 0.8 * 2; + /** + * At this amount of health, play the Winning animation instead of the idle. + */ + static final WINNING_THRESHOLD = 0.8 * 2; - /** - * At this amount of health, play the Losing animation instead of the idle. - */ - static final LOSING_THRESHOLD = 0.2 * 2; + /** + * At this amount of health, play the Losing animation instead of the idle. + */ + static final LOSING_THRESHOLD = 0.2 * 2; - /** - * The maximum health of the player. - */ - static final MAXIMUM_HEALTH = 2; + /** + * The maximum health of the player. + */ + static final MAXIMUM_HEALTH = 2; - /** - * The size of a non-pixel icon when using the legacy format. - * Remember, modern icons can be any size. - */ - public static final HEALTH_ICON_SIZE = 150; + /** + * The size of a non-pixel icon when using the legacy format. + * Remember, modern icons can be any size. + */ + public static final HEALTH_ICON_SIZE = 150; - /** - * The size of a pixel icon when using the legacy format. - * Remember, modern icons can be any size. - */ - static final PIXEL_ICON_SIZE = 32; + /** + * The size of a pixel icon when using the legacy format. + * Remember, modern icons can be any size. + */ + static final PIXEL_ICON_SIZE = 32; - /** - * shitty hardcoded value for a specific positioning!!! - */ - static final POSITION_OFFSET = 26; + /** + * shitty hardcoded value for a specific positioning!!! + */ + static final POSITION_OFFSET = 26; - public function new(char:String = 'bf', playerId:Int = 0) - { - super(0, 0); - this.playerId = playerId; - this.scrollFactor.set(); + public function new(char:String = 'bf', playerId:Int = 0) + { + super(0, 0); + this.playerId = playerId; + this.scrollFactor.set(); - this.characterId = char; + this.characterId = char; - this.antialiasing = !isPixel; + this.antialiasing = !isPixel; - initTargetSize(); - } + initTargetSize(); + } - function set_characterId(value:String):String - { - if (value == characterId) - return value; + function set_characterId(value:String):String + { + if (value == characterId) return value; - characterId = value; - loadCharacter(characterId); - return value; - } + characterId = value; + loadCharacter(characterId); + return value; + } - /** - * Easter egg; press 9 in the PlayState to use the old player icon. - */ - public function toggleOldIcon():Void - { - if (characterId == 'bf-old') - { - characterId = PlayState.currentSong.player1; - } - else - { - characterId = 'bf-old'; - } - } + /** + * Easter egg; press 9 in the PlayState to use the old player icon. + */ + public function toggleOldIcon():Void + { + if (characterId == 'bf-old') + { + characterId = PlayState.currentSong.player1; + } + else + { + characterId = 'bf-old'; + } + } - /** - * Called by Flixel every frame. Includes logic to manage the currently playing animation. - */ - override function update(elapsed:Float):Void - { - super.update(elapsed); + /** + * Called by Flixel every frame. Includes logic to manage the currently playing animation. + */ + override function update(elapsed:Float):Void + { + super.update(elapsed); - // Auto-update the state of the icon based on the player's health. - // Make sure this is false if the health icon is not being used in the PlayState. - if (autoUpdate && PlayState.instance != null) - { - switch (playerId) - { - case 0: // Boyfriend - // Update the animation based on the current state. - updateHealthIcon(PlayState.instance.health); - // Update the position to match the health bar. - this.x = PlayState.instance.healthBar.x - + (PlayState.instance.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.value, 0, 2, 100, 0) * 0.01) - - POSITION_OFFSET); - case 1: // Dad - // Update the animation based on the current state. - updateHealthIcon(MAXIMUM_HEALTH - PlayState.instance.health); - // Update the position to match the health bar. - this.x = PlayState.instance.healthBar.x - + (PlayState.instance.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.value, 0, 2, 100, 0) * 0.01)) - - (this.width - POSITION_OFFSET); - } - } + // Auto-update the state of the icon based on the player's health. + // Make sure this is false if the health icon is not being used in the PlayState. + if (autoUpdate && PlayState.instance != null) + { + switch (playerId) + { + case 0: // Boyfriend + // Update the animation based on the current state. + updateHealthIcon(PlayState.instance.health); + // Update the position to match the health bar. + this.x = PlayState.instance.healthBar.x + + (PlayState.instance.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.value, 0, 2, 100, 0) * 0.01) - POSITION_OFFSET); + case 1: // Dad + // Update the animation based on the current state. + updateHealthIcon(MAXIMUM_HEALTH - PlayState.instance.health); + // Update the position to match the health bar. + this.x = PlayState.instance.healthBar.x + + (PlayState.instance.healthBar.width * (FlxMath.remapToRange(PlayState.instance.healthBar.value, 0, 2, 100, 0) * 0.01)) + - (this.width - POSITION_OFFSET); + } + } - if (bumpEvery != 0) - { - // Lerp the health icon back to its normal size, - // while maintaining aspect ratio. - if (this.width > this.height) - { - // Apply linear interpolation while accounting for frame rate. - var targetSize = Std.int(CoolUtil.coolLerp(this.width, HEALTH_ICON_SIZE * this.size.x, 0.15)); + if (bumpEvery != 0) + { + // Lerp the health icon back to its normal size, + // while maintaining aspect ratio. + if (this.width > this.height) + { + // Apply linear interpolation while accounting for frame rate. + var targetSize = Std.int(CoolUtil.coolLerp(this.width, HEALTH_ICON_SIZE * this.size.x, 0.15)); - setGraphicSize(targetSize, 0); - } - else - { - var targetSize = Std.int(CoolUtil.coolLerp(this.height, HEALTH_ICON_SIZE * this.size.y, 0.15)); + setGraphicSize(targetSize, 0); + } + else + { + var targetSize = Std.int(CoolUtil.coolLerp(this.height, HEALTH_ICON_SIZE * this.size.y, 0.15)); - setGraphicSize(0, targetSize); - } - this.updateHitbox(); - } - } + setGraphicSize(0, targetSize); + } + this.updateHitbox(); + } + } - public function onStepHit(curStep:Int) - { - if (bumpEvery != 0 && curStep % bumpEvery == 0 && isLegacyStyle) - { - // Make the health icons bump (the update function causes them to lerp back down). - if (this.width > this.height) - { - setGraphicSize(Std.int(this.width + (HEALTH_ICON_SIZE * this.size.x * 0.2)), 0); - } - else - { - setGraphicSize(0, Std.int(this.height + (HEALTH_ICON_SIZE * this.size.y * 0.2))); - } - this.updateHitbox(); - } - } + public function onStepHit(curStep:Int) + { + if (bumpEvery != 0 && curStep % bumpEvery == 0 && isLegacyStyle) + { + // Make the health icons bump (the update function causes them to lerp back down). + if (this.width > this.height) + { + setGraphicSize(Std.int(this.width + (HEALTH_ICON_SIZE * this.size.x * 0.2)), 0); + } + else + { + setGraphicSize(0, Std.int(this.height + (HEALTH_ICON_SIZE * this.size.y * 0.2))); + } + this.updateHitbox(); + } + } - inline function initTargetSize() - { - setGraphicSize(HEALTH_ICON_SIZE); - updateHitbox(); - } + inline function initTargetSize() + { + setGraphicSize(HEALTH_ICON_SIZE); + updateHitbox(); + } - function updateHealthIcon(health:Float) - { - // We want to efficiently handle animation playback + function updateHealthIcon(health:Float) + { + // We want to efficiently handle animation playback - // Here, we use the current animation name to track the current state - // of a simple state machine. Neat! + // Here, we use the current animation name to track the current state + // of a simple state machine. Neat! - switch (getCurrentAnimation()) - { - case IDLE: - if (health < LOSING_THRESHOLD) - playAnimation(TO_LOSING, LOSING); - else if (health > WINNING_THRESHOLD) - playAnimation(TO_WINNING, WINNING); - else - playAnimation(IDLE); - case WINNING: - if (health < WINNING_THRESHOLD) - playAnimation(FROM_WINNING, IDLE); - else - playAnimation(WINNING, IDLE); - case LOSING: - if (health > LOSING_THRESHOLD) - playAnimation(FROM_LOSING, IDLE); - else - playAnimation(LOSING, IDLE); - case TO_LOSING: - if (isAnimationFinished()) - playAnimation(LOSING, IDLE); - case TO_WINNING: - if (isAnimationFinished()) - playAnimation(WINNING, IDLE); - case FROM_LOSING | FROM_WINNING: - if (isAnimationFinished()) - playAnimation(IDLE); - case "": - playAnimation(IDLE); - default: - playAnimation(IDLE); - } - } + switch (getCurrentAnimation()) + { + case IDLE: + if (health < LOSING_THRESHOLD) playAnimation(TO_LOSING, LOSING); + else if (health > WINNING_THRESHOLD) playAnimation(TO_WINNING, WINNING); + else + playAnimation(IDLE); + case WINNING: + if (health < WINNING_THRESHOLD) playAnimation(FROM_WINNING, IDLE); + else + playAnimation(WINNING, IDLE); + case LOSING: + if (health > LOSING_THRESHOLD) playAnimation(FROM_LOSING, IDLE); + else + playAnimation(LOSING, IDLE); + case TO_LOSING: + if (isAnimationFinished()) playAnimation(LOSING, IDLE); + case TO_WINNING: + if (isAnimationFinished()) playAnimation(WINNING, IDLE); + case FROM_LOSING | FROM_WINNING: + if (isAnimationFinished()) playAnimation(IDLE); + case "": + playAnimation(IDLE); + default: + playAnimation(IDLE); + } + } - /** - * Load - * @param charId - */ - function loadAnimationNew(charId:String):Void - { - this.animation.addByPrefix(IDLE, IDLE, 24, true); - this.animation.addByPrefix(WINNING, WINNING, 24, true); - this.animation.addByPrefix(LOSING, LOSING, 24, true); - this.animation.addByPrefix(TO_WINNING, TO_WINNING, 24, true); - this.animation.addByPrefix(TO_LOSING, TO_LOSING, 24, true); - this.animation.addByPrefix(FROM_WINNING, FROM_WINNING, 24, true); - this.animation.addByPrefix(FROM_LOSING, FROM_LOSING, 24, true); - } + /** + * Load + * @param charId + */ + function loadAnimationNew(charId:String):Void + { + this.animation.addByPrefix(IDLE, IDLE, 24, true); + this.animation.addByPrefix(WINNING, WINNING, 24, true); + this.animation.addByPrefix(LOSING, LOSING, 24, true); + this.animation.addByPrefix(TO_WINNING, TO_WINNING, 24, true); + this.animation.addByPrefix(TO_LOSING, TO_LOSING, 24, true); + this.animation.addByPrefix(FROM_WINNING, FROM_WINNING, 24, true); + this.animation.addByPrefix(FROM_LOSING, FROM_LOSING, 24, true); + } - /** - * Load health icon animations using the legacy format. - * Simply assumes two icons, one on - * @param charId - */ - function loadAnimationOld(charId:String):Void - { - this.animation.add(IDLE, [0], 0, false, this.playerId == 0); - this.animation.add(LOSING, [1], 0, false, this.playerId == 0); - } + /** + * Load health icon animations using the legacy format. + * Simply assumes two icons, one on + * @param charId + */ + function loadAnimationOld(charId:String):Void + { + this.animation.add(IDLE, [0], 0, false, this.playerId == 0); + this.animation.add(LOSING, [1], 0, false, this.playerId == 0); + } - function correctCharacterId(charId:String):String - { - if (!Assets.exists(Paths.image('icons/icon-$charId'))) - { - FlxG.log.warn('No icon for character: $charId : using default placeholder face instead!'); - return "face"; - } + function correctCharacterId(charId:String):String + { + if (!Assets.exists(Paths.image('icons/icon-$charId'))) + { + FlxG.log.warn('No icon for character: $charId : using default placeholder face instead!'); + return "face"; + } - return charId; - } + return charId; + } - function isNewSpritesheet(charId:String):Bool - { - return Assets.exists(Paths.file('images/icons/icon-$characterId.xml')); - } + function isNewSpritesheet(charId:String):Bool + { + return Assets.exists(Paths.file('images/icons/icon-$characterId.xml')); + } - function fetchIsPixel(charId:String):Bool - { - var charData = CharacterDataParser.fetchCharacterData(charId); - if (charData == null) - { - FlxG.log.warn('No character data found for character: $charId'); - return false; - } - return charData.isPixel; - } + function fetchIsPixel(charId:String):Bool + { + var charData = CharacterDataParser.fetchCharacterData(charId); + if (charData == null) + { + FlxG.log.warn('No character data found for character: $charId'); + return false; + } + return charData.isPixel; + } - function loadCharacter(charId:String):Void - { - if (correctCharacterId(charId) != charId) - { - characterId = correctCharacterId(charId); - return; - } + function loadCharacter(charId:String):Void + { + if (correctCharacterId(charId) != charId) + { + characterId = correctCharacterId(charId); + return; + } - isPixel = fetchIsPixel(charId); + isPixel = fetchIsPixel(charId); - isLegacyStyle = !isNewSpritesheet(charId); + isLegacyStyle = !isNewSpritesheet(charId); - if (!isLegacyStyle) - { - frames = Paths.getSparrowAtlas('icons/icon-$charId'); + if (!isLegacyStyle) + { + frames = Paths.getSparrowAtlas('icons/icon-$charId'); - loadAnimationNew(charId); - } - else - { - loadGraphic(Paths.image('icons/icon-$charId'), true, isPixel ? PIXEL_ICON_SIZE : HEALTH_ICON_SIZE, isPixel ? PIXEL_ICON_SIZE : HEALTH_ICON_SIZE); + loadAnimationNew(charId); + } + else + { + loadGraphic(Paths.image('icons/icon-$charId'), true, isPixel ? PIXEL_ICON_SIZE : HEALTH_ICON_SIZE, isPixel ? PIXEL_ICON_SIZE : HEALTH_ICON_SIZE); - loadAnimationOld(charId); - } - } + loadAnimationOld(charId); + } + } - /** - * @return Name of the current animation being played by this health icon. - */ - public function getCurrentAnimation():String - { - if (this.animation == null || this.animation.curAnim == null) - return ""; - return this.animation.curAnim.name; - } + /** + * @return Name of the current animation being played by this health icon. + */ + public function getCurrentAnimation():String + { + if (this.animation == null || this.animation.curAnim == null) return ""; + return this.animation.curAnim.name; + } - /** - * @return Whether this sprite posesses the given animation. - * Only true if the animation was successfully loaded from the XML. - */ - public function hasAnimation(id:String):Bool - { - if (this.animation == null) - return false; + /** + * @return Whether this sprite posesses the given animation. + * Only true if the animation was successfully loaded from the XML. + */ + public function hasAnimation(id:String):Bool + { + if (this.animation == null) return false; - return this.animation.getByName(id) != null; - } + return this.animation.getByName(id) != null; + } - /** - * @return Whether the current animation is in the finished state. - */ - public function isAnimationFinished():Bool - { - return this.animation.finished; - } + /** + * @return Whether the current animation is in the finished state. + */ + public function isAnimationFinished():Bool + { + return this.animation.finished; + } - /** - * Plays the animation with the given name. - * @param name The name of the animation to play. - * @param fallback The fallback animation to play if the given animation is not found. - * @param restart Whether to forcibly restart the animation if it is already playing. - */ - public function playAnimation(name:String, fallback:String = null, restart = false):Void - { - // Attempt to play the animation - if (hasAnimation(name)) - { - this.animation.play(name, restart, false, 0); - return; - } + /** + * Plays the animation with the given name. + * @param name The name of the animation to play. + * @param fallback The fallback animation to play if the given animation is not found. + * @param restart Whether to forcibly restart the animation if it is already playing. + */ + public function playAnimation(name:String, fallback:String = null, restart = false):Void + { + // Attempt to play the animation + if (hasAnimation(name)) + { + this.animation.play(name, restart, false, 0); + return; + } - // Play the fallback animation if the requested animation was not found - if (fallback != null && hasAnimation(fallback)) - { - this.animation.play(fallback, restart, false, 0); - return; - } + // Play the fallback animation if the requested animation was not found + if (fallback != null && hasAnimation(fallback)) + { + this.animation.play(fallback, restart, false, 0); + return; + } - // If we don't have an animation, we're done. - } + // If we don't have an animation, we're done. + } } enum abstract HealthIconState(String) to String from String { - /** - * Indicates the health icon is in the default animation. - * Plays as long as health is between 20% and 80%. - */ - var IDLE = "idle"; + /** + * Indicates the health icon is in the default animation. + * Plays as long as health is between 20% and 80%. + */ + var IDLE = "idle"; - /** - * Indicates the health icon is playing the Winning animation. - * Plays as long as health is above 80%. - */ - var WINNING = "winning"; + /** + * Indicates the health icon is playing the Winning animation. + * Plays as long as health is above 80%. + */ + var WINNING = "winning"; - /** - * Indicates the health icon is playing the Losing animation. - * Plays as long as health is below 20%. - */ - var LOSING = "losing"; + /** + * Indicates the health icon is playing the Losing animation. + * Plays as long as health is below 20%. + */ + var LOSING = "losing"; - /** - * Indicates that the health icon is transitioning between `idle` and `winning`. - * The next animation will play once the current animation finishes. - */ - var TO_WINNING = "toWinning"; + /** + * Indicates that the health icon is transitioning between `idle` and `winning`. + * The next animation will play once the current animation finishes. + */ + var TO_WINNING = "toWinning"; - /** - * Indicates that the health icon is transitioning between `idle` and `losing`. - * The next animation will play once the current animation finishes. - */ - var TO_LOSING = "toLosing"; + /** + * Indicates that the health icon is transitioning between `idle` and `losing`. + * The next animation will play once the current animation finishes. + */ + var TO_LOSING = "toLosing"; - /** - * Indicates that the health icon is transitioning between `winning` and `idle`. - * The next animation will play once the current animation finishes. - */ - var FROM_WINNING = "fromWinning"; + /** + * Indicates that the health icon is transitioning between `winning` and `idle`. + * The next animation will play once the current animation finishes. + */ + var FROM_WINNING = "fromWinning"; - /** - * Indicates that the health icon is transitioning between `losing` and `idle`. - * The next animation will play once the current animation finishes. - */ - var FROM_LOSING = "fromLosing"; + /** + * Indicates that the health icon is transitioning between `losing` and `idle`. + * The next animation will play once the current animation finishes. + */ + var FROM_LOSING = "fromLosing"; } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 5c166d43d..5495ad894 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -111,7 +111,7 @@ class PlayState extends MusicBeatState /** * Used to persist the position of the `cameraFollowPosition` between resets. */ - private static var previousCameraFollowPoint:FlxObject = null; + static var previousCameraFollowPoint:FlxObject = null; /** * PUBLIC INSTANCE VARIABLES @@ -161,27 +161,27 @@ class PlayState extends MusicBeatState * The Array containing the notes that are not currently on the screen. * The `update()` function regularly shifts these out to add new notes to the screen. */ - private var inactiveNotes:Array; + var inactiveNotes:Array; - private var songEvents:Array; + var songEvents:Array; /** * If true, the player is allowed to pause the game. * Disabled during the ending of a song. */ - private var mayPauseGame:Bool = true; + var mayPauseGame:Bool = true; /** * The displayed value of the player's health. * Used to provide smooth animations based on linear interpolation of the player's health. */ - private var healthLerp:Float = 1; + var healthLerp:Float = 1; /** * Forcibly disables all update logic while the game moves back to the Menu state. * This is used only when a critical error occurs and the game cannot continue. */ - private var criticalFailure:Bool = false; + var criticalFailure:Bool = false; /** * RENDER OBJECTS @@ -189,12 +189,12 @@ class PlayState extends MusicBeatState /** * The SpriteGroup containing the notes that are currently on the screen or are about to be on the screen. */ - private var activeNotes:FlxTypedGroup = null; + var activeNotes:FlxTypedGroup = null; /** * The FlxText which displays the current score. */ - private var scoreText:FlxText; + var scoreText:FlxText; /** * The bar which displays the player's health. @@ -248,7 +248,7 @@ class PlayState extends MusicBeatState * - The Game Over screen is open. * - The Chart Editor screen is open. */ - private var isGamePaused(get, never):Bool; + var isGamePaused(get, never):Bool; function get_isGamePaused():Bool { @@ -265,14 +265,14 @@ class PlayState extends MusicBeatState public static var seenCutscene:Bool = false; public static var campaignScore:Int = 0; - private var vocals:VoicesGroup; - private var vocalsFinished:Bool = false; + var vocals:VoicesGroup; + var vocalsFinished:Bool = false; - private var camZooming:Bool = false; - private var gfSpeed:Int = 1; + var camZooming:Bool = false; + var gfSpeed:Int = 1; // private var combo:Int = 0; - private var generatedMusic:Bool = false; - private var startingSong:Bool = false; + var generatedMusic:Bool = false; + var startingSong:Bool = false; var dialogue:Array; var talking:Bool = true; @@ -329,8 +329,7 @@ class PlayState extends MusicBeatState this.persistentDraw = true; // Stop any pre-existing music. - if (FlxG.sound.music != null) - FlxG.sound.music.stop(); + if (FlxG.sound.music != null) FlxG.sound.music.stop(); // Prepare the current song to be played. if (currentChart != null) @@ -497,8 +496,7 @@ class PlayState extends MusicBeatState function get_currentChart():SongDifficulty { - if (currentSong_NEW == null || storyDifficulty_NEW == null) - return null; + if (currentSong_NEW == null || storyDifficulty_NEW == null) return null; return currentSong_NEW.getDifficulty(storyDifficulty_NEW); } @@ -618,14 +616,11 @@ class PlayState extends MusicBeatState gfVersion = 'gf-tankmen'; } - if (currentSong.player1 == "pico") - gfVersion = "nene"; + if (currentSong.player1 == "pico") gfVersion = "nene"; - if (currentSong.song.toLowerCase() == 'stress') - gfVersion = 'pico-speaker'; + if (currentSong.song.toLowerCase() == 'stress') gfVersion = 'pico-speaker'; - if (currentSong.song.toLowerCase() == 'tutorial') - gfVersion = ''; + if (currentSong.song.toLowerCase() == 'tutorial') gfVersion = ''; // // GIRLFRIEND @@ -937,8 +932,7 @@ class PlayState extends MusicBeatState { black.alpha -= 0.15; - if (black.alpha > 0) - tmr.reset(0.3); + if (black.alpha > 0) tmr.reset(0.3); else { if (dialogueBox != null) @@ -952,8 +946,7 @@ class PlayState extends MusicBeatState new FlxTimer().start(0.3, function(swagTimer:FlxTimer) { senpaiEvil.alpha += 0.15; - if (senpaiEvil.alpha < 1) - swagTimer.reset(); + if (senpaiEvil.alpha < 1) swagTimer.reset(); else { senpaiEvil.animation.play('idle'); @@ -1021,7 +1014,7 @@ class PlayState extends MusicBeatState #end } - private function generateSong():Void + function generateSong():Void { // FlxG.log.add(ChartParser.parse()); @@ -1029,8 +1022,7 @@ class PlayState extends MusicBeatState currentSong.song = currentSong.song; - if (currentSong.needsVoices) - vocals = VoicesGroup.build(currentSong.song, currentSong.voiceList); + if (currentSong.needsVoices) vocals = VoicesGroup.build(currentSong.song, currentSong.voiceList); else vocals = VoicesGroup.build(currentSong.song, null); @@ -1050,7 +1042,7 @@ class PlayState extends MusicBeatState generatedMusic = true; } - private function generateSong_NEW():Void + function generateSong_NEW():Void { if (currentChart == null) { @@ -1087,15 +1079,16 @@ class PlayState extends MusicBeatState activeNotes.forEach(function(nt) { nt.followsTime = false; - FlxTween.tween(nt, {y: FlxG.height + nt.y}, 0.5, { - ease: FlxEase.expoIn, - onComplete: function(twn) + FlxTween.tween(nt, {y: FlxG.height + nt.y}, 0.5, { - nt.kill(); - activeNotes.remove(nt, true); - nt.destroy(); - } - }); + ease: FlxEase.expoIn, + onComplete: function(twn) + { + nt.kill(); + activeNotes.remove(nt, true); + nt.destroy(); + } + }); }); var noteData:Array; @@ -1116,8 +1109,7 @@ class PlayState extends MusicBeatState gottaHitNote = !section.mustHitSection; var oldNote:Note; - if (inactiveNotes.length > 0) - oldNote = inactiveNotes[Std.int(inactiveNotes.length - 1)]; + if (inactiveNotes.length > 0) oldNote = inactiveNotes[Std.int(inactiveNotes.length - 1)]; else oldNote = null; @@ -1154,8 +1146,7 @@ class PlayState extends MusicBeatState sustainNote.mustPress = gottaHitNote; - if (sustainNote.mustPress) - sustainNote.x += FlxG.width / 2; // general offset + if (sustainNote.mustPress) sustainNote.x += FlxG.width / 2; // general offset } // TODO: Replace 4 with strumlineSize @@ -1208,15 +1199,16 @@ class PlayState extends MusicBeatState activeNotes.forEach(function(nt) { nt.followsTime = false; - FlxTween.tween(nt, {y: FlxG.height + nt.y}, 0.5, { - ease: FlxEase.expoIn, - onComplete: function(twn) + FlxTween.tween(nt, {y: FlxG.height + nt.y}, 0.5, { - nt.kill(); - activeNotes.remove(nt, true); - nt.destroy(); - } - }); + ease: FlxEase.expoIn, + onComplete: function(twn) + { + nt.kill(); + activeNotes.remove(nt, true); + nt.destroy(); + } + }); }); var noteData:Array = currentChart.notes; @@ -1336,8 +1328,8 @@ class PlayState extends MusicBeatState { if (health > 0 && !paused && FlxG.autoPause) { - if (Conductor.songPosition > 0.0) - DiscordClient.changePresence(detailsText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); + if (Conductor.songPosition > 0.0) DiscordClient.changePresence(detailsText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC, true, + songLength - Conductor.songPosition); else DiscordClient.changePresence(detailsText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC); } @@ -1347,8 +1339,7 @@ class PlayState extends MusicBeatState override public function onFocusLost():Void { - if (health > 0 && !paused && FlxG.autoPause) - DiscordClient.changePresence(detailsPausedText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC); + if (health > 0 && !paused && FlxG.autoPause) DiscordClient.changePresence(detailsPausedText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC); super.onFocusLost(); } @@ -1356,16 +1347,14 @@ class PlayState extends MusicBeatState function resyncVocals():Void { - if (_exiting || vocals == null) - return; + if (_exiting || vocals == null) return; vocals.pause(); FlxG.sound.music.play(); Conductor.update(FlxG.sound.music.time + Conductor.offset); - if (vocalsFinished) - return; + if (vocalsFinished) return; vocals.time = FlxG.sound.music.time; vocals.play(); @@ -1375,8 +1364,7 @@ class PlayState extends MusicBeatState { super.update(elapsed); - if (criticalFailure) - return; + if (criticalFailure) return; if (FlxG.keys.justPressed.U) { @@ -1427,8 +1415,7 @@ class PlayState extends MusicBeatState #if !debug perfectMode = false; #else - if (FlxG.keys.justPressed.H) - camHUD.visible = !camHUD.visible; + if (FlxG.keys.justPressed.H) camHUD.visible = !camHUD.visible; #end // do this BEFORE super.update() so songPosition is accurate @@ -1437,14 +1424,12 @@ class PlayState extends MusicBeatState if (isInCountdown) { Conductor.songPosition += elapsed * 1000; - if (Conductor.songPosition >= 0) - startSong(); + if (Conductor.songPosition >= 0) startSong(); } } else { - if (Paths.SOUND_EXT == 'mp3') - Conductor.offset = -13; // DO NOT FORGET TO REMOVE THE HARDCODE! WHEN I MAKE BETTER OFFSET SYSTEM! + if (Paths.SOUND_EXT == 'mp3') Conductor.offset = -13; // DO NOT FORGET TO REMOVE THE HARDCODE! WHEN I MAKE BETTER OFFSET SYSTEM! Conductor.update(FlxG.sound.music.time + Conductor.offset); @@ -1505,16 +1490,13 @@ class PlayState extends MusicBeatState #if debug // 1: End the song immediately. - if (FlxG.keys.justPressed.ONE) - endSong(); + if (FlxG.keys.justPressed.ONE) endSong(); // 2: Gain 10% health. - if (FlxG.keys.justPressed.TWO) - health += 0.1 * 2.0; + if (FlxG.keys.justPressed.TWO) health += 0.1 * 2.0; // 3: Lose 5% health. - if (FlxG.keys.justPressed.THREE) - health -= 0.05 * 2.0; + if (FlxG.keys.justPressed.THREE) health -= 0.05 * 2.0; #end // 7: Move to the charter. @@ -1528,28 +1510,22 @@ class PlayState extends MusicBeatState } // 8: Move to the offset editor. - if (FlxG.keys.justPressed.EIGHT) - FlxG.switchState(new funkin.ui.animDebugShit.DebugBoundingState()); + if (FlxG.keys.justPressed.EIGHT) FlxG.switchState(new funkin.ui.animDebugShit.DebugBoundingState()); // 9: Toggle the old icon. - if (FlxG.keys.justPressed.NINE) - iconP1.toggleOldIcon(); + if (FlxG.keys.justPressed.NINE) iconP1.toggleOldIcon(); #if debug // PAGEUP: Skip forward one section. // SHIFT+PAGEUP: Skip forward ten sections. - if (FlxG.keys.justPressed.PAGEUP) - changeSection(FlxG.keys.pressed.SHIFT ? 10 : 1); + if (FlxG.keys.justPressed.PAGEUP) changeSection(FlxG.keys.pressed.SHIFT ? 10 : 1); // PAGEDOWN: Skip backward one section. Doesn't replace notes. // SHIFT+PAGEDOWN: Skip backward ten sections. - if (FlxG.keys.justPressed.PAGEDOWN) - changeSection(FlxG.keys.pressed.SHIFT ? -10 : -1); + if (FlxG.keys.justPressed.PAGEDOWN) changeSection(FlxG.keys.pressed.SHIFT ? -10 : -1); #end - if (health > 2.0) - health = 2.0; - if (health < 0.0) - health = 0.0; + if (health > 2.0) health = 2.0; + if (health < 0.0) health = 0.0; if (camZooming && subState == null) { @@ -1638,8 +1614,7 @@ class PlayState extends MusicBeatState { var dunceNote:Note = inactiveNotes[0]; - if (dunceNote.mustPress && !dunceNote.isSustainNote) - Highscore.tallies.totalNotes++; + if (dunceNote.mustPress && !dunceNote.isSustainNote) Highscore.tallies.totalNotes++; activeNotes.add(dunceNote); @@ -1664,16 +1639,15 @@ class PlayState extends MusicBeatState var strumLineMid = playerStrumline.y + Note.swagWidth / 2; - if (daNote.followsTime) - daNote.y = (Conductor.songPosition - daNote.data.strumTime) * (0.45 * FlxMath.roundDecimal(SongLoad.getSpeed(), 2) * daNote.noteSpeedMulti); + if (daNote.followsTime) daNote.y = (Conductor.songPosition - daNote.data.strumTime) * (0.45 * FlxMath.roundDecimal(SongLoad.getSpeed(), + 2) * daNote.noteSpeedMulti); if (PreferencesMenu.getPref('downscroll')) { daNote.y += playerStrumline.y; if (daNote.isSustainNote) { - if (daNote.animation.curAnim.name.endsWith("end") && daNote.prevNote != null) - daNote.y += daNote.prevNote.height; + if (daNote.animation.curAnim.name.endsWith("end") && daNote.prevNote != null) daNote.y += daNote.prevNote.height; else daNote.y += daNote.height / 2; @@ -1686,8 +1660,7 @@ class PlayState extends MusicBeatState } else { - if (daNote.followsTime) - daNote.y = playerStrumline.y - daNote.y; + if (daNote.followsTime) daNote.y = playerStrumline.y - daNote.y; if (daNote.isSustainNote && (!daNote.mustPress || (daNote.wasGoodHit || (daNote.prevNote.wasGoodHit && !daNote.canBeHit))) && daNote.y + daNote.offset.y * daNote.scale.y <= strumLineMid) @@ -1698,8 +1671,7 @@ class PlayState extends MusicBeatState if (!daNote.mustPress && daNote.wasGoodHit && !daNote.tooLate) { - if (currentSong != null && currentSong.song != 'Tutorial') - camZooming = true; + if (currentSong != null && currentSong.song != 'Tutorial') camZooming = true; var event:NoteScriptEvent = new NoteScriptEvent(ScriptEvent.NOTE_HIT, daNote, Highscore.tallies.combo, true); dispatchEvent(event); @@ -1715,8 +1687,7 @@ class PlayState extends MusicBeatState else { // Volume of DAD. - if (currentSong != null && currentSong.needsVoices) - vocals.volume = 1; + if (currentSong != null && currentSong.needsVoices) vocals.volume = 1; } } @@ -1773,8 +1744,7 @@ class PlayState extends MusicBeatState } } - if (!isInCutscene) - keyShit(true); + if (!isInCutscene) keyShit(true); } function applyClipRect(daNote:Note):Void @@ -1800,9 +1770,8 @@ class PlayState extends MusicBeatState function killCombo():Void { // Girlfriend gets sad if you combo break after hitting 5 notes. - if (currentStage != null && currentStage.getGirlfriend() != null) - if (Highscore.tallies.combo > 5 && currentStage.getGirlfriend().hasAnimation('sad')) - currentStage.getGirlfriend().playAnimation('sad'); + if (currentStage != null && currentStage.getGirlfriend() != null) if (Highscore.tallies.combo > 5 + && currentStage.getGirlfriend().hasAnimation('sad')) currentStage.getGirlfriend().playAnimation('sad'); if (Highscore.tallies.combo != 0) { @@ -1825,8 +1794,7 @@ class PlayState extends MusicBeatState for (i in 0...(Std.int(Conductor.currentStep / 16 + sec))) { var section = SongLoad.getSong()[i]; - if (section == null) - continue; + if (section == null) continue; if (section.changeBPM) { daBPM = SongLoad.getSong()[i].bpm; @@ -1893,11 +1861,9 @@ class PlayState extends MusicBeatState { var difficulty:String = ""; - if (storyDifficulty == 0) - difficulty = '-easy'; + if (storyDifficulty == 0) difficulty = '-easy'; - if (storyDifficulty == 2) - difficulty = '-hard'; + if (storyDifficulty == 2) difficulty = '-hard'; trace('LOADING NEXT SONG'); trace(storyPlaylist[0].toLowerCase() + difficulty); @@ -1950,25 +1916,26 @@ class PlayState extends MusicBeatState { currentStage.getGirlfriend().animation.play("cheer"); - FlxTween.tween(FlxG.camera, {zoom: 1200}, 1.1, { - ease: FlxEase.expoIn, - onComplete: _ -> + FlxTween.tween(FlxG.camera, {zoom: 1200}, 1.1, { - persistentUpdate = false; - vocals.stop(); - camHUD.alpha = 1; - var res:ResultState = new ResultState(); - res.camera = camHUD; - openSubState(res); - } - }); + ease: FlxEase.expoIn, + onComplete: _ -> + { + persistentUpdate = false; + vocals.stop(); + camHUD.alpha = 1; + var res:ResultState = new ResultState(); + res.camera = camHUD; + openSubState(res); + } + }); }); // FlxG.switchState(new FreeplayState()); } } // gives score and pops up rating - private function popUpScore(strumtime:Float, daNote:Note):Void + function popUpScore(strumtime:Float, daNote:Note):Void { var noteDiff:Float = Math.abs(strumtime - Conductor.songPosition); // boyfriend.playAnimation('hey'); @@ -2014,11 +1981,9 @@ class PlayState extends MusicBeatState grpNoteSplashes.add(noteSplash); } // Only add the score if you're not on practice mode - if (!isPracticeMode) - songScore += score; + if (!isPracticeMode) songScore += score; comboPopUps.displayRating(daRating); - if (Highscore.tallies.combo >= 10 || Highscore.tallies.combo == 0) - comboPopUps.displayCombo(Highscore.tallies.combo); + if (Highscore.tallies.combo >= 10 || Highscore.tallies.combo == 0) comboPopUps.displayCombo(Highscore.tallies.combo); } /* @@ -2081,8 +2046,7 @@ class PlayState extends MusicBeatState public function keyShit(test:Bool):Void { - if (PlayState.instance == null) - return; + if (PlayState.instance == null) return; // control arrays, order L D R U var holdArray:Array = [controls.NOTE_LEFT, controls.NOTE_DOWN, controls.NOTE_UP, controls.NOTE_RIGHT]; @@ -2103,8 +2067,7 @@ class PlayState extends MusicBeatState { PlayState.instance.activeNotes.forEachAlive(function(daNote:Note) { - if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.data.noteData]) - PlayState.instance.goodNoteHit(daNote); + if (daNote.isSustainNote && daNote.canBeHit && daNote.mustPress && holdArray[daNote.data.noteData]) PlayState.instance.goodNoteHit(daNote); }); } @@ -2159,19 +2122,16 @@ class PlayState extends MusicBeatState possibleNotes.sort((a, b) -> Std.int(a.data.strumTime - b.data.strumTime)); - if (PlayState.instance.perfectMode) - PlayState.instance.goodNoteHit(possibleNotes[0]); + if (PlayState.instance.perfectMode) PlayState.instance.goodNoteHit(possibleNotes[0]); else if (possibleNotes.length > 0) { for (shit in 0...pressArray.length) { // if a direction is hit that shouldn't be - if (pressArray[shit] && !directionList.contains(shit)) - PlayState.instance.ghostNoteMiss(shit); + if (pressArray[shit] && !directionList.contains(shit)) PlayState.instance.ghostNoteMiss(shit); } for (coolNote in possibleNotes) { - if (pressArray[coolNote.data.noteData]) - PlayState.instance.goodNoteHit(coolNote); + if (pressArray[coolNote.data.noteData]) PlayState.instance.goodNoteHit(coolNote); } } else @@ -2179,18 +2139,15 @@ class PlayState extends MusicBeatState // HNGGG I really want to add an option for ghost tapping // L + ratio for (shit in 0...pressArray.length) - if (pressArray[shit]) - PlayState.instance.ghostNoteMiss(shit, false); + if (pressArray[shit]) PlayState.instance.ghostNoteMiss(shit, false); } } - if (PlayState.instance == null || PlayState.instance.currentStage == null) - return; + if (PlayState.instance == null || PlayState.instance.currentStage == null) return; for (keyId => isPressed in pressArray) { - if (playerStrumline == null) - continue; + if (playerStrumline == null) continue; var arrow:StrumlineArrow = PlayState.instance.playerStrumline.getArrow(keyId); if (isPressed && arrow.animation.curAnim.name != 'confirm') @@ -2222,13 +2179,11 @@ class PlayState extends MusicBeatState dispatchEvent(event); // Calling event.cancelEvent() skips animations and penalties. Neat! - if (event.eventCanceled) - return; + if (event.eventCanceled) return; health += event.healthChange; - if (!isPracticeMode) - songScore += event.scoreChange; + if (!isPracticeMode) songScore += event.scoreChange; if (event.playSound) { @@ -2245,12 +2200,10 @@ class PlayState extends MusicBeatState var event:NoteScriptEvent = new NoteScriptEvent(ScriptEvent.NOTE_MISS, note, Highscore.tallies.combo, true); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! - if (event.eventCanceled) - return; + if (event.eventCanceled) return; health -= 0.0775; - if (!isPracticeMode) - songScore -= 10; + if (!isPracticeMode) songScore -= 10; vocals.volume = 0; if (Highscore.tallies.combo != 0) @@ -2274,16 +2227,14 @@ class PlayState extends MusicBeatState dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! - if (event.eventCanceled) - return; + if (event.eventCanceled) return; if (!note.isSustainNote) { Highscore.tallies.combo++; Highscore.tallies.totalNotesHit++; - if (Highscore.tallies.combo > Highscore.tallies.maxCombo) - Highscore.tallies.maxCombo = Highscore.tallies.combo; + if (Highscore.tallies.combo > Highscore.tallies.maxCombo) Highscore.tallies.maxCombo = Highscore.tallies.combo; popUpScore(note.data.strumTime, note); } @@ -2304,12 +2255,10 @@ class PlayState extends MusicBeatState override function stepHit():Bool { - if (SongLoad.songData == null) - return false; + if (SongLoad.songData == null) return false; // super.stepHit() returns false if a module cancelled the event. - if (!super.stepHit()) - return false; + if (!super.stepHit()) return false; if (Math.abs(FlxG.sound.music.time - (Conductor.songPosition - Conductor.offset)) > 20 || Math.abs(vocals.checkSyncError(Conductor.songPosition - Conductor.offset)) > 20) @@ -2317,10 +2266,8 @@ class PlayState extends MusicBeatState resyncVocals(); } - if (iconP1 != null) - iconP1.onStepHit(Std.int(Conductor.currentStep)); - if (iconP2 != null) - iconP2.onStepHit(Std.int(Conductor.currentStep)); + if (iconP1 != null) iconP1.onStepHit(Std.int(Conductor.currentStep)); + if (iconP2 != null) iconP2.onStepHit(Std.int(Conductor.currentStep)); return true; } @@ -2328,8 +2275,7 @@ class PlayState extends MusicBeatState override function beatHit():Bool { // super.beatHit() returns false if a module cancelled the event. - if (!super.beatHit()) - return false; + if (!super.beatHit()) return false; if (generatedMusic) { @@ -2428,8 +2374,7 @@ class PlayState extends MusicBeatState */ public function danceOnBeat() { - if (currentStage == null) - return; + if (currentStage == null) return; // TODO: Move this to a song event. if (Conductor.currentBeat % 16 == 15 // && currentSong.song == 'Tutorial' @@ -2505,8 +2450,7 @@ class PlayState extends MusicBeatState if (FlxG.sound.music != null) { FlxG.sound.music.pause(); - if (vocals != null) - vocals.pause(); + if (vocals != null) vocals.pause(); } // Pause the countdown. @@ -2528,18 +2472,16 @@ class PlayState extends MusicBeatState dispatchEvent(event); - if (event.eventCanceled) - return; + if (event.eventCanceled) return; - if (FlxG.sound.music != null && !startingSong && !isInCutscene) - resyncVocals(); + if (FlxG.sound.music != null && !startingSong && !isInCutscene) resyncVocals(); // Resume the countdown. Countdown.resumeCountdown(); #if discord_rpc - if (startTimer.finished) - DiscordClient.changePresence(detailsText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC, true, songLength - Conductor.songPosition); + if (startTimer.finished) DiscordClient.changePresence(detailsText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC, true, + songLength - Conductor.songPosition); else DiscordClient.changePresence(detailsText, currentSong.song + " (" + storyDifficultyText + ")", iconRPC); #end @@ -2555,8 +2497,7 @@ class PlayState extends MusicBeatState function startCountdown():Void { var result = Countdown.performCountdown(currentStageId.startsWith('school')); - if (!result) - return; + if (!result) return; isInCutscene = false; camHUD.visible = true; @@ -2577,8 +2518,7 @@ class PlayState extends MusicBeatState ScriptEventDispatcher.callEvent(currentStage, event); // Dispatch event to character script(s). - if (currentStage != null) - currentStage.dispatchToCharacters(event); + if (currentStage != null) currentStage.dispatchToCharacters(event); // TODO: Dispatch event to song script } diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 1adac9300..59879c5a4 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -19,307 +19,302 @@ import funkin.ui.TallyCounter; class ResultState extends MusicBeatSubstate { - var resultsVariation:ResultVariations; - var songName:FlxBitmapText; - var difficulty:FlxSprite; + var resultsVariation:ResultVariations; + var songName:FlxBitmapText; + var difficulty:FlxSprite; - var maskShaderSongName = new LeftMaskShader(); - var maskShaderDifficulty = new LeftMaskShader(); + var maskShaderSongName = new LeftMaskShader(); + var maskShaderDifficulty = new LeftMaskShader(); - override function create() - { - if (Highscore.tallies.sick == Highscore.tallies.totalNotesHit && Highscore.tallies.maxCombo == Highscore.tallies.totalNotesHit) - resultsVariation = PERFECT; - else if (Highscore.tallies.missed + Highscore.tallies.bad + Highscore.tallies.shit >= Highscore.tallies.totalNotes * 0.50) - resultsVariation = SHIT; // if more than half of your song was missed, bad, or shit notes, you get shit ending! - else - resultsVariation = NORMAL; + override function create() + { + if (Highscore.tallies.sick == Highscore.tallies.totalNotesHit + && Highscore.tallies.maxCombo == Highscore.tallies.totalNotesHit) resultsVariation = PERFECT; + else if (Highscore.tallies.missed + + Highscore.tallies.bad + + Highscore.tallies.shit >= Highscore.tallies.totalNotes * 0.50) + resultsVariation = SHIT; // if more than half of your song was missed, bad, or shit notes, you get shit ending! + else + resultsVariation = NORMAL; - FlxG.sound.playMusic(Paths.music("results" + resultsVariation)); + FlxG.sound.playMusic(Paths.music("results" + resultsVariation)); - // TEMP-ish, just used to sorta "cache" the 3000x3000 image! - var cacheBullShit = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem")); - add(cacheBullShit); + // TEMP-ish, just used to sorta "cache" the 3000x3000 image! + var cacheBullShit = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem")); + add(cacheBullShit); - var dumb = new FlxSprite().loadGraphic(Paths.image("resultScreen/scorePopin")); - add(dumb); + var dumb = new FlxSprite().loadGraphic(Paths.image("resultScreen/scorePopin")); + add(dumb); - var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90); - bg.scrollFactor.set(); - add(bg); + var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90); + bg.scrollFactor.set(); + add(bg); - var gf:FlxSprite = new FlxSprite(500, 300); - gf.frames = Paths.getSparrowAtlas('resultScreen/resultGirlfriendGOOD'); - gf.animation.addByPrefix("clap", "Girlfriend Good Anim", 24, false); - gf.visible = false; - gf.animation.finishCallback = _ -> - { - gf.animation.play('clap', true, false, 9); - }; - add(gf); + var gf:FlxSprite = new FlxSprite(500, 300); + gf.frames = Paths.getSparrowAtlas('resultScreen/resultGirlfriendGOOD'); + gf.animation.addByPrefix("clap", "Girlfriend Good Anim", 24, false); + gf.visible = false; + gf.animation.finishCallback = _ -> + { + gf.animation.play('clap', true, false, 9); + }; + add(gf); - var boyfriend:FlxSprite = new FlxSprite(640, -200); - boyfriend.frames = Paths.getSparrowAtlas('resultScreen/resultBoyfriendGOOD'); - boyfriend.animation.addByPrefix("fall", "Boyfriend Good", 24, false); - boyfriend.visible = false; - boyfriend.animation.finishCallback = function(_) - { - boyfriend.animation.play('fall', true, false, 14); - }; + var boyfriend:FlxSprite = new FlxSprite(640, -200); + boyfriend.frames = Paths.getSparrowAtlas('resultScreen/resultBoyfriendGOOD'); + boyfriend.animation.addByPrefix("fall", "Boyfriend Good", 24, false); + boyfriend.visible = false; + boyfriend.animation.finishCallback = function(_) + { + boyfriend.animation.play('fall', true, false, 14); + }; - add(boyfriend); + add(boyfriend); - var soundSystem:FlxSprite = new FlxSprite(-15, -180); - soundSystem.frames = Paths.getSparrowAtlas("resultScreen/soundSystem"); - soundSystem.animation.addByPrefix("idle", "sound system", 24, false); - soundSystem.visible = false; - new FlxTimer().start(0.4, _ -> - { - soundSystem.animation.play("idle"); - soundSystem.visible = true; - }); - soundSystem.antialiasing = true; - add(soundSystem); + var soundSystem:FlxSprite = new FlxSprite(-15, -180); + soundSystem.frames = Paths.getSparrowAtlas("resultScreen/soundSystem"); + soundSystem.animation.addByPrefix("idle", "sound system", 24, false); + soundSystem.visible = false; + new FlxTimer().start(0.4, _ -> + { + soundSystem.animation.play("idle"); + soundSystem.visible = true; + }); + soundSystem.antialiasing = true; + add(soundSystem); - difficulty = new FlxSprite(555); + difficulty = new FlxSprite(555); - var diffSpr:String = switch (CoolUtil.difficultyString()) - { - case "EASY": - "difEasy"; - case "NORMAL": - "difNormal"; - case "HARD": - "difHard"; - case _: - "difNormal"; - } + var diffSpr:String = switch (CoolUtil.difficultyString()) + { + case "EASY": + "difEasy"; + case "NORMAL": + "difNormal"; + case "HARD": + "difHard"; + case _: + "difNormal"; + } - difficulty.loadGraphic(Paths.image("resultScreen/" + diffSpr)); - difficulty.antialiasing = true; - add(difficulty); + difficulty.loadGraphic(Paths.image("resultScreen/" + diffSpr)); + difficulty.antialiasing = true; + add(difficulty); - var fontLetters:String = "AaBbCcDdEeFfGgHhiIJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:1234567890"; - songName = new FlxBitmapText(FlxBitmapFont.fromMonospace(Paths.image("resultScreen/tardlingSpritesheet"), fontLetters, FlxPoint.get(49, 62))); + var fontLetters:String = "AaBbCcDdEeFfGgHhiIJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:1234567890"; + songName = new FlxBitmapText(FlxBitmapFont.fromMonospace(Paths.image("resultScreen/tardlingSpritesheet"), fontLetters, FlxPoint.get(49, 62))); - // stole this from PauseSubState, I think eric wrote it!! - if (PlayState.instance.currentChart != null) - { - songName.text += '${PlayState.instance.currentChart.songName}:${PlayState.instance.currentChart.songArtist}'; - } - else - { - songName.text += PlayState.currentSong.song; - } + // stole this from PauseSubState, I think eric wrote it!! + if (PlayState.instance.currentChart != null) + { + songName.text += '${PlayState.instance.currentChart.songName}:${PlayState.instance.currentChart.songArtist}'; + } + else + { + songName.text += PlayState.currentSong.song; + } - songName.antialiasing = true; - songName.letterSpacing = -15; - songName.angle = -4.1; - add(songName); + songName.antialiasing = true; + songName.letterSpacing = -15; + songName.angle = -4.1; + add(songName); - timerThenSongName(); + timerThenSongName(); - songName.shader = maskShaderSongName; - difficulty.shader = maskShaderDifficulty; + songName.shader = maskShaderSongName; + difficulty.shader = maskShaderDifficulty; - // maskShaderSongName.swagMaskX = difficulty.x - 15; - maskShaderDifficulty.swagMaskX = difficulty.x - 15; + // maskShaderSongName.swagMaskX = difficulty.x - 15; + maskShaderDifficulty.swagMaskX = difficulty.x - 15; - var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); - blackTopBar.y = -blackTopBar.height; - FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut, startDelay: 0.5}); - blackTopBar.antialiasing = true; - add(blackTopBar); + var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); + blackTopBar.y = -blackTopBar.height; + FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut, startDelay: 0.5}); + blackTopBar.antialiasing = true; + add(blackTopBar); - var resultsAnim:FlxSprite = new FlxSprite(-200, -10); - resultsAnim.frames = Paths.getSparrowAtlas("resultScreen/results"); - resultsAnim.animation.addByPrefix("result", "results", 24, false); - resultsAnim.animation.play("result"); - resultsAnim.antialiasing = true; - add(resultsAnim); + var resultsAnim:FlxSprite = new FlxSprite(-200, -10); + resultsAnim.frames = Paths.getSparrowAtlas("resultScreen/results"); + resultsAnim.animation.addByPrefix("result", "results", 24, false); + resultsAnim.animation.play("result"); + resultsAnim.antialiasing = true; + add(resultsAnim); - var ratingsPopin:FlxSprite = new FlxSprite(-150, 120); - ratingsPopin.frames = Paths.getSparrowAtlas("resultScreen/ratingsPopin"); - ratingsPopin.animation.addByPrefix("idle", "Categories", 24, false); - // ratingsPopin.animation.play("idle"); - ratingsPopin.visible = false; - ratingsPopin.antialiasing = true; - add(ratingsPopin); + var ratingsPopin:FlxSprite = new FlxSprite(-150, 120); + ratingsPopin.frames = Paths.getSparrowAtlas("resultScreen/ratingsPopin"); + ratingsPopin.animation.addByPrefix("idle", "Categories", 24, false); + // ratingsPopin.animation.play("idle"); + ratingsPopin.visible = false; + ratingsPopin.antialiasing = true; + add(ratingsPopin); - var scorePopin:FlxSprite = new FlxSprite(-180, 520); - scorePopin.frames = Paths.getSparrowAtlas("resultScreen/scorePopin"); - scorePopin.animation.addByPrefix("score", "tally score", 24, false); - scorePopin.visible = false; - add(scorePopin); + var scorePopin:FlxSprite = new FlxSprite(-180, 520); + scorePopin.frames = Paths.getSparrowAtlas("resultScreen/scorePopin"); + scorePopin.animation.addByPrefix("score", "tally score", 24, false); + scorePopin.visible = false; + add(scorePopin); - var highscoreNew:FlxSprite = new FlxSprite(280, 580); - highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); - highscoreNew.animation.addByPrefix("new", "NEW HIGHSCORE", 24); - highscoreNew.visible = false; - highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); - highscoreNew.updateHitbox(); - add(highscoreNew); + var highscoreNew:FlxSprite = new FlxSprite(280, 580); + highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); + highscoreNew.animation.addByPrefix("new", "NEW HIGHSCORE", 24); + highscoreNew.visible = false; + highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); + highscoreNew.updateHitbox(); + add(highscoreNew); - var hStuf:Int = 50; + var hStuf:Int = 50; - var ratingGrp:FlxTypedGroup = new FlxTypedGroup(); - add(ratingGrp); + var ratingGrp:FlxTypedGroup = new FlxTypedGroup(); + add(ratingGrp); - var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, Highscore.tallies.totalNotesHit); - ratingGrp.add(totalHit); + var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, Highscore.tallies.totalNotesHit); + ratingGrp.add(totalHit); - var maxCombo:TallyCounter = new TallyCounter(375, hStuf * 4, Highscore.tallies.maxCombo); - ratingGrp.add(maxCombo); + var maxCombo:TallyCounter = new TallyCounter(375, hStuf * 4, Highscore.tallies.maxCombo); + ratingGrp.add(maxCombo); - hStuf += 2; - var extraYOffset:Float = 5; - var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, Highscore.tallies.sick, 0xFF89E59E); - ratingGrp.add(tallySick); + hStuf += 2; + var extraYOffset:Float = 5; + var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, Highscore.tallies.sick, 0xFF89E59E); + ratingGrp.add(tallySick); - var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, Highscore.tallies.good, 0xFF89C9E5); - ratingGrp.add(tallyGood); + var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, Highscore.tallies.good, 0xFF89C9E5); + ratingGrp.add(tallyGood); - var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, Highscore.tallies.bad, 0xffE6CF8A); - ratingGrp.add(tallyBad); + var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, Highscore.tallies.bad, 0xffE6CF8A); + ratingGrp.add(tallyBad); - var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, Highscore.tallies.shit, 0xFFE68C8A); - ratingGrp.add(tallyShit); + var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, Highscore.tallies.shit, 0xFFE68C8A); + ratingGrp.add(tallyShit); - var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, Highscore.tallies.missed, 0xFFC68AE6); - ratingGrp.add(tallyMissed); + var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, Highscore.tallies.missed, 0xFFC68AE6); + ratingGrp.add(tallyMissed); - for (ind => rating in ratingGrp.members) - { - rating.visible = false; - new FlxTimer().start((0.3 * ind) + 0.55, _ -> - { - rating.visible = true; - FlxTween.tween(rating, {curNumber: rating.neededNumber}, 0.5, {ease: FlxEase.quartOut}); - }); - } + for (ind => rating in ratingGrp.members) + { + rating.visible = false; + new FlxTimer().start((0.3 * ind) + 0.55, _ -> + { + rating.visible = true; + FlxTween.tween(rating, {curNumber: rating.neededNumber}, 0.5, {ease: FlxEase.quartOut}); + }); + } - new FlxTimer().start(0.5, _ -> - { - ratingsPopin.animation.play("idle"); - ratingsPopin.visible = true; + new FlxTimer().start(0.5, _ -> + { + ratingsPopin.animation.play("idle"); + ratingsPopin.visible = true; - ratingsPopin.animation.finishCallback = anim -> - { - scorePopin.animation.play("score"); - scorePopin.visible = true; + ratingsPopin.animation.finishCallback = anim -> + { + scorePopin.animation.play("score"); + scorePopin.visible = true; - highscoreNew.visible = true; - highscoreNew.animation.play("new"); - FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); - }; + highscoreNew.visible = true; + highscoreNew.animation.play("new"); + FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); + }; - boyfriend.animation.play('fall'); - boyfriend.visible = true; + boyfriend.animation.play('fall'); + boyfriend.visible = true; - new FlxTimer().start((1 / 24) * 22, _ -> - { - // plays about 22 frames (at 24fps timing) after bf spawns in - gf.animation.play('clap', true); - gf.visible = true; - }); - }); + new FlxTimer().start((1 / 24) * 22, _ -> + { + // plays about 22 frames (at 24fps timing) after bf spawns in + gf.animation.play('clap', true); + gf.visible = true; + }); + }); - if (Highscore.tallies.isNewHighscore) - trace("ITS A NEW HIGHSCORE!!!"); + if (Highscore.tallies.isNewHighscore) trace("ITS A NEW HIGHSCORE!!!"); - super.create(); - } + super.create(); + } - function timerThenSongName() - { - movingSongStuff = false; + function timerThenSongName() + { + movingSongStuff = false; - difficulty.x = 555; + difficulty.x = 555; - var diffYTween = 122; + var diffYTween = 122; - difficulty.y = -difficulty.height; - FlxTween.tween(difficulty, {y: diffYTween}, 0.5, {ease: FlxEase.quartOut, startDelay: 0.8}); + difficulty.y = -difficulty.height; + FlxTween.tween(difficulty, {y: diffYTween}, 0.5, {ease: FlxEase.quartOut, startDelay: 0.8}); - songName.y = diffYTween - 30; - songName.x = (difficulty.x + difficulty.width) + 20; + songName.y = diffYTween - 30; + songName.x = (difficulty.x + difficulty.width) + 20; - new FlxTimer().start(3, _ -> - { - movingSongStuff = true; - }); - } + new FlxTimer().start(3, _ -> + { + movingSongStuff = true; + }); + } - var movingSongStuff:Bool = false; - var speedOfTween:FlxPoint = FlxPoint.get(-1, 0.1); + var movingSongStuff:Bool = false; + var speedOfTween:FlxPoint = FlxPoint.get(-1, 0.1); - override function draw():Void - { - super.draw(); + override function draw():Void + { + super.draw(); - if (songName != null) - { - songName.clipRect = FlxRect.get(Math.max(0, 540 - songName.x), 0, FlxG.width, songName.height); - // PROBABLY SHOULD FIX MEMORY FREE OR WHATEVER THE PUT() FUNCTION DOES !!!! FEELS LIKE IT STUTTERS!!! - } + if (songName != null) + { + songName.clipRect = FlxRect.get(Math.max(0, 540 - songName.x), 0, FlxG.width, songName.height); + // PROBABLY SHOULD FIX MEMORY FREE OR WHATEVER THE PUT() FUNCTION DOES !!!! FEELS LIKE IT STUTTERS!!! + } - // if (songName != null && songName.frame != null) - // maskShaderSongName.frameUV = songName.frame.uv; - } + // if (songName != null && songName.frame != null) + // maskShaderSongName.frameUV = songName.frame.uv; + } - override function update(elapsed:Float) - { - // maskShaderSongName.swagSprX = songName.x; - maskShaderDifficulty.swagSprX = difficulty.x; + override function update(elapsed:Float) + { + // maskShaderSongName.swagSprX = songName.x; + maskShaderDifficulty.swagSprX = difficulty.x; - if (movingSongStuff) - { - songName.x += speedOfTween.x; - difficulty.x += speedOfTween.x; - songName.y += speedOfTween.y; - difficulty.y += speedOfTween.y; + if (movingSongStuff) + { + songName.x += speedOfTween.x; + difficulty.x += speedOfTween.x; + songName.y += speedOfTween.y; + difficulty.y += speedOfTween.y; - if (songName.x + songName.width < 100) - { - timerThenSongName(); - } - } + if (songName.x + songName.width < 100) + { + timerThenSongName(); + } + } - if (FlxG.keys.justPressed.RIGHT) - speedOfTween.x += 0.1; + if (FlxG.keys.justPressed.RIGHT) speedOfTween.x += 0.1; - if (FlxG.keys.justPressed.LEFT) - { - speedOfTween.x -= 0.1; - } + if (FlxG.keys.justPressed.LEFT) + { + speedOfTween.x -= 0.1; + } - if (FlxG.keys.justPressed.UP) - speedOfTween.y -= 0.1; + if (FlxG.keys.justPressed.UP) speedOfTween.y -= 0.1; - if (FlxG.keys.justPressed.DOWN) - speedOfTween.y += 0.1; + if (FlxG.keys.justPressed.DOWN) speedOfTween.y += 0.1; - if (FlxG.keys.pressed.V) - { - trace(speedOfTween); - } + if (FlxG.keys.pressed.V) + { + trace(speedOfTween); + } - if (FlxG.keys.justPressed.PERIOD) - songName.angle += 0.1; + if (FlxG.keys.justPressed.PERIOD) songName.angle += 0.1; - if (FlxG.keys.justPressed.COMMA) - songName.angle -= 0.1; + if (FlxG.keys.justPressed.COMMA) songName.angle -= 0.1; - if (controls.PAUSE) - FlxG.switchState(new FreeplayState()); + if (controls.PAUSE) FlxG.switchState(new FreeplayState()); - super.update(elapsed); - } + super.update(elapsed); + } } enum abstract ResultVariations(String) { - var PERFECT; - var NORMAL; - var SHIT; + var PERFECT; + var NORMAL; + var SHIT; } diff --git a/source/funkin/play/Strumline.hx b/source/funkin/play/Strumline.hx index 5efe21863..f45de5cac 100644 --- a/source/funkin/play/Strumline.hx +++ b/source/funkin/play/Strumline.hx @@ -18,229 +18,229 @@ import funkin.util.Constants; */ class Strumline extends FlxTypedSpriteGroup { - /** - * The style of the strumline. - * Options are normal and pixel. - */ - var style:StrumlineStyle; + /** + * The style of the strumline. + * Options are normal and pixel. + */ + var style:StrumlineStyle; - /** - * The player this strumline belongs to. - * 0 is Player 1, etc. - */ - var playerId:Int; + /** + * The player this strumline belongs to. + * 0 is Player 1, etc. + */ + var playerId:Int; - /** - * The number of notes in the strumline. - */ - var size:Int; + /** + * The number of notes in the strumline. + */ + var size:Int; - public function new(playerId:Int = 0, style:StrumlineStyle = NORMAL, size:Int = 4) - { - super(0); - this.playerId = playerId; - this.style = style; - this.size = size; + public function new(playerId:Int = 0, style:StrumlineStyle = NORMAL, size:Int = 4) + { + super(0); + this.playerId = playerId; + this.style = style; + this.size = size; - generateStrumline(); - } + generateStrumline(); + } - function generateStrumline():Void - { - for (index in 0...size) - { - createStrumlineArrow(index); - } - } + function generateStrumline():Void + { + for (index in 0...size) + { + createStrumlineArrow(index); + } + } - function createStrumlineArrow(index:Int):Void - { - var arrow:StrumlineArrow = new StrumlineArrow(index, style); - add(arrow); - } + function createStrumlineArrow(index:Int):Void + { + var arrow:StrumlineArrow = new StrumlineArrow(index, style); + add(arrow); + } - /** - * Apply a small animation which moves the arrow down and fades it in. - * Only plays at the start of Free Play songs. - * - * Note that modifying the offset of the whole strumline won't have the - * @param arrow The arrow to animate. - * @param index The index of the arrow in the strumline. - */ - function fadeInArrow(arrow:FlxSprite):Void - { - arrow.y -= 10; - arrow.alpha = 0; - FlxTween.tween(arrow, {y: arrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * arrow.ID)}); - } + /** + * Apply a small animation which moves the arrow down and fades it in. + * Only plays at the start of Free Play songs. + * + * Note that modifying the offset of the whole strumline won't have the + * @param arrow The arrow to animate. + * @param index The index of the arrow in the strumline. + */ + function fadeInArrow(arrow:FlxSprite):Void + { + arrow.y -= 10; + arrow.alpha = 0; + FlxTween.tween(arrow, {y: arrow.y + 10, alpha: 1}, 1, {ease: FlxEase.circOut, startDelay: 0.5 + (0.2 * arrow.ID)}); + } - public function fadeInArrows():Void - { - for (arrow in this.members) - { - fadeInArrow(arrow); - } - } + public function fadeInArrows():Void + { + for (arrow in this.members) + { + fadeInArrow(arrow); + } + } - function updatePositions() - { - for (arrow in members) - { - arrow.x = Note.swagWidth * arrow.ID; - arrow.x += offset.x; + function updatePositions() + { + for (arrow in members) + { + arrow.x = Note.swagWidth * arrow.ID; + arrow.x += offset.x; - arrow.y = 0; - arrow.y += offset.y; - } - } + arrow.y = 0; + arrow.y += offset.y; + } + } - /** - * Retrieves the arrow at the given position in the strumline. - * @param index The index to retrieve. - * @return The corresponding FlxSprite. - */ - public inline function getArrow(value:Int):StrumlineArrow - { - // members maintains the order that the arrows were added. - return this.members[value]; - } + /** + * Retrieves the arrow at the given position in the strumline. + * @param index The index to retrieve. + * @return The corresponding FlxSprite. + */ + public inline function getArrow(value:Int):StrumlineArrow + { + // members maintains the order that the arrows were added. + return this.members[value]; + } - public inline function getArrowByNoteType(value:NoteType):StrumlineArrow - { - return getArrow(value.int); - } + public inline function getArrowByNoteType(value:NoteType):StrumlineArrow + { + return getArrow(value.int); + } - public inline function getArrowByNoteDir(value:NoteDir):StrumlineArrow - { - return getArrow(value.int); - } + public inline function getArrowByNoteDir(value:NoteDir):StrumlineArrow + { + return getArrow(value.int); + } - public inline function getArrowByNoteColor(value:funkin.noteStuff.NoteBasic.NoteColor):StrumlineArrow - { - return getArrow(value.int); - } + public inline function getArrowByNoteColor(value:funkin.noteStuff.NoteBasic.NoteColor):StrumlineArrow + { + return getArrow(value.int); + } - /** - * Get the default Y offset of the strumline. - * @return Int - */ - public static inline function getYPos():Int - { - return PreferencesMenu.getPref('downscroll') ? (FlxG.height - 150) : 50; - } + /** + * Get the default Y offset of the strumline. + * @return Int + */ + public static inline function getYPos():Int + { + return PreferencesMenu.getPref('downscroll') ? (FlxG.height - 150) : 50; + } } class StrumlineArrow extends FlxSprite { - var style:StrumlineStyle; + var style:StrumlineStyle; - public function new(id:Int, style:StrumlineStyle) - { - super(0, 0); + public function new(id:Int, style:StrumlineStyle) + { + super(0, 0); - this.ID = id; - this.style = style; + this.ID = id; + this.style = style; - // TODO: Unhardcode this. Maybe use a note style system> - switch (style) - { - case PIXEL: - buildPixelGraphic(); - case NORMAL: - buildNormalGraphic(); - } + // TODO: Unhardcode this. Maybe use a note style system> + switch (style) + { + case PIXEL: + buildPixelGraphic(); + case NORMAL: + buildNormalGraphic(); + } - this.updateHitbox(); - scrollFactor.set(0, 0); - animation.play('static'); - } + this.updateHitbox(); + scrollFactor.set(0, 0); + animation.play('static'); + } - public function playAnimation(anim:String, force:Bool = false) - { - animation.play(anim, force); - centerOffsets(); - centerOrigin(); - } + public function playAnimation(anim:String, force:Bool = false) + { + animation.play(anim, force); + centerOffsets(); + centerOrigin(); + } - /** - * Applies the default note style to an arrow. - */ - function buildNormalGraphic():Void - { - this.frames = Paths.getSparrowAtlas('NOTE_assets'); + /** + * Applies the default note style to an arrow. + */ + function buildNormalGraphic():Void + { + this.frames = Paths.getSparrowAtlas('NOTE_assets'); - this.animation.addByPrefix('green', 'arrowUP'); - this.animation.addByPrefix('blue', 'arrowDOWN'); - this.animation.addByPrefix('purple', 'arrowLEFT'); - this.animation.addByPrefix('red', 'arrowRIGHT'); + this.animation.addByPrefix('green', 'arrowUP'); + this.animation.addByPrefix('blue', 'arrowDOWN'); + this.animation.addByPrefix('purple', 'arrowLEFT'); + this.animation.addByPrefix('red', 'arrowRIGHT'); - this.setGraphicSize(Std.int(this.width * 0.7)); - this.antialiasing = true; + this.setGraphicSize(Std.int(this.width * 0.7)); + this.antialiasing = true; - this.x += Note.swagWidth * this.ID; + this.x += Note.swagWidth * this.ID; - switch (Math.abs(this.ID)) - { - case 0: - this.animation.addByPrefix('static', 'arrow static instance 1'); - this.animation.addByPrefix('pressed', 'left press', 24, false); - this.animation.addByPrefix('confirm', 'left confirm', 24, false); - case 1: - this.animation.addByPrefix('static', 'arrow static instance 2'); - this.animation.addByPrefix('pressed', 'down press', 24, false); - this.animation.addByPrefix('confirm', 'down confirm', 24, false); - case 2: - this.animation.addByPrefix('static', 'arrow static instance 4'); - this.animation.addByPrefix('pressed', 'up press', 24, false); - this.animation.addByPrefix('confirm', 'up confirm', 24, false); - case 3: - this.animation.addByPrefix('static', 'arrow static instance 3'); - this.animation.addByPrefix('pressed', 'right press', 24, false); - this.animation.addByPrefix('confirm', 'right confirm', 24, false); - } - } + switch (Math.abs(this.ID)) + { + case 0: + this.animation.addByPrefix('static', 'arrow static instance 1'); + this.animation.addByPrefix('pressed', 'left press', 24, false); + this.animation.addByPrefix('confirm', 'left confirm', 24, false); + case 1: + this.animation.addByPrefix('static', 'arrow static instance 2'); + this.animation.addByPrefix('pressed', 'down press', 24, false); + this.animation.addByPrefix('confirm', 'down confirm', 24, false); + case 2: + this.animation.addByPrefix('static', 'arrow static instance 4'); + this.animation.addByPrefix('pressed', 'up press', 24, false); + this.animation.addByPrefix('confirm', 'up confirm', 24, false); + case 3: + this.animation.addByPrefix('static', 'arrow static instance 3'); + this.animation.addByPrefix('pressed', 'right press', 24, false); + this.animation.addByPrefix('confirm', 'right confirm', 24, false); + } + } - /** - * Applies the pixel note style to an arrow. - */ - function buildPixelGraphic():Void - { - this.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); + /** + * Applies the pixel note style to an arrow. + */ + function buildPixelGraphic():Void + { + this.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); - this.animation.add('purplel', [4]); - this.animation.add('blue', [5]); - this.animation.add('green', [6]); - this.animation.add('red', [7]); + this.animation.add('purplel', [4]); + this.animation.add('blue', [5]); + this.animation.add('green', [6]); + this.animation.add('red', [7]); - this.setGraphicSize(Std.int(this.width * Constants.PIXEL_ART_SCALE)); - this.updateHitbox(); + this.setGraphicSize(Std.int(this.width * Constants.PIXEL_ART_SCALE)); + this.updateHitbox(); - // Forcibly disable anti-aliasing on pixel graphics to stop blur. - this.antialiasing = false; + // Forcibly disable anti-aliasing on pixel graphics to stop blur. + this.antialiasing = false; - this.x += Note.swagWidth * this.ID; + this.x += Note.swagWidth * this.ID; - // TODO: Seems weird that these are hardcoded like this... no XML? - switch (Math.abs(this.ID)) - { - case 0: - this.animation.add('static', [0]); - this.animation.add('pressed', [4, 8], 12, false); - this.animation.add('confirm', [12, 16], 24, false); - case 1: - this.animation.add('static', [1]); - this.animation.add('pressed', [5, 9], 12, false); - this.animation.add('confirm', [13, 17], 24, false); - case 2: - this.animation.add('static', [2]); - this.animation.add('pressed', [6, 10], 12, false); - this.animation.add('confirm', [14, 18], 12, false); - case 3: - this.animation.add('static', [3]); - this.animation.add('pressed', [7, 11], 12, false); - this.animation.add('confirm', [15, 19], 24, false); - } - } + // TODO: Seems weird that these are hardcoded like this... no XML? + switch (Math.abs(this.ID)) + { + case 0: + this.animation.add('static', [0]); + this.animation.add('pressed', [4, 8], 12, false); + this.animation.add('confirm', [12, 16], 24, false); + case 1: + this.animation.add('static', [1]); + this.animation.add('pressed', [5, 9], 12, false); + this.animation.add('confirm', [13, 17], 24, false); + case 2: + this.animation.add('static', [2]); + this.animation.add('pressed', [6, 10], 12, false); + this.animation.add('confirm', [14, 18], 12, false); + case 3: + this.animation.add('static', [3]); + this.animation.add('pressed', [7, 11], 12, false); + this.animation.add('confirm', [15, 19], 24, false); + } + } } /** @@ -248,6 +248,6 @@ class StrumlineArrow extends FlxSprite */ enum StrumlineStyle { - NORMAL; - PIXEL; + NORMAL; + PIXEL; } diff --git a/source/funkin/play/VanillaCutscenes.hx b/source/funkin/play/VanillaCutscenes.hx index a9402d850..020612470 100644 --- a/source/funkin/play/VanillaCutscenes.hx +++ b/source/funkin/play/VanillaCutscenes.hx @@ -14,91 +14,92 @@ import flixel.util.FlxTimer; */ class VanillaCutscenes { - public static function playUghCutscene():Void - { - playVideoCutscene('music/ughCutscene.mp4'); - } + public static function playUghCutscene():Void + { + playVideoCutscene('music/ughCutscene.mp4'); + } - public static function playGunsCutscene():Void - { - playVideoCutscene('music/gunsCutscene.mp4'); - } + public static function playGunsCutscene():Void + { + playVideoCutscene('music/gunsCutscene.mp4'); + } - public static function playStressCutscene():Void - { - playVideoCutscene('music/stressCutscene.mp4'); - } + public static function playStressCutscene():Void + { + playVideoCutscene('music/stressCutscene.mp4'); + } - static var blackScreen:FlxSprite; + static var blackScreen:FlxSprite; - /** - * Plays a cutscene from a video file, then starts the countdown once the video is done. - * TODO: Cutscene is currently skipped on native platforms. - */ - static function playVideoCutscene(path:String):Void - { - PlayState.isInCutscene = true; - PlayState.instance.camHUD.visible = false; + /** + * Plays a cutscene from a video file, then starts the countdown once the video is done. + * TODO: Cutscene is currently skipped on native platforms. + */ + static function playVideoCutscene(path:String):Void + { + PlayState.isInCutscene = true; + PlayState.instance.camHUD.visible = false; - blackScreen = new FlxSprite(-200, -200).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); - blackScreen.scrollFactor.set(0, 0); - PlayState.instance.add(blackScreen); + blackScreen = new FlxSprite(-200, -200).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); + blackScreen.scrollFactor.set(0, 0); + PlayState.instance.add(blackScreen); - #if html5 - var vid:FlxVideo = new FlxVideo(path); - vid.finishCallback = finishVideoCutscene; - #else - finishVideoCutscene(); - #end - } + #if html5 + var vid:FlxVideo = new FlxVideo(path); + vid.finishCallback = finishVideoCutscene; + #else + finishVideoCutscene(); + #end + } - /** - * Does the cleanup to start the countdown after the video is done. - * Gets called immediately if the video can't be played. - */ - static function finishVideoCutscene():Void - { - PlayState.instance.remove(blackScreen); - blackScreen = null; + /** + * Does the cleanup to start the countdown after the video is done. + * Gets called immediately if the video can't be played. + */ + static function finishVideoCutscene():Void + { + PlayState.instance.remove(blackScreen); + blackScreen = null; - FlxTween.tween(FlxG.camera, {zoom: PlayState.defaultCameraZoom}, (Conductor.crochet / 1000) * 5, {ease: FlxEase.quadInOut}); - @:privateAccess - PlayState.instance.startCountdown(); - // @:privateAccess - // PlayState.instance.controlCamera(); - } + FlxTween.tween(FlxG.camera, {zoom: PlayState.defaultCameraZoom}, (Conductor.crochet / 1000) * 5, {ease: FlxEase.quadInOut}); + @:privateAccess + PlayState.instance.startCountdown(); + // @:privateAccess + // PlayState.instance.controlCamera(); + } - public static function playHorrorStartCutscene() - { - PlayState.isInCutscene = true; - PlayState.instance.camHUD.visible = false; + public static function playHorrorStartCutscene() + { + PlayState.isInCutscene = true; + PlayState.instance.camHUD.visible = false; - blackScreen = new FlxSprite(-200, -200).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); - blackScreen.scrollFactor.set(0, 0); - PlayState.instance.add(blackScreen); + blackScreen = new FlxSprite(-200, -200).makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.BLACK); + blackScreen.scrollFactor.set(0, 0); + PlayState.instance.add(blackScreen); - new FlxTimer().start(0.1, function(tmr:FlxTimer) - { - PlayState.instance.remove(blackScreen); - FlxG.sound.play(Paths.sound('Lights_Turn_On')); - PlayState.instance.cameraFollowPoint.y = -2050; - PlayState.instance.cameraFollowPoint.x += 200; - FlxG.camera.focusOn(PlayState.instance.cameraFollowPoint.getPosition()); - FlxG.camera.zoom = 1.5; + new FlxTimer().start(0.1, function(tmr:FlxTimer) + { + PlayState.instance.remove(blackScreen); + FlxG.sound.play(Paths.sound('Lights_Turn_On')); + PlayState.instance.cameraFollowPoint.y = -2050; + PlayState.instance.cameraFollowPoint.x += 200; + FlxG.camera.focusOn(PlayState.instance.cameraFollowPoint.getPosition()); + FlxG.camera.zoom = 1.5; - new FlxTimer().start(0.8, function(tmr:FlxTimer) - { - PlayState.instance.camHUD.visible = true; - PlayState.instance.remove(blackScreen); - blackScreen = null; - FlxTween.tween(FlxG.camera, {zoom: PlayState.defaultCameraZoom}, 2.5, { - ease: FlxEase.quadInOut, - onComplete: function(twn:FlxTween) - { - Countdown.performCountdown(false); - } - }); - }); - }); - } + new FlxTimer().start(0.8, function(tmr:FlxTimer) + { + PlayState.instance.camHUD.visible = true; + PlayState.instance.remove(blackScreen); + blackScreen = null; + FlxTween.tween(FlxG.camera, {zoom: PlayState.defaultCameraZoom}, 2.5, + { + ease: FlxEase.quadInOut, + onComplete: function(twn:FlxTween) + { + Countdown.performCountdown(false); + } + }); + }); + }); + } } diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index 30dabe0cf..20d1280c2 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -13,589 +13,575 @@ import funkin.play.stage.Bopper; */ class BaseCharacter extends Bopper { - // Metadata about a character. - public var characterId(default, null):String; - public var characterName(default, null):String; - - /** - * Whether the player is an active character (Boyfriend) or not. - */ - public var characterType:CharacterType = OTHER; - - /** - * Tracks how long, in seconds, the character has been playing the current `sing` animation. - * This is used to ensure that characters play the `sing` animations for at least one beat, - * preventing them from reverting to the `idle` animation between notes. - */ - public var holdTimer:Float = 0; - - public var isDead:Bool = false; - public var debugMode:Bool = false; - - /** - * This character plays a given animation when hitting these specific combo numbers. - */ - public var comboNoteCounts(default, null):Array; - - /** - * This character plays a given animation when dropping combos larger than these numbers. - */ - public var dropNoteCounts(default, null):Array; - - final _data:CharacterData; - final singTimeCrochet:Float; - - /** - * The offset between the corner of the sprite and the origin of the sprite (at the character's feet). - * cornerPosition = stageData - characterOrigin - */ - public var characterOrigin(get, null):FlxPoint; - - function get_characterOrigin():FlxPoint - { - var xPos = (width / 2); // Horizontal center - var yPos = (height); // Vertical bottom - return new FlxPoint(xPos, yPos); - } - - /** - * The absolute position of the top-left of the character. - * @return - */ - public var cornerPosition(get, null):FlxPoint; - - function get_cornerPosition():FlxPoint - { - return new FlxPoint(x, y); - } - - /** - * The absolute position of the character's feet, at the bottom-center of the sprite. - */ - public var feetPosition(get, null):FlxPoint; - - function get_feetPosition():FlxPoint - { - return new FlxPoint(x + characterOrigin.x, y + characterOrigin.y); - } - - /** - * Returns the point the camera should focus on. - * Should be approximately centered on the character, and should not move based on the current animation. - * - * Set the position of this rather than reassigning it, so that anything referencing it will not be affected. - */ - public var cameraFocusPoint(default, null):FlxPoint = new FlxPoint(0, 0); - - override function set_animOffsets(value:Array) - { - if (animOffsets == null) - value = [0, 0]; - if (animOffsets == value) - return value; - - // Make sure animOffets are halved when scale is 0.5. - var xDiff = (animOffsets[0] * this.scale.x) - value[0]; - var yDiff = (animOffsets[1] * this.scale.y) - value[1]; - - // Call the super function so that camera focus point is not affected. - super.set_x(this.x + xDiff); - super.set_y(this.y + yDiff); - - return animOffsets = value; - } - - /** - * If the x position changes, other than via changing the animation offset, - * then we need to update the camera focus point. - */ - override function set_x(value:Float):Float - { - if (value == this.x) - return value; - - var xDiff = value - this.x; - this.cameraFocusPoint.x += xDiff; - - return super.set_x(value); - } - - /** - * If the y position changes, other than via changing the animation offset, - * then we need to update the camera focus point. - */ - override function set_y(value:Float):Float - { - if (value == this.y) - return value; - - var yDiff = value - this.y; - this.cameraFocusPoint.y += yDiff; - - return super.set_y(value); - } - - public function new(id:String) - { - super(); - this.characterId = id; - - _data = CharacterDataParser.fetchCharacterData(this.characterId); - if (_data == null) - { - throw 'Could not find character data for characterId: $characterId'; - } - else - { - this.characterName = _data.name; - this.singTimeCrochet = _data.singTime; - this.globalOffsets = _data.offsets; - this.flipX = _data.flipX; - } - - shouldBop = false; - } - - /** - * Gets the value of flipX from the character data. - * `!getFlipX()` is the direction Boyfriend should face. - */ - public function getDataFlipX():Bool - { - return _data.flipX; - } - - function findCountAnimations(prefix:String):Array - { - var animNames:Array = this.animation.getNameList(); - - var result:Array = []; - - for (anim in animNames) - { - if (anim.startsWith(prefix)) - { - var comboNum:Null = Std.parseInt(anim.substring(prefix.length)); - if (comboNum != null) - { - result.push(comboNum); - } - } - } - - // Sort numerically. - result.sort((a, b) -> a - b); - return result; - } - - /** - * Reset the character so it can be used at the start of the level. - * Call this when restarting the level. - */ - public function resetCharacter(resetCamera:Bool = true):Void - { - // Reset the animation offsets. This will modify x and y to be the absolute position of the character. - this.animOffsets = [0, 0]; - - // Now we can set the x and y to be their original values without having to account for animOffsets. - this.resetPosition(); - - // Make sure we are playing the idle animation (to reapply animOffsets)... - this.dance(true); // Force to avoid the old animation playing with the wrong offset at the start of the song. - // ...then update the hitbox so that this.width and this.height are correct. - this.updateHitbox(); - - // Reset the camera focus point while we're at it. - if (resetCamera) - this.resetCameraFocusPoint(); - } - - /** - * Set the sprite scale to the appropriate value. - * @param scale - */ - function setScale(scale:Null):Void - { - if (scale == null) - scale = 1.0; - - var feetPos:FlxPoint = feetPosition; - this.scale.x = scale; - this.scale.y = scale; - this.updateHitbox(); - // Reposition with newly scaled sprite. - this.x = feetPos.x - characterOrigin.x + globalOffsets[0]; - this.y = feetPos.y - characterOrigin.y + globalOffsets[1]; - } - - /** - * The per-character camera offset. - */ - var characterCameraOffsets(get, null):Array; - - function get_characterCameraOffsets():Array - { - return _data.cameraOffsets; - } - - override function onCreate(event:ScriptEvent):Void - { - // Make sure we are playing the idle animation... - this.dance(); - // ...then update the hitbox so that this.width and this.height are correct. - this.updateHitbox(); - // Without the above code, width and height (and therefore character position) - // will be based on the first animation in the sheet rather than the default animation. - - this.resetCameraFocusPoint(); - - // Child class should have created animations by now, - // so we can query which ones are available. - this.comboNoteCounts = findCountAnimations('combo'); // example: combo50 - this.dropNoteCounts = findCountAnimations('drop'); // example: drop50 - // trace('${this.animation.getNameList()}'); - // trace('Combo note counts: ' + this.comboNoteCounts); - // trace('Drop note counts: ' + this.dropNoteCounts); - - super.onCreate(event); - } - - function resetCameraFocusPoint():Void - { - // Calculate the camera focus point - var charCenterX = this.x + this.width / 2; - var charCenterY = this.y + this.height / 2; - this.cameraFocusPoint = new FlxPoint(charCenterX + _data.cameraOffsets[0], charCenterY + _data.cameraOffsets[1]); - } - - public function initHealthIcon(isOpponent:Bool):Void - { - if (!isOpponent) - { - if (PlayState.instance.iconP1 == null) - { - trace('[WARN] Player 1 health icon not found!'); - } - PlayState.instance.iconP1.characterId = _data.healthIcon.id; - PlayState.instance.iconP1.size.set(_data.healthIcon.scale, _data.healthIcon.scale); - PlayState.instance.iconP1.offset.x = _data.healthIcon.offsets[0]; - PlayState.instance.iconP1.offset.y = _data.healthIcon.offsets[1]; - PlayState.instance.iconP1.flipX = !_data.healthIcon.flipX; - } - else - { - if (PlayState.instance.iconP2 == null) - { - trace('[WARN] Player 2 health icon not found!'); - } - PlayState.instance.iconP2.characterId = _data.healthIcon.id; - PlayState.instance.iconP2.size.set(_data.healthIcon.scale, _data.healthIcon.scale); - PlayState.instance.iconP2.offset.x = _data.healthIcon.offsets[0]; - PlayState.instance.iconP2.offset.y = _data.healthIcon.offsets[1]; - PlayState.instance.iconP1.flipX = _data.healthIcon.flipX; - } - } - - public override function onUpdate(event:UpdateScriptEvent):Void - { - super.onUpdate(event); - - // Reset hold timer for each note pressed. - if (justPressedNote() && this.characterType == BF) - { - holdTimer = 0; - } - - if (isDead) - { - playDeathAnimation(); - return; - } - - if (hasAnimation('idle-hold') && getCurrentAnimation() == "idle" && isAnimationFinished()) - playAnimation('idle-hold'); - if (hasAnimation('singLEFT-hold') && getCurrentAnimation() == "singLEFT" && isAnimationFinished()) - playAnimation('singLEFT-hold'); - if (hasAnimation('singDOWN-hold') && getCurrentAnimation() == "singDOWN" && isAnimationFinished()) - playAnimation('singDOWN-hold'); - if (hasAnimation('singUP-hold') && getCurrentAnimation() == "singUP" && isAnimationFinished()) - playAnimation('singUP-hold'); - if (hasAnimation('singRIGHT-hold') && getCurrentAnimation() == "singRIGHT" && isAnimationFinished()) - playAnimation('singRIGHT-hold'); - - // Handle character note hold time. - if (getCurrentAnimation().startsWith("sing")) - { - // TODO: Rework this code (and all character animations ugh) - // such that the hold time is handled by padding frames, - // and reverting to the idle animation is done when `isAnimationFinished()`. - // This lets you add frames to the end of the sing animation to ease back into the idle! - - holdTimer += event.elapsed; - var singTimeMs:Float = singTimeCrochet * (Conductor.crochet * 0.001); // x beats, to ms. - - if (getCurrentAnimation().endsWith("miss")) - singTimeMs *= 2; // makes it feel more awkward when you miss - - // Without this check here, the player character would only play the `sing` animation - // for one beat, as opposed to holding it as long as the player is holding the button. - var shouldStopSinging:Bool = (this.characterType == BF) ? !isHoldingNote() : true; - - FlxG.watch.addQuick('singTimeMs-${characterId}', singTimeMs); - if (holdTimer > singTimeMs && shouldStopSinging) - { - // trace('holdTimer reached ${holdTimer}sec (> ${singTimeMs}), stopping sing animation'); - holdTimer = 0; - dance(true); - } - } - else - { - holdTimer = 0; - // super.onBeatHit handles the regular `dance()` calls. - } - FlxG.watch.addQuick('holdTimer-${characterId}', holdTimer); - } - - /** - * Since no `onBeatHit` or `dance` calls happen in GameOverSubstate, - * this regularly gets called instead. - */ - public function playDeathAnimation(force:Bool = false):Void - { - if (force || (getCurrentAnimation().startsWith("firstDeath") && isAnimationFinished())) - { - playAnimation("deathLoop" + GameOverSubstate.animationSuffix); - } - } - - override function dance(force:Bool = false) - { - // Prevent default dancing behavior. - if (debugMode) - return; - - if (isDead) - return; - - if (!force) - { - if (getCurrentAnimation().startsWith("sing")) - { - return; - } - if (["hey", "cheer"].contains(getCurrentAnimation()) && !isAnimationFinished()) - { - return; - } - } - - // Prevent dancing while another animation is playing. - if (!force && getCurrentAnimation().startsWith("sing")) - { - return; - } - - // Otherwise, fallback to the super dance() method, which handles playing the idle animation. - super.dance(); - } - - /** - * Returns true if the player just pressed a note. - * Used when determing whether a the player character should revert to the `idle` animation. - * On non-player characters, this should be ignored. - */ - function justPressedNote(player:Int = 1):Bool - { - // Returns true if at least one of LEFT, DOWN, UP, or RIGHT is being held. - switch (player) - { - case 1: - return [ - PlayerSettings.player1.controls.NOTE_LEFT_P, - PlayerSettings.player1.controls.NOTE_DOWN_P, - PlayerSettings.player1.controls.NOTE_UP_P, - PlayerSettings.player1.controls.NOTE_RIGHT_P, - ].contains(true); - case 2: - return [ - PlayerSettings.player2.controls.NOTE_LEFT_P, - PlayerSettings.player2.controls.NOTE_DOWN_P, - PlayerSettings.player2.controls.NOTE_UP_P, - PlayerSettings.player2.controls.NOTE_RIGHT_P, - ].contains(true); - } - return false; - } - - /** - * Returns true if the player is holding a note. - * Used when determing whether a the player character should revert to the `idle` animation. - * On non-player characters, this should be ignored. - */ - function isHoldingNote(player:Int = 1):Bool - { - // Returns true if at least one of LEFT, DOWN, UP, or RIGHT is being held. - switch (player) - { - case 1: - return [ - PlayerSettings.player1.controls.NOTE_LEFT, - PlayerSettings.player1.controls.NOTE_DOWN, - PlayerSettings.player1.controls.NOTE_UP, - PlayerSettings.player1.controls.NOTE_RIGHT, - ].contains(true); - case 2: - return [ - PlayerSettings.player2.controls.NOTE_LEFT, - PlayerSettings.player2.controls.NOTE_DOWN, - PlayerSettings.player2.controls.NOTE_UP, - PlayerSettings.player2.controls.NOTE_RIGHT, - ].contains(true); - } - return false; - } - - /** - * Every time a note is hit, check if the note is from the same strumline. - * If it is, then play the sing animation. - */ - public override function onNoteHit(event:NoteScriptEvent) - { - super.onNoteHit(event); - - if (event.note.mustPress && characterType == BF) - { - // If the note is from the same strumline, play the sing animation. - this.playSingAnimation(event.note.data.dir, false); - holdTimer = 0; - } - else if (!event.note.mustPress && characterType == DAD) - { - // If the note is from the same strumline, play the sing animation. - this.playSingAnimation(event.note.data.dir, false); - holdTimer = 0; - } - } - - /** - * Every time a note is missed, check if the note is from the same strumline. - * If it is, then play the sing animation. - */ - public override function onNoteMiss(event:NoteScriptEvent) - { - super.onNoteMiss(event); - - if (event.note.mustPress && characterType == BF) - { - // If the note is from the same strumline, play the sing animation. - this.playSingAnimation(event.note.data.dir, true); - } - else if (!event.note.mustPress && characterType == DAD) - { - // If the note is from the same strumline, play the sing animation. - this.playSingAnimation(event.note.data.dir, true); - } - else if (event.note.mustPress && characterType == GF) - { - var dropAnim = ''; - - // Choose the combo drop anim to play. - // If there are several (for example, drop10 and drop50) the highest one will be used. - // If the combo count is too low, no animation will be played. - for (count in dropNoteCounts) - { - if (event.comboCount >= count) - { - dropAnim = 'drop${count}'; - } - } - - if (dropAnim != '') - { - trace('Playing GF combo drop animation: ${dropAnim}'); - this.playAnimation(dropAnim, true, true); - } - } - } - - /** - * Every time a wrong key is pressed, play the miss animation if we are Boyfriend. - */ - public override function onNoteGhostMiss(event:GhostMissNoteScriptEvent) - { - super.onNoteGhostMiss(event); - - if (event.eventCanceled || !event.playAnim) - { - // Skipping... - return; - } - - if (characterType == BF) - { - // If the note is from the same strumline, play the sing animation. - // trace('Playing ghost miss animation...'); - this.playSingAnimation(event.dir, true); - } - } - - public override function onDestroy(event:ScriptEvent):Void - { - this.characterType = OTHER; - } - - /** - * Play the appropriate singing animation, for the given note direction. - * @param dir The direction of the note. - * @param miss If true, play the miss animation instead of the sing animation. - * @param suffix A suffix to append to the animation name, like `alt`. - */ - public function playSingAnimation(dir:NoteDir, miss:Bool = false, suffix:String = ""):Void - { - var anim:String = 'sing${dir.nameUpper}${miss ? 'miss' : ''}${suffix != "" ? '-${suffix}' : ''}'; - - // restart even if already playing, because the character might sing the same note twice. - playAnimation(anim, true); - } + // Metadata about a character. + public var characterId(default, null):String; + public var characterName(default, null):String; + + /** + * Whether the player is an active character (Boyfriend) or not. + */ + public var characterType:CharacterType = OTHER; + + /** + * Tracks how long, in seconds, the character has been playing the current `sing` animation. + * This is used to ensure that characters play the `sing` animations for at least one beat, + * preventing them from reverting to the `idle` animation between notes. + */ + public var holdTimer:Float = 0; + + public var isDead:Bool = false; + public var debugMode:Bool = false; + + /** + * This character plays a given animation when hitting these specific combo numbers. + */ + public var comboNoteCounts(default, null):Array; + + /** + * This character plays a given animation when dropping combos larger than these numbers. + */ + public var dropNoteCounts(default, null):Array; + + final _data:CharacterData; + final singTimeCrochet:Float; + + /** + * The offset between the corner of the sprite and the origin of the sprite (at the character's feet). + * cornerPosition = stageData - characterOrigin + */ + public var characterOrigin(get, null):FlxPoint; + + function get_characterOrigin():FlxPoint + { + var xPos = (width / 2); // Horizontal center + var yPos = (height); // Vertical bottom + return new FlxPoint(xPos, yPos); + } + + /** + * The absolute position of the top-left of the character. + * @return + */ + public var cornerPosition(get, null):FlxPoint; + + function get_cornerPosition():FlxPoint + { + return new FlxPoint(x, y); + } + + /** + * The absolute position of the character's feet, at the bottom-center of the sprite. + */ + public var feetPosition(get, null):FlxPoint; + + function get_feetPosition():FlxPoint + { + return new FlxPoint(x + characterOrigin.x, y + characterOrigin.y); + } + + /** + * Returns the point the camera should focus on. + * Should be approximately centered on the character, and should not move based on the current animation. + * + * Set the position of this rather than reassigning it, so that anything referencing it will not be affected. + */ + public var cameraFocusPoint(default, null):FlxPoint = new FlxPoint(0, 0); + + override function set_animOffsets(value:Array) + { + if (animOffsets == null) value = [0, 0]; + if (animOffsets == value) return value; + + // Make sure animOffets are halved when scale is 0.5. + var xDiff = (animOffsets[0] * this.scale.x) - value[0]; + var yDiff = (animOffsets[1] * this.scale.y) - value[1]; + + // Call the super function so that camera focus point is not affected. + super.set_x(this.x + xDiff); + super.set_y(this.y + yDiff); + + return animOffsets = value; + } + + /** + * If the x position changes, other than via changing the animation offset, + * then we need to update the camera focus point. + */ + override function set_x(value:Float):Float + { + if (value == this.x) return value; + + var xDiff = value - this.x; + this.cameraFocusPoint.x += xDiff; + + return super.set_x(value); + } + + /** + * If the y position changes, other than via changing the animation offset, + * then we need to update the camera focus point. + */ + override function set_y(value:Float):Float + { + if (value == this.y) return value; + + var yDiff = value - this.y; + this.cameraFocusPoint.y += yDiff; + + return super.set_y(value); + } + + public function new(id:String) + { + super(); + this.characterId = id; + + _data = CharacterDataParser.fetchCharacterData(this.characterId); + if (_data == null) + { + throw 'Could not find character data for characterId: $characterId'; + } + else + { + this.characterName = _data.name; + this.singTimeCrochet = _data.singTime; + this.globalOffsets = _data.offsets; + this.flipX = _data.flipX; + } + + shouldBop = false; + } + + /** + * Gets the value of flipX from the character data. + * `!getFlipX()` is the direction Boyfriend should face. + */ + public function getDataFlipX():Bool + { + return _data.flipX; + } + + function findCountAnimations(prefix:String):Array + { + var animNames:Array = this.animation.getNameList(); + + var result:Array = []; + + for (anim in animNames) + { + if (anim.startsWith(prefix)) + { + var comboNum:Null = Std.parseInt(anim.substring(prefix.length)); + if (comboNum != null) + { + result.push(comboNum); + } + } + } + + // Sort numerically. + result.sort((a, b) -> a - b); + return result; + } + + /** + * Reset the character so it can be used at the start of the level. + * Call this when restarting the level. + */ + public function resetCharacter(resetCamera:Bool = true):Void + { + // Reset the animation offsets. This will modify x and y to be the absolute position of the character. + this.animOffsets = [0, 0]; + + // Now we can set the x and y to be their original values without having to account for animOffsets. + this.resetPosition(); + + // Make sure we are playing the idle animation (to reapply animOffsets)... + this.dance(true); // Force to avoid the old animation playing with the wrong offset at the start of the song. + // ...then update the hitbox so that this.width and this.height are correct. + this.updateHitbox(); + + // Reset the camera focus point while we're at it. + if (resetCamera) this.resetCameraFocusPoint(); + } + + /** + * Set the sprite scale to the appropriate value. + * @param scale + */ + function setScale(scale:Null):Void + { + if (scale == null) scale = 1.0; + + var feetPos:FlxPoint = feetPosition; + this.scale.x = scale; + this.scale.y = scale; + this.updateHitbox(); + // Reposition with newly scaled sprite. + this.x = feetPos.x - characterOrigin.x + globalOffsets[0]; + this.y = feetPos.y - characterOrigin.y + globalOffsets[1]; + } + + /** + * The per-character camera offset. + */ + var characterCameraOffsets(get, null):Array; + + function get_characterCameraOffsets():Array + { + return _data.cameraOffsets; + } + + override function onCreate(event:ScriptEvent):Void + { + // Make sure we are playing the idle animation... + this.dance(); + // ...then update the hitbox so that this.width and this.height are correct. + this.updateHitbox(); + // Without the above code, width and height (and therefore character position) + // will be based on the first animation in the sheet rather than the default animation. + + this.resetCameraFocusPoint(); + + // Child class should have created animations by now, + // so we can query which ones are available. + this.comboNoteCounts = findCountAnimations('combo'); // example: combo50 + this.dropNoteCounts = findCountAnimations('drop'); // example: drop50 + // trace('${this.animation.getNameList()}'); + // trace('Combo note counts: ' + this.comboNoteCounts); + // trace('Drop note counts: ' + this.dropNoteCounts); + + super.onCreate(event); + } + + function resetCameraFocusPoint():Void + { + // Calculate the camera focus point + var charCenterX = this.x + this.width / 2; + var charCenterY = this.y + this.height / 2; + this.cameraFocusPoint = new FlxPoint(charCenterX + _data.cameraOffsets[0], charCenterY + _data.cameraOffsets[1]); + } + + public function initHealthIcon(isOpponent:Bool):Void + { + if (!isOpponent) + { + if (PlayState.instance.iconP1 == null) + { + trace('[WARN] Player 1 health icon not found!'); + } + PlayState.instance.iconP1.characterId = _data.healthIcon.id; + PlayState.instance.iconP1.size.set(_data.healthIcon.scale, _data.healthIcon.scale); + PlayState.instance.iconP1.offset.x = _data.healthIcon.offsets[0]; + PlayState.instance.iconP1.offset.y = _data.healthIcon.offsets[1]; + PlayState.instance.iconP1.flipX = !_data.healthIcon.flipX; + } + else + { + if (PlayState.instance.iconP2 == null) + { + trace('[WARN] Player 2 health icon not found!'); + } + PlayState.instance.iconP2.characterId = _data.healthIcon.id; + PlayState.instance.iconP2.size.set(_data.healthIcon.scale, _data.healthIcon.scale); + PlayState.instance.iconP2.offset.x = _data.healthIcon.offsets[0]; + PlayState.instance.iconP2.offset.y = _data.healthIcon.offsets[1]; + PlayState.instance.iconP1.flipX = _data.healthIcon.flipX; + } + } + + public override function onUpdate(event:UpdateScriptEvent):Void + { + super.onUpdate(event); + + // Reset hold timer for each note pressed. + if (justPressedNote() && this.characterType == BF) + { + holdTimer = 0; + } + + if (isDead) + { + playDeathAnimation(); + return; + } + + if (hasAnimation('idle-hold') && getCurrentAnimation() == "idle" && isAnimationFinished()) playAnimation('idle-hold'); + if (hasAnimation('singLEFT-hold') && getCurrentAnimation() == "singLEFT" && isAnimationFinished()) playAnimation('singLEFT-hold'); + if (hasAnimation('singDOWN-hold') && getCurrentAnimation() == "singDOWN" && isAnimationFinished()) playAnimation('singDOWN-hold'); + if (hasAnimation('singUP-hold') && getCurrentAnimation() == "singUP" && isAnimationFinished()) playAnimation('singUP-hold'); + if (hasAnimation('singRIGHT-hold') && getCurrentAnimation() == "singRIGHT" && isAnimationFinished()) playAnimation('singRIGHT-hold'); + + // Handle character note hold time. + if (getCurrentAnimation().startsWith("sing")) + { + // TODO: Rework this code (and all character animations ugh) + // such that the hold time is handled by padding frames, + // and reverting to the idle animation is done when `isAnimationFinished()`. + // This lets you add frames to the end of the sing animation to ease back into the idle! + + holdTimer += event.elapsed; + var singTimeMs:Float = singTimeCrochet * (Conductor.crochet * 0.001); // x beats, to ms. + + if (getCurrentAnimation().endsWith("miss")) singTimeMs *= 2; // makes it feel more awkward when you miss + + // Without this check here, the player character would only play the `sing` animation + // for one beat, as opposed to holding it as long as the player is holding the button. + var shouldStopSinging:Bool = (this.characterType == BF) ? !isHoldingNote() : true; + + FlxG.watch.addQuick('singTimeMs-${characterId}', singTimeMs); + if (holdTimer > singTimeMs && shouldStopSinging) + { + // trace('holdTimer reached ${holdTimer}sec (> ${singTimeMs}), stopping sing animation'); + holdTimer = 0; + dance(true); + } + } + else + { + holdTimer = 0; + // super.onBeatHit handles the regular `dance()` calls. + } + FlxG.watch.addQuick('holdTimer-${characterId}', holdTimer); + } + + /** + * Since no `onBeatHit` or `dance` calls happen in GameOverSubstate, + * this regularly gets called instead. + */ + public function playDeathAnimation(force:Bool = false):Void + { + if (force || (getCurrentAnimation().startsWith("firstDeath") && isAnimationFinished())) + { + playAnimation("deathLoop" + GameOverSubstate.animationSuffix); + } + } + + override function dance(force:Bool = false) + { + // Prevent default dancing behavior. + if (debugMode) return; + + if (isDead) return; + + if (!force) + { + if (getCurrentAnimation().startsWith("sing")) + { + return; + } + if (["hey", "cheer"].contains(getCurrentAnimation()) && !isAnimationFinished()) + { + return; + } + } + + // Prevent dancing while another animation is playing. + if (!force && getCurrentAnimation().startsWith("sing")) + { + return; + } + + // Otherwise, fallback to the super dance() method, which handles playing the idle animation. + super.dance(); + } + + /** + * Returns true if the player just pressed a note. + * Used when determing whether a the player character should revert to the `idle` animation. + * On non-player characters, this should be ignored. + */ + function justPressedNote(player:Int = 1):Bool + { + // Returns true if at least one of LEFT, DOWN, UP, or RIGHT is being held. + switch (player) + { + case 1: + return [ + PlayerSettings.player1.controls.NOTE_LEFT_P, + PlayerSettings.player1.controls.NOTE_DOWN_P, + PlayerSettings.player1.controls.NOTE_UP_P, + PlayerSettings.player1.controls.NOTE_RIGHT_P, + ].contains(true); + case 2: + return [ + PlayerSettings.player2.controls.NOTE_LEFT_P, + PlayerSettings.player2.controls.NOTE_DOWN_P, + PlayerSettings.player2.controls.NOTE_UP_P, + PlayerSettings.player2.controls.NOTE_RIGHT_P, + ].contains(true); + } + return false; + } + + /** + * Returns true if the player is holding a note. + * Used when determing whether a the player character should revert to the `idle` animation. + * On non-player characters, this should be ignored. + */ + function isHoldingNote(player:Int = 1):Bool + { + // Returns true if at least one of LEFT, DOWN, UP, or RIGHT is being held. + switch (player) + { + case 1: + return [ + PlayerSettings.player1.controls.NOTE_LEFT, + PlayerSettings.player1.controls.NOTE_DOWN, + PlayerSettings.player1.controls.NOTE_UP, + PlayerSettings.player1.controls.NOTE_RIGHT, + ].contains(true); + case 2: + return [ + PlayerSettings.player2.controls.NOTE_LEFT, + PlayerSettings.player2.controls.NOTE_DOWN, + PlayerSettings.player2.controls.NOTE_UP, + PlayerSettings.player2.controls.NOTE_RIGHT, + ].contains(true); + } + return false; + } + + /** + * Every time a note is hit, check if the note is from the same strumline. + * If it is, then play the sing animation. + */ + public override function onNoteHit(event:NoteScriptEvent) + { + super.onNoteHit(event); + + if (event.note.mustPress && characterType == BF) + { + // If the note is from the same strumline, play the sing animation. + this.playSingAnimation(event.note.data.dir, false); + holdTimer = 0; + } + else if (!event.note.mustPress && characterType == DAD) + { + // If the note is from the same strumline, play the sing animation. + this.playSingAnimation(event.note.data.dir, false); + holdTimer = 0; + } + } + + /** + * Every time a note is missed, check if the note is from the same strumline. + * If it is, then play the sing animation. + */ + public override function onNoteMiss(event:NoteScriptEvent) + { + super.onNoteMiss(event); + + if (event.note.mustPress && characterType == BF) + { + // If the note is from the same strumline, play the sing animation. + this.playSingAnimation(event.note.data.dir, true); + } + else if (!event.note.mustPress && characterType == DAD) + { + // If the note is from the same strumline, play the sing animation. + this.playSingAnimation(event.note.data.dir, true); + } + else if (event.note.mustPress && characterType == GF) + { + var dropAnim = ''; + + // Choose the combo drop anim to play. + // If there are several (for example, drop10 and drop50) the highest one will be used. + // If the combo count is too low, no animation will be played. + for (count in dropNoteCounts) + { + if (event.comboCount >= count) + { + dropAnim = 'drop${count}'; + } + } + + if (dropAnim != '') + { + trace('Playing GF combo drop animation: ${dropAnim}'); + this.playAnimation(dropAnim, true, true); + } + } + } + + /** + * Every time a wrong key is pressed, play the miss animation if we are Boyfriend. + */ + public override function onNoteGhostMiss(event:GhostMissNoteScriptEvent) + { + super.onNoteGhostMiss(event); + + if (event.eventCanceled || !event.playAnim) + { + // Skipping... + return; + } + + if (characterType == BF) + { + // If the note is from the same strumline, play the sing animation. + // trace('Playing ghost miss animation...'); + this.playSingAnimation(event.dir, true); + } + } + + public override function onDestroy(event:ScriptEvent):Void + { + this.characterType = OTHER; + } + + /** + * Play the appropriate singing animation, for the given note direction. + * @param dir The direction of the note. + * @param miss If true, play the miss animation instead of the sing animation. + * @param suffix A suffix to append to the animation name, like `alt`. + */ + public function playSingAnimation(dir:NoteDir, miss:Bool = false, suffix:String = ""):Void + { + var anim:String = 'sing${dir.nameUpper}${miss ? 'miss' : ''}${suffix != "" ? '-${suffix}' : ''}'; + + // restart even if already playing, because the character might sing the same note twice. + playAnimation(anim, true); + } } enum CharacterType { - /** - * The BF character has the following behaviors. - * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. - * - When the player hits a note, plays the appropriate `singDIR` animation until BF is done singing. - * - If there is a `singDIR-end` animation, the `singDIR` animation will play once before looping the `singDIR-end` animation until BF is done singing. - * - If the player misses or hits a ghost note, plays the appropriate `singDIR-miss` animation until BF is done singing. - */ - BF; + /** + * The BF character has the following behaviors. + * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. + * - When the player hits a note, plays the appropriate `singDIR` animation until BF is done singing. + * - If there is a `singDIR-end` animation, the `singDIR` animation will play once before looping the `singDIR-end` animation until BF is done singing. + * - If the player misses or hits a ghost note, plays the appropriate `singDIR-miss` animation until BF is done singing. + */ + BF; - /** - * The DAD character has the following behaviors. - * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. - * - When the CPU hits a note, plays the appropriate `singDIR` animation until DAD is done singing. - * - If there is a `singDIR-end` animation, the `singDIR` animation will play once before looping the `singDIR-end` animation until DAD is done singing. - * - When the CPU misses a note (NOTE: This only happens via script, not by default), plays the appropriate `singDIR-miss` animation until DAD is done singing. - */ - DAD; + /** + * The DAD character has the following behaviors. + * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. + * - When the CPU hits a note, plays the appropriate `singDIR` animation until DAD is done singing. + * - If there is a `singDIR-end` animation, the `singDIR` animation will play once before looping the `singDIR-end` animation until DAD is done singing. + * - When the CPU misses a note (NOTE: This only happens via script, not by default), plays the appropriate `singDIR-miss` animation until DAD is done singing. + */ + DAD; - /** - * The GF character has the following behaviors. - * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. - * - If available, `combo###` animations will play when certain combo counts are reached. - * - For example, `combo50` will play when the player hits 50 notes in a row. - * - Multiple combo animations can be provided for different thresholds. - * - If available, `drop###` animations will play when combos are dropped above certain thresholds. - * - For example, `drop10` will play when the player drops a combo larger than 10. - * - Multiple drop animations can be provided for different thresholds (i.e. dropping larger combos). - * - No drop animation will play if one isn't applicable (i.e. if the combo count is too low). - */ - GF; + /** + * The GF character has the following behaviors. + * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. + * - If available, `combo###` animations will play when certain combo counts are reached. + * - For example, `combo50` will play when the player hits 50 notes in a row. + * - Multiple combo animations can be provided for different thresholds. + * - If available, `drop###` animations will play when combos are dropped above certain thresholds. + * - For example, `drop10` will play when the player drops a combo larger than 10. + * - Multiple drop animations can be provided for different thresholds (i.e. dropping larger combos). + * - No drop animation will play if one isn't applicable (i.e. if the combo count is too low). + */ + GF; - /** - * The OTHER character will only perform the `danceLeft`/`danceRight` or `idle` animation by default, depending on what's available. - * Additional behaviors can be performed via scripts. - */ - OTHER; + /** + * The OTHER character will only perform the `danceLeft`/`danceRight` or `idle` animation by default, depending on what's available. + * Additional behaviors can be performed via scripts. + */ + OTHER; } diff --git a/source/funkin/play/character/CharacterData.hx b/source/funkin/play/character/CharacterData.hx index 7dcbf9cf6..87cbd078b 100644 --- a/source/funkin/play/character/CharacterData.hx +++ b/source/funkin/play/character/CharacterData.hx @@ -362,12 +362,13 @@ class CharacterDataParser if (input.healthIcon == null) { - input.healthIcon = { - id: null, - scale: null, - flipX: null, - offsets: null - }; + input.healthIcon = + { + id: null, + scale: null, + flipX: null, + offsets: null + }; } if (input.healthIcon.id == null) diff --git a/source/funkin/play/character/MultiSparrowCharacter.hx b/source/funkin/play/character/MultiSparrowCharacter.hx index 2b539d6e3..98dda41d0 100644 --- a/source/funkin/play/character/MultiSparrowCharacter.hx +++ b/source/funkin/play/character/MultiSparrowCharacter.hx @@ -23,17 +23,17 @@ class MultiSparrowCharacter extends BaseCharacter /** * The actual group which holds all spritesheets this character uses. */ - private var members:Map = new Map(); + var members:Map = new Map(); /** * A map between animation names and what frame collection the animation should use. */ - private var animAssetPath:Map = new Map(); + var animAssetPath:Map = new Map(); /** * The current frame collection being used. */ - private var activeMember:String; + var activeMember:String; public function new(id:String) { @@ -179,8 +179,7 @@ class MultiSparrowCharacter extends BaseCharacter { // Make sure we ignore other animations if we're currently playing a forced one, // unless we're forcing a new animation. - if (!this.canPlayOtherAnims && !ignoreOther) - return; + if (!this.canPlayOtherAnims && !ignoreOther) return; loadFramesByAnimName(name); super.playAnimation(name, restart, ignoreOther); diff --git a/source/funkin/play/character/ScriptedCharacter.hx b/source/funkin/play/character/ScriptedCharacter.hx index 72c1d7477..2760cb42c 100644 --- a/source/funkin/play/character/ScriptedCharacter.hx +++ b/source/funkin/play/character/ScriptedCharacter.hx @@ -6,6 +6,8 @@ import funkin.play.character.SparrowCharacter; import polymod.hscript.HScriptedClass; /** + * A script that can be tied to a BaseCharacter, which persists across states. + * Create a scripted class that extends BaseCharacter to use this. * Note: Making a scripted class extending BaseCharacter is not recommended. * Do so ONLY if are handling all the character rendering yourself, * and can't use one of the built-in render modes. @@ -13,11 +15,26 @@ import polymod.hscript.HScriptedClass; @:hscriptClass class ScriptedBaseCharacter extends BaseCharacter implements HScriptedClass {} +/** + * A script that can be tied to a SparrowCharacter, which persists across states. + * Create a scripted class that extends SparrowCharacter, + * then call `super('charId')` in the constructor to use this. + */ @:hscriptClass class ScriptedSparrowCharacter extends SparrowCharacter implements HScriptedClass {} +/** + * A script that can be tied to a MultiSparrowCharacter, which persists across states. + * Create a scripted class that extends MultiSparrowCharacter, + * then call `super('charId')` in the constructor to use this. + */ @:hscriptClass class ScriptedMultiSparrowCharacter extends MultiSparrowCharacter implements HScriptedClass {} +/** + * A script that can be tied to a PackerCharacter, which persists across states. + * Create a scripted class that extends PackerCharacter, + * then call `super('charId')` in the constructor to use this. + */ @:hscriptClass class ScriptedPackerCharacter extends PackerCharacter implements HScriptedClass {} diff --git a/source/funkin/play/event/FocusCameraSongEvent.hx b/source/funkin/play/event/FocusCameraSongEvent.hx index cc8f52164..e674a1e24 100644 --- a/source/funkin/play/event/FocusCameraSongEvent.hx +++ b/source/funkin/play/event/FocusCameraSongEvent.hx @@ -50,20 +50,16 @@ class FocusCameraSongEvent extends SongEvent public override function handleEvent(data:SongEventData) { // Does nothing if there is no PlayState camera or stage. - if (PlayState.instance == null || PlayState.instance.currentStage == null) - return; + if (PlayState.instance == null || PlayState.instance.currentStage == null) return; var posX = data.getFloat('x'); - if (posX == null) - posX = 0.0; + if (posX == null) posX = 0.0; var posY = data.getFloat('y'); - if (posY == null) - posY = 0.0; + if (posY == null) posY = 0.0; var char = data.getInt('char'); - if (char == null) - char = cast data.value; + if (char == null) char = cast data.value; switch (char) { diff --git a/source/funkin/play/event/PlayAnimationSongEvent.hx b/source/funkin/play/event/PlayAnimationSongEvent.hx index fcf246d57..73937e61a 100644 --- a/source/funkin/play/event/PlayAnimationSongEvent.hx +++ b/source/funkin/play/event/PlayAnimationSongEvent.hx @@ -15,14 +15,12 @@ class PlayAnimationSongEvent extends SongEvent public override function handleEvent(data:SongEventData) { // Does nothing if there is no PlayState camera or stage. - if (PlayState.instance == null || PlayState.instance.currentStage == null) - return; + if (PlayState.instance == null || PlayState.instance.currentStage == null) return; var targetName = data.getString('target'); var anim = data.getString('anim'); var force = data.getBool('force'); - if (force == null) - force = false; + if (force == null) force = false; var target:FlxSprite = null; @@ -51,8 +49,7 @@ class PlayAnimationSongEvent extends SongEvent target = PlayState.instance.currentStage.getGirlfriend(); default: target = PlayState.instance.currentStage.getNamedProp(targetName); - if (target == null) - trace('Unknown animation target: $targetName'); + if (target == null) trace('Unknown animation target: $targetName'); else trace('Fetched animation target $targetName from stage.'); } diff --git a/source/funkin/play/event/ScriptedSongEvent.hx b/source/funkin/play/event/ScriptedSongEvent.hx index 079e35110..6f5e1c9bc 100644 --- a/source/funkin/play/event/ScriptedSongEvent.hx +++ b/source/funkin/play/event/ScriptedSongEvent.hx @@ -3,7 +3,14 @@ package funkin.play.event; import funkin.play.song.Song; import polymod.hscript.HScriptedClass; +/** + * A script that can be tied to a SongEvent. + * Create a scripted class that extends SongEvent, + * then call `super('SongEventType')` to use this. + * + * - Remember to override `handleEvent(data:SongEventData)` to perform your actions when the event is hit. + * - Remember to override `getTitle()` to return an event name that will be displayed in the editor. + * - Remember to override `getEventSchema()` to return a schema for the event data, used to build a form in the chart editor. + */ @:hscriptClass -class ScriptedSongEvent extends SongEvent implements HScriptedClass -{ -} +class ScriptedSongEvent extends SongEvent implements HScriptedClass {} diff --git a/source/funkin/play/event/SongEvent.hx b/source/funkin/play/event/SongEvent.hx index a06cfb23a..4071f9a34 100644 --- a/source/funkin/play/event/SongEvent.hx +++ b/source/funkin/play/event/SongEvent.hx @@ -9,6 +9,9 @@ import funkin.play.song.SongData.SongEventData; */ class SongEvent { + /** + * The internal song event ID that this handler is responsible for. + */ public var id:String; public function new(id:String) @@ -16,16 +19,29 @@ class SongEvent this.id = id; } - public function handleEvent(data:SongEventData) + /** + * Handles a song event that matches this handler's ID. + * @param data The data associated with the event. + */ + public function handleEvent(data:SongEventData):Void { throw 'SongEvent.handleEvent() must be overridden!'; } + /** + * Retrieves the chart editor schema for this song event type. + * @return The schema, or null if this event type does not have a schema. + */ public function getEventSchema():SongEventSchema { return null; } + /** + * Retrieves the human readable title of this song event type. + * Used for the chart editor. + * @return The title. + */ public function getTitle():String { return this.id.toTitleCase(); @@ -37,13 +53,16 @@ class SongEvent } } +/** + * This class statically handles the parsing of internal and scripted song event handlers. + */ class SongEventParser { /** * Every built-in event class must be added to this list. * Thankfully, with the power of `SongEventMacro`, this is done automatically. */ - private static final BUILTIN_EVENTS:List> = ClassMacro.listSubclassesOf(SongEvent); + static final BUILTIN_EVENTS:List> = ClassMacro.listSubclassesOf(SongEvent); /** * Map of internal handlers for song events. @@ -68,8 +87,7 @@ class SongEventParser for (eventCls in BUILTIN_EVENTS) { var eventClsName:String = Type.getClassName(eventCls); - if (eventClsName == 'funkin.play.event.SongEvent' || eventClsName == 'funkin.play.event.ScriptedSongEvent') - continue; + if (eventClsName == 'funkin.play.event.SongEvent' || eventClsName == 'funkin.play.event.ScriptedSongEvent') continue; var event:SongEvent = Type.createInstance(eventCls, ["UNKNOWN"]); @@ -88,8 +106,7 @@ class SongEventParser static function registerScriptedEvents() { var scriptedEventClassNames:Array = ScriptedSongEvent.listScriptClasses(); - if (scriptedEventClassNames == null || scriptedEventClassNames.length == 0) - return; + if (scriptedEventClassNames == null || scriptedEventClassNames.length == 0) return; trace('Instantiating ${scriptedEventClassNames.length} scripted song events...'); for (eventCls in scriptedEventClassNames) @@ -126,8 +143,7 @@ class SongEventParser public static function getEventSchema(id:String):SongEventSchema { var event:SongEvent = getEvent(id); - if (event == null) - return null; + if (event == null) return null; return event.getEventSchema(); } @@ -171,12 +187,10 @@ class SongEventParser return events.filter(function(event:SongEventData):Bool { // If the event is already activated, don't activate it again. - if (event.activated) - return false; + if (event.activated) return false; // If the event is in the future, don't activate it. - if (event.time > currentTime) - return false; + if (event.time > currentTime) return false; return true; }); diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index 88f52ec57..1e2ff28bb 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -1,198 +1,259 @@ package funkin.play.scoring; -enum abstract ScoringSystem(String) { - /** - * The scoring system used in versions of the game Week 6 and older. - * Scores the player based on judgement, represented by a step function. - */ - var LEGACY; - /** - * The scoring system used in Week 7. It has tighter scoring windows than Legacy. - * Scores the player based on judgement, represented by a step function. - */ - var WEEK7; - /** - * Points Based On Timing scoring system, version 1 - * Scores the player based on the offset based on timing, represented by a sigmoid function. - */ - var PBOT1; - // WIFE1 - // WIFE3 +enum abstract ScoringSystem(String) +{ + /** + * The scoring system used in versions of the game Week 6 and older. + * Scores the player based on judgement, represented by a step function. + */ + var LEGACY; + + /** + * The scoring system used in Week 7. It has tighter scoring windows than Legacy. + * Scores the player based on judgement, represented by a step function. + */ + var WEEK7; + + /** + * Points Based On Timing scoring system, version 1 + * Scores the player based on the offset based on timing, represented by a sigmoid function. + */ + var PBOT1; + + // WIFE1 + // WIFE3 } /** * A static class which holds any functions related to scoring. */ -class Scoring { - /** - * Determine the score a note receives under a given scoring system. - * @param msTiming The difference between the note's time and when it was hit. - * @param scoringSystem The scoring system to use. - * @return The score the note receives. - */ - public static function scoreNote(msTiming:Float, scoringSystem:ScoringSystem = PBOT1) { - switch (scoringSystem) { - case LEGACY: - return scoreNote_LEGACY(msTiming); - case WEEK7: - return scoreNote_WEEK7(msTiming); - case PBOT1: - return scoreNote_PBOT1(msTiming); - default: - trace('ERROR: Unknown scoring system: ' + scoringSystem); - return 0; - } +class Scoring +{ + /** + * Determine the score a note receives under a given scoring system. + * @param msTiming The difference between the note's time and when it was hit. + * @param scoringSystem The scoring system to use. + * @return The score the note receives. + */ + public static function scoreNote(msTiming:Float, scoringSystem:ScoringSystem = PBOT1) + { + switch (scoringSystem) + { + case LEGACY: + return scoreNote_LEGACY(msTiming); + case WEEK7: + return scoreNote_WEEK7(msTiming); + case PBOT1: + return scoreNote_PBOT1(msTiming); + default: + trace('ERROR: Unknown scoring system: ' + scoringSystem); + return 0; } + } - /** - * Determine the judgement a note receives under a given scoring system. - * @param msTiming The difference between the note's time and when it was hit. - * @return The judgement the note receives. - */ - public static function judgeNote(msTiming:Float, scoringSystem:ScoringSystem = PBOT1):String { - switch (scoringSystem) { - case LEGACY: - return judgeNote_LEGACY(msTiming); - case WEEK7: - return judgeNote_WEEK7(msTiming); - case PBOT1: - return judgeNote_PBOT1(msTiming); - default: - trace('ERROR: Unknown scoring system: ' + scoringSystem); - return 'miss'; - } - } - - /** - * The maximum score received. - */ - public static var PBOT1_MAX_SCORE = 350; - /** - * The minimum score received. - */ - public static var PBOT1_MIN_SCORE = 0; - /** - * The threshold at which a note hit is considered perfect and always given the max score. - **/ - public static var PBOT1_PERFECT_THRESHOLD = 5.0; // 5ms. - /** - * The threshold at which a note hit is considered missed and always given the min score. - **/ - public static var PBOT1_MISS_THRESHOLD = (10/60) * 1000; // ~166ms - - // Magic numbers used to tweak the shape of the scoring function. - public static var PBOT1_SCORING_SLOPE:Float = 0.052; - public static var PBOT1_SCORING_OFFSET:Float = 80.0; - - static function scoreNote_PBOT1(msTiming:Float):Int { - // Absolute value because otherwise late hits are always given the max score. - var absTiming = Math.abs(msTiming); - if (absTiming > PBOT1_MISS_THRESHOLD) { - return PBOT1_MIN_SCORE; - } else if (absTiming < PBOT1_PERFECT_THRESHOLD) { - return PBOT1_MAX_SCORE; - } else { - // Calculate the score based on the timing using a sigmoid function. - var factor:Float = 1.0 - (1.0 / (1.0 + Math.exp(-PBOT1_SCORING_SLOPE * (absTiming - PBOT1_SCORING_OFFSET)))); - - var score = Std.int(PBOT1_MAX_SCORE * factor); - - return score; - } - } - - static function judgeNote_PBOT1(msTiming:Float):String { + /** + * Determine the judgement a note receives under a given scoring system. + * @param msTiming The difference between the note's time and when it was hit. + * @return The judgement the note receives. + */ + public static function judgeNote(msTiming:Float, scoringSystem:ScoringSystem = PBOT1):String + { + switch (scoringSystem) + { + case LEGACY: + return judgeNote_LEGACY(msTiming); + case WEEK7: return judgeNote_WEEK7(msTiming); + case PBOT1: + return judgeNote_PBOT1(msTiming); + default: + trace('ERROR: Unknown scoring system: ' + scoringSystem); + return 'miss'; } + } - /** - * The window of time in which a note is considered to be hit, on the Funkin Legacy scoring system. - * Currently equal to 10 frames at 60fps, or ~166ms. - */ - public static var LEGACY_HIT_WINDOW:Float = (10 / 60) * 1000; // 166.67 ms hit window (10 frames at 60fps) - /** - * The threshold at which a note is considered a "Bad" hit rather than a "Shit" hit. - * Represented as a percentage of the total hit window. - */ - public static var LEGACY_BAD_THRESHOLD:Float = 0.9; - public static var LEGACY_GOOD_THRESHOLD:Float = 0.75; - public static var LEGACY_SICK_THRESHOLD:Float = 0.2; - public static var LEGACY_SHIT_SCORE = 50; - public static var LEGACY_BAD_SCORE = 100; - public static var LEGACY_GOOD_SCORE = 200; - public static var LEGACY_SICK_SCORE = 350; + /** + * The maximum score received. + */ + public static var PBOT1_MAX_SCORE = 350; - static function scoreNote_LEGACY(msTiming:Float):Int { - var absTiming = Math.abs(msTiming); - if (absTiming < LEGACY_HIT_WINDOW * LEGACY_SICK_THRESHOLD) { - return LEGACY_SICK_SCORE; - } else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_GOOD_THRESHOLD) { - return LEGACY_GOOD_SCORE; - } else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_BAD_THRESHOLD) { - return LEGACY_BAD_SCORE; - } else if (absTiming < LEGACY_HIT_WINDOW) { - return LEGACY_SHIT_SCORE; - } else { - return 0; - } + /** + * The minimum score received. + */ + public static var PBOT1_MIN_SCORE = 0; + + /** + * The threshold at which a note hit is considered perfect and always given the max score. + **/ + public static var PBOT1_PERFECT_THRESHOLD = 5.0; // 5ms. + + /** + * The threshold at which a note hit is considered missed and always given the min score. + **/ + public static var PBOT1_MISS_THRESHOLD = (10 / 60) * 1000; // ~166ms + + // Magic numbers used to tweak the shape of the scoring function. + public static var PBOT1_SCORING_SLOPE:Float = 0.052; + public static var PBOT1_SCORING_OFFSET:Float = 80.0; + + static function scoreNote_PBOT1(msTiming:Float):Int + { + // Absolute value because otherwise late hits are always given the max score. + var absTiming = Math.abs(msTiming); + if (absTiming > PBOT1_MISS_THRESHOLD) + { + return PBOT1_MIN_SCORE; } - - static function judgeNote_LEGACY(msTiming:Float):String { - var absTiming = Math.abs(msTiming); - if (absTiming < LEGACY_HIT_WINDOW * LEGACY_SICK_THRESHOLD) { - return 'sick'; - } else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_GOOD_THRESHOLD) { - return 'good'; - } else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_BAD_THRESHOLD) { - return 'bad'; - } else if (absTiming < LEGACY_HIT_WINDOW) { - return 'shit'; - } else { - return 'miss'; - } + else if (absTiming < PBOT1_PERFECT_THRESHOLD) + { + return PBOT1_MAX_SCORE; } + else + { + // Calculate the score based on the timing using a sigmoid function. + var factor:Float = 1.0 - (1.0 / (1.0 + Math.exp(-PBOT1_SCORING_SLOPE * (absTiming - PBOT1_SCORING_OFFSET)))); - /** - * The window of time in which a note is considered to be hit, on the Funkin Classic scoring system. - * Same as L 10 frames at 60fps, or ~166ms. - */ - public static var WEEK7_HIT_WINDOW = LEGACY_HIT_WINDOW; - public static var WEEK7_BAD_THRESHOLD = 0.8; // 80% of the hit window, or ~125ms - public static var WEEK7_GOOD_THRESHOLD = 0.55; // 55% of the hit window, or ~91ms - public static var WEEK7_SICK_THRESHOLD = 0.2; // 20% of the hit window, or ~33ms - public static var WEEK7_SHIT_SCORE = 50; - public static var WEEK7_BAD_SCORE = 100; - public static var WEEK7_GOOD_SCORE = 200; - public static var WEEK7_SICK_SCORE = 350; + var score = Std.int(PBOT1_MAX_SCORE * factor); - static function scoreNote_WEEK7(msTiming:Float):Int { - var absTiming = Math.abs(msTiming); - if (absTiming < WEEK7_HIT_WINDOW * WEEK7_SICK_THRESHOLD) { - return WEEK7_SICK_SCORE; - } else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_GOOD_THRESHOLD) { - return WEEK7_GOOD_SCORE; - } else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_BAD_THRESHOLD) { - return WEEK7_BAD_SCORE; - } else if (absTiming < WEEK7_HIT_WINDOW) { - return WEEK7_SHIT_SCORE; - } else { - return 0; - } + return score; } + } - static function judgeNote_WEEK7(msTiming:Float):String { - var absTiming = Math.abs(msTiming); - if (absTiming < WEEK7_HIT_WINDOW * WEEK7_SICK_THRESHOLD) { - return 'sick'; - } else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_GOOD_THRESHOLD) { - return 'good'; - } else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_BAD_THRESHOLD) { - return 'bad'; - } else if (absTiming < WEEK7_HIT_WINDOW) { - return 'shit'; - } else { - return 'miss'; - } + static function judgeNote_PBOT1(msTiming:Float):String + { + return judgeNote_WEEK7(msTiming); + } + + /** + * The window of time in which a note is considered to be hit, on the Funkin Legacy scoring system. + * Currently equal to 10 frames at 60fps, or ~166ms. + */ + public static var LEGACY_HIT_WINDOW:Float = (10 / 60) * 1000; // 166.67 ms hit window (10 frames at 60fps) + + /** + * The threshold at which a note is considered a "Bad" hit rather than a "Shit" hit. + * Represented as a percentage of the total hit window. + */ + public static var LEGACY_BAD_THRESHOLD:Float = 0.9; + + public static var LEGACY_GOOD_THRESHOLD:Float = 0.75; + public static var LEGACY_SICK_THRESHOLD:Float = 0.2; + public static var LEGACY_SHIT_SCORE = 50; + public static var LEGACY_BAD_SCORE = 100; + public static var LEGACY_GOOD_SCORE = 200; + public static var LEGACY_SICK_SCORE = 350; + + static function scoreNote_LEGACY(msTiming:Float):Int + { + var absTiming = Math.abs(msTiming); + if (absTiming < LEGACY_HIT_WINDOW * LEGACY_SICK_THRESHOLD) + { + return LEGACY_SICK_SCORE; } + else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_GOOD_THRESHOLD) + { + return LEGACY_GOOD_SCORE; + } + else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_BAD_THRESHOLD) + { + return LEGACY_BAD_SCORE; + } + else if (absTiming < LEGACY_HIT_WINDOW) + { + return LEGACY_SHIT_SCORE; + } + else + { + return 0; + } + } + + static function judgeNote_LEGACY(msTiming:Float):String + { + var absTiming = Math.abs(msTiming); + if (absTiming < LEGACY_HIT_WINDOW * LEGACY_SICK_THRESHOLD) + { + return 'sick'; + } + else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_GOOD_THRESHOLD) + { + return 'good'; + } + else if (absTiming < LEGACY_HIT_WINDOW * LEGACY_BAD_THRESHOLD) + { + return 'bad'; + } + else if (absTiming < LEGACY_HIT_WINDOW) + { + return 'shit'; + } + else + { + return 'miss'; + } + } + + /** + * The window of time in which a note is considered to be hit, on the Funkin Classic scoring system. + * Same as L 10 frames at 60fps, or ~166ms. + */ + public static var WEEK7_HIT_WINDOW = LEGACY_HIT_WINDOW; + + public static var WEEK7_BAD_THRESHOLD = 0.8; // 80% of the hit window, or ~125ms + public static var WEEK7_GOOD_THRESHOLD = 0.55; // 55% of the hit window, or ~91ms + public static var WEEK7_SICK_THRESHOLD = 0.2; // 20% of the hit window, or ~33ms + public static var WEEK7_SHIT_SCORE = 50; + public static var WEEK7_BAD_SCORE = 100; + public static var WEEK7_GOOD_SCORE = 200; + public static var WEEK7_SICK_SCORE = 350; + + static function scoreNote_WEEK7(msTiming:Float):Int + { + var absTiming = Math.abs(msTiming); + if (absTiming < WEEK7_HIT_WINDOW * WEEK7_SICK_THRESHOLD) + { + return WEEK7_SICK_SCORE; + } + else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_GOOD_THRESHOLD) + { + return WEEK7_GOOD_SCORE; + } + else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_BAD_THRESHOLD) + { + return WEEK7_BAD_SCORE; + } + else if (absTiming < WEEK7_HIT_WINDOW) + { + return WEEK7_SHIT_SCORE; + } + else + { + return 0; + } + } + + static function judgeNote_WEEK7(msTiming:Float):String + { + var absTiming = Math.abs(msTiming); + if (absTiming < WEEK7_HIT_WINDOW * WEEK7_SICK_THRESHOLD) + { + return 'sick'; + } + else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_GOOD_THRESHOLD) + { + return 'good'; + } + else if (absTiming < WEEK7_HIT_WINDOW * WEEK7_BAD_THRESHOLD) + { + return 'bad'; + } + else if (absTiming < WEEK7_HIT_WINDOW) + { + return 'shit'; + } + else + { + return 'miss'; + } + } } - diff --git a/source/funkin/play/song/ScriptedSong.hx b/source/funkin/play/song/ScriptedSong.hx index 600b4f9bc..35cd80014 100644 --- a/source/funkin/play/song/ScriptedSong.hx +++ b/source/funkin/play/song/ScriptedSong.hx @@ -1,9 +1,8 @@ package funkin.play.song; -import funkin.play.song.Song; -import polymod.hscript.HScriptedClass; - +/** + * A script that can be tied to a Song. + * Create a scripted class that extends Song to use this. + */ @:hscriptClass -class ScriptedSong extends Song implements HScriptedClass -{ -} +class ScriptedSong extends funkin.play.song.Song implements polymod.hscript.HScriptedClass {} diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index f15f4dafb..5cd4d1589 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -129,8 +129,7 @@ class Song // implements IPlayStateScriptedClass */ public inline function getDifficulty(?diffId:String):SongDifficulty { - if (diffId == null) - diffId = difficulties.keys().array()[0]; + if (diffId == null) diffId = difficulties.keys().array()[0]; return difficulties.get(diffId); } diff --git a/source/funkin/play/song/SongData.hx b/source/funkin/play/song/SongData.hx index 480c3aab5..3666885bd 100644 --- a/source/funkin/play/song/SongData.hx +++ b/source/funkin/play/song/SongData.hx @@ -235,30 +235,33 @@ abstract SongMetadata(RawSongMetadata) { public function new(songName:String, artist:String, variation:String = 'default') { - this = { - version: SongMigrator.CHART_VERSION, - songName: songName, - artist: artist, - timeFormat: 'ms', - divisions: 96, - timeChanges: [new SongTimeChange(-1, 0, 100, 4, 4, [4, 4, 4, 4])], - loop: false, - playData: { - songVariations: [], - difficulties: ['normal'], + this = + { + version: SongMigrator.CHART_VERSION, + songName: songName, + artist: artist, + timeFormat: 'ms', + divisions: 96, + timeChanges: [new SongTimeChange(-1, 0, 100, 4, 4, [4, 4, 4, 4])], + loop: false, + playData: + { + songVariations: [], + difficulties: ['normal'], - playableChars: { - bf: new SongPlayableChar('gf', 'dad'), - }, + playableChars: + { + bf: new SongPlayableChar('gf', 'dad'), + }, - stage: 'mainStage', - noteSkin: 'Normal' - }, - generatedBy: SongValidator.DEFAULT_GENERATEDBY, + stage: 'mainStage', + noteSkin: 'Normal' + }, + generatedBy: SongValidator.DEFAULT_GENERATEDBY, - // Variation ID. - variation: variation - }; + // Variation ID. + variation: variation + }; } public function clone(?newVariation:String = null):SongMetadata @@ -330,12 +333,13 @@ abstract SongNoteData(RawSongNoteData) { public function new(time:Float, data:Int, length:Float = 0, kind:String = "") { - this = { - t: time, - d: data, - l: length, - k: kind - }; + this = + { + t: time, + d: data, + l: length, + k: kind + }; } public var time(get, set):Float; @@ -433,25 +437,21 @@ abstract SongNoteData(RawSongNoteData) public function get_kind():String { - if (this.k == null || this.k == '') - return 'normal'; + if (this.k == null || this.k == '') return 'normal'; return this.k; } public function set_kind(value:String):String { - if (value == 'normal' || value == '') - value = null; + if (value == 'normal' || value == '') value = null; return this.k = value; } @:op(A == B) public function op_equals(other:SongNoteData):Bool { - if (this.k == '') - if (other.kind != '' && other.kind != 'normal') - return false; + if (this.k == '') if (other.kind != '' && other.kind != 'normal') return false; return this.t == other.time && this.d == other.data && this.l == other.length; } @@ -519,12 +519,13 @@ abstract SongEventData(RawSongEventData) { public function new(time:Float, event:String, value:Dynamic = null) { - this = { - t: time, - e: event, - v: value, - a: false - }; + this = + { + t: time, + e: event, + v: value, + a: false + }; } public var time(get, set):Float; @@ -659,11 +660,12 @@ abstract SongPlayableChar(RawSongPlayableChar) { public function new(girlfriend:String, opponent:String, inst:String = "") { - this = { - g: girlfriend, - o: opponent, - i: inst - }; + this = + { + g: girlfriend, + o: opponent, + i: inst + }; } public var girlfriend(get, set):String; @@ -718,26 +720,28 @@ abstract SongChartData(RawSongChartData) { public function new(scrollSpeed:Float, events:Array, notes:Array) { - this = { - version: SongMigrator.CHART_VERSION, + this = + { + version: SongMigrator.CHART_VERSION, - events: events, - notes: { - normal: notes - }, - scrollSpeed: { - normal: scrollSpeed - }, - generatedBy: SongValidator.DEFAULT_GENERATEDBY - } + events: events, + notes: + { + normal: notes + }, + scrollSpeed: + { + normal: scrollSpeed + }, + generatedBy: SongValidator.DEFAULT_GENERATEDBY + } } public function getScrollSpeed(diff:String = 'default'):Float { var result:Float = this.scrollSpeed.get(diff); - if (result == 0.0 && diff != 'default') - return getScrollSpeed('default'); + if (result == 0.0 && diff != 'default') return getScrollSpeed('default'); return (result == 0.0) ? 1.0 : result; } @@ -788,14 +792,15 @@ abstract SongTimeChange(RawSongTimeChange) { public function new(timeStamp:Float, beatTime:Int, bpm:Float, timeSignatureNum:Int = 4, timeSignatureDen:Int = 4, beatTuplets:Array) { - this = { - t: timeStamp, - b: beatTime, - bpm: bpm, - n: timeSignatureNum, - d: timeSignatureDen, - bt: beatTuplets, - } + this = + { + t: timeStamp, + b: beatTime, + bpm: bpm, + n: timeSignatureNum, + d: timeSignatureDen, + bt: beatTuplets, + } } public var timeStamp(get, set):Float; diff --git a/source/funkin/play/song/SongDataUtils.hx b/source/funkin/play/song/SongDataUtils.hx index 834aaa64f..27625e846 100644 --- a/source/funkin/play/song/SongDataUtils.hx +++ b/source/funkin/play/song/SongDataUtils.hx @@ -10,234 +10,230 @@ using Lambda; class SongDataUtils { - /** - * Given an array of SongNoteData objects, return a new array of SongNoteData objects - * whose timestamps are shifted by the given amount. - * Does not mutate the original array. - * - * @param notes The notes to modify. - * @param offset The time difference to apply in milliseconds. - */ - public static function offsetSongNoteData(notes:Array, offset:Int):Array - { - return notes.map(function(note:SongNoteData):SongNoteData - { - return new SongNoteData(note.time + offset, note.data, note.length, note.kind); - }); - } + /** + * Given an array of SongNoteData objects, return a new array of SongNoteData objects + * whose timestamps are shifted by the given amount. + * Does not mutate the original array. + * + * @param notes The notes to modify. + * @param offset The time difference to apply in milliseconds. + */ + public static function offsetSongNoteData(notes:Array, offset:Int):Array + { + return notes.map(function(note:SongNoteData):SongNoteData + { + return new SongNoteData(note.time + offset, note.data, note.length, note.kind); + }); + } - /** - * Given an array of SongEventData objects, return a new array of SongEventData objects - * whose timestamps are shifted by the given amount. - * Does not mutate the original array. - * - * @param events The events to modify. - * @param offset The time difference to apply in milliseconds. - */ - public static function offsetSongEventData(events:Array, offset:Int):Array - { - return events.map(function(event:SongEventData):SongEventData - { - return new SongEventData(event.time + offset, event.event, event.value); - }); - } + /** + * Given an array of SongEventData objects, return a new array of SongEventData objects + * whose timestamps are shifted by the given amount. + * Does not mutate the original array. + * + * @param events The events to modify. + * @param offset The time difference to apply in milliseconds. + */ + public static function offsetSongEventData(events:Array, offset:Int):Array + { + return events.map(function(event:SongEventData):SongEventData + { + return new SongEventData(event.time + offset, event.event, event.value); + }); + } - /** - * Return a new array without a certain subset of notes from an array of SongNoteData objects. - * Does not mutate the original array. - * - * @param notes The array of notes to be subtracted from. - * @param subtrahend The notes to remove from the `notes` array. Yes, subtrahend is a real word. - */ - public static function subtractNotes(notes:Array, subtrahend:Array) - { - if (notes.length == 0 || subtrahend.length == 0) - return notes; + /** + * Return a new array without a certain subset of notes from an array of SongNoteData objects. + * Does not mutate the original array. + * + * @param notes The array of notes to be subtracted from. + * @param subtrahend The notes to remove from the `notes` array. Yes, subtrahend is a real word. + */ + public static function subtractNotes(notes:Array, subtrahend:Array) + { + if (notes.length == 0 || subtrahend.length == 0) return notes; - var result = notes.filter(function(note:SongNoteData):Bool - { - for (x in subtrahend) - // SongNoteData's == operation has been overridden so that this will work. - if (x == note) - return false; + var result = notes.filter(function(note:SongNoteData):Bool + { + for (x in subtrahend) + // SongNoteData's == operation has been overridden so that this will work. + if (x == note) return false; - return true; - }); + return true; + }); - return result; - } + return result; + } - /** - * Return a new array without a certain subset of events from an array of SongEventData objects. - * Does not mutate the original array. - * - * @param events The array of events to be subtracted from. - * @param subtrahend The events to remove from the `events` array. Yes, subtrahend is a real word. - */ - public static function subtractEvents(events:Array, subtrahend:Array) - { - if (events.length == 0 || subtrahend.length == 0) - return events; + /** + * Return a new array without a certain subset of events from an array of SongEventData objects. + * Does not mutate the original array. + * + * @param events The array of events to be subtracted from. + * @param subtrahend The events to remove from the `events` array. Yes, subtrahend is a real word. + */ + public static function subtractEvents(events:Array, subtrahend:Array) + { + if (events.length == 0 || subtrahend.length == 0) return events; - return events.filter(function(event:SongEventData):Bool - { - // SongEventData's == operation has been overridden so that this will work. - return !subtrahend.has(event); - }); - } + return events.filter(function(event:SongEventData):Bool + { + // SongEventData's == operation has been overridden so that this will work. + return !subtrahend.has(event); + }); + } - /** - * Create an array of notes whose note data is flipped (player becomes opponent and vice versa) - * Does not mutate the original array. - */ - public static function flipNotes(notes:Array, ?strumlineSize:Int = 4):Array - { - return notes.map(function(note:SongNoteData):SongNoteData - { - var newData = note.data; + /** + * Create an array of notes whose note data is flipped (player becomes opponent and vice versa) + * Does not mutate the original array. + */ + public static function flipNotes(notes:Array, ?strumlineSize:Int = 4):Array + { + return notes.map(function(note:SongNoteData):SongNoteData + { + var newData = note.data; - if (newData < strumlineSize) - newData += strumlineSize; - else - newData -= strumlineSize; + if (newData < strumlineSize) newData += strumlineSize; + else + newData -= strumlineSize; - return new SongNoteData(note.time, newData, note.length, note.kind); - }); - } + return new SongNoteData(note.time, newData, note.length, note.kind); + }); + } - /** - * Prepare an array of notes to be used as the clipboard data. - * - * Offset the provided array of notes such that the first note is at 0 milliseconds. - */ - public static function buildNoteClipboard(notes:Array):Array - { - return offsetSongNoteData(sortNotes(notes), -Std.int(notes[0].time)); - } + /** + * Prepare an array of notes to be used as the clipboard data. + * + * Offset the provided array of notes such that the first note is at 0 milliseconds. + */ + public static function buildNoteClipboard(notes:Array):Array + { + return offsetSongNoteData(sortNotes(notes), -Std.int(notes[0].time)); + } - /** - * Prepare an array of events to be used as the clipboard data. - * - * Offset the provided array of events such that the first event is at 0 milliseconds. - */ - public static function buildEventClipboard(events:Array):Array - { - return offsetSongEventData(sortEvents(events), -Std.int(events[0].time)); - } + /** + * Prepare an array of events to be used as the clipboard data. + * + * Offset the provided array of events such that the first event is at 0 milliseconds. + */ + public static function buildEventClipboard(events:Array):Array + { + return offsetSongEventData(sortEvents(events), -Std.int(events[0].time)); + } - /** - * Sort an array of notes by strum time. - */ - public static function sortNotes(notes:Array, ?desc:Bool = false):Array - { - // TODO: Modifies the array in place. Is this okay? - notes.sort(function(a:SongNoteData, b:SongNoteData):Int - { - return FlxSort.byValues(desc ? FlxSort.DESCENDING : FlxSort.ASCENDING, a.time, b.time); - }); - return notes; - } + /** + * Sort an array of notes by strum time. + */ + public static function sortNotes(notes:Array, ?desc:Bool = false):Array + { + // TODO: Modifies the array in place. Is this okay? + notes.sort(function(a:SongNoteData, b:SongNoteData):Int + { + return FlxSort.byValues(desc ? FlxSort.DESCENDING : FlxSort.ASCENDING, a.time, b.time); + }); + return notes; + } - /** - * Sort an array of events by strum time. - */ - public static function sortEvents(events:Array, ?desc:Bool = false):Array - { - // TODO: Modifies the array in place. Is this okay? - events.sort(function(a:SongEventData, b:SongEventData):Int - { - return FlxSort.byValues(desc ? FlxSort.DESCENDING : FlxSort.ASCENDING, a.time, b.time); - }); - return events; - } + /** + * Sort an array of events by strum time. + */ + public static function sortEvents(events:Array, ?desc:Bool = false):Array + { + // TODO: Modifies the array in place. Is this okay? + events.sort(function(a:SongEventData, b:SongEventData):Int + { + return FlxSort.byValues(desc ? FlxSort.DESCENDING : FlxSort.ASCENDING, a.time, b.time); + }); + return events; + } - /** - * Serialize note and event data and write it to the clipboard. - */ - public static function writeItemsToClipboard(data:SongClipboardItems):Void - { - var dataString = SerializerUtil.toJSON(data); + /** + * Serialize note and event data and write it to the clipboard. + */ + public static function writeItemsToClipboard(data:SongClipboardItems):Void + { + var dataString = SerializerUtil.toJSON(data); - ClipboardUtil.setClipboard(dataString); + ClipboardUtil.setClipboard(dataString); - trace('Wrote ' + data.notes.length + ' notes and ' + data.events.length + ' events to clipboard.'); + trace('Wrote ' + data.notes.length + ' notes and ' + data.events.length + ' events to clipboard.'); - trace(dataString); - } + trace(dataString); + } - /** - * Read an array of note data from the clipboard and deserialize it. - */ - public static function readItemsFromClipboard():SongClipboardItems - { - var notesString = ClipboardUtil.getClipboard(); + /** + * Read an array of note data from the clipboard and deserialize it. + */ + public static function readItemsFromClipboard():SongClipboardItems + { + var notesString = ClipboardUtil.getClipboard(); - trace('Read ${notesString.length} characters from clipboard.'); + trace('Read ${notesString.length} characters from clipboard.'); - var data:SongClipboardItems = notesString.parseJSON(); + var data:SongClipboardItems = notesString.parseJSON(); - if (data == null) - { - trace('Failed to parse notes from clipboard.'); - return { - notes: [], - events: [] - }; - } - else - { - trace('Parsed ' + data.notes.length + ' notes and ' + data.events.length + ' from clipboard.'); - return data; - } - } + if (data == null) + { + trace('Failed to parse notes from clipboard.'); + return { + notes: [], + events: [] + }; + } + else + { + trace('Parsed ' + data.notes.length + ' notes and ' + data.events.length + ' from clipboard.'); + return data; + } + } - /** - * Filter a list of notes to only include notes that are within the given time range. - */ - public static function getNotesInTimeRange(notes:Array, start:Float, end:Float):Array - { - return notes.filter(function(note:SongNoteData):Bool - { - return note.time >= start && note.time <= end; - }); - } + /** + * Filter a list of notes to only include notes that are within the given time range. + */ + public static function getNotesInTimeRange(notes:Array, start:Float, end:Float):Array + { + return notes.filter(function(note:SongNoteData):Bool + { + return note.time >= start && note.time <= end; + }); + } - /** - * Filter a list of events to only include events that are within the given time range. - */ - public static function getEventsInTimeRange(events:Array, start:Float, end:Float):Array - { - return events.filter(function(event:SongEventData):Bool - { - return event.time >= start && event.time <= end; - }); - } + /** + * Filter a list of events to only include events that are within the given time range. + */ + public static function getEventsInTimeRange(events:Array, start:Float, end:Float):Array + { + return events.filter(function(event:SongEventData):Bool + { + return event.time >= start && event.time <= end; + }); + } - /** - * Filter a list of notes to only include notes whose data is within the given range. - */ - public static function getNotesInDataRange(notes:Array, start:Int, end:Int):Array - { - return notes.filter(function(note:SongNoteData):Bool - { - return note.data >= start && note.data <= end; - }); - } + /** + * Filter a list of notes to only include notes whose data is within the given range. + */ + public static function getNotesInDataRange(notes:Array, start:Int, end:Int):Array + { + return notes.filter(function(note:SongNoteData):Bool + { + return note.data >= start && note.data <= end; + }); + } - /** - * Filter a list of notes to only include notes whose data is one of the given values. - */ - public static function getNotesWithData(notes:Array, data:Array):Array - { - return notes.filter(function(note:SongNoteData):Bool - { - return data.indexOf(note.data) != -1; - }); - } + /** + * Filter a list of notes to only include notes whose data is one of the given values. + */ + public static function getNotesWithData(notes:Array, data:Array):Array + { + return notes.filter(function(note:SongNoteData):Bool + { + return data.indexOf(note.data) != -1; + }); + } } typedef SongClipboardItems = { - notes:Array, - events:Array + notes:Array, + events:Array } diff --git a/source/funkin/play/song/SongSerializer.hx b/source/funkin/play/song/SongSerializer.hx index 31e37415f..c7933665a 100644 --- a/source/funkin/play/song/SongSerializer.hx +++ b/source/funkin/play/song/SongSerializer.hx @@ -14,203 +14,196 @@ import openfl.net.FileReference; */ class SongSerializer { - /** - * Access a SongChartData JSON file from a specific path, then load it. - * @param path The file path to read from. - */ - public static function importSongChartDataSync(path:String):SongChartData - { - var fileData = readFile(path); + /** + * Access a SongChartData JSON file from a specific path, then load it. + * @param path The file path to read from. + */ + public static function importSongChartDataSync(path:String):SongChartData + { + var fileData = readFile(path); - if (fileData == null) - return null; + if (fileData == null) return null; - var songChartData:SongChartData = fileData.parseJSON(); + var songChartData:SongChartData = fileData.parseJSON(); - return songChartData; - } + return songChartData; + } - /** - * Access a SongMetadata JSON file from a specific path, then load it. - * @param path The file path to read from. - */ - public static function importSongMetadataSync(path:String):SongMetadata - { - var fileData = readFile(path); + /** + * Access a SongMetadata JSON file from a specific path, then load it. + * @param path The file path to read from. + */ + public static function importSongMetadataSync(path:String):SongMetadata + { + var fileData = readFile(path); - if (fileData == null) - return null; + if (fileData == null) return null; - var songMetadata:SongMetadata = fileData.parseJSON(); + var songMetadata:SongMetadata = fileData.parseJSON(); - return songMetadata; - } + return songMetadata; + } - /** - * Prompt the user to browse for a SongChartData JSON file path, then load it. - * @param callback The function to call when the file is loaded. - */ - public static function importSongChartDataAsync(callback:SongChartData->Void):Void - { - browseFileReference(function(fileReference:FileReference) - { - var data = fileReference.data.toString(); + /** + * Prompt the user to browse for a SongChartData JSON file path, then load it. + * @param callback The function to call when the file is loaded. + */ + public static function importSongChartDataAsync(callback:SongChartData->Void):Void + { + browseFileReference(function(fileReference:FileReference) + { + var data = fileReference.data.toString(); - if (data == null) - return; + if (data == null) return; - var songChartData:SongChartData = data.parseJSON(); + var songChartData:SongChartData = data.parseJSON(); - if (songChartData != null) - callback(songChartData); - }); - } + if (songChartData != null) callback(songChartData); + }); + } - /** - * Prompt the user to browse for a SongMetadata JSON file path, then load it. - * @param callback The function to call when the file is loaded. - */ - public static function importSongMetadataAsync(callback:SongMetadata->Void):Void - { - browseFileReference(function(fileReference:FileReference) - { - var data = fileReference.data.toString(); + /** + * Prompt the user to browse for a SongMetadata JSON file path, then load it. + * @param callback The function to call when the file is loaded. + */ + public static function importSongMetadataAsync(callback:SongMetadata->Void):Void + { + browseFileReference(function(fileReference:FileReference) + { + var data = fileReference.data.toString(); - if (data == null) - return; + if (data == null) return; - var songMetadata:SongMetadata = data.parseJSON(); + var songMetadata:SongMetadata = data.parseJSON(); - if (songMetadata != null) - callback(songMetadata); - }); - } + if (songMetadata != null) callback(songMetadata); + }); + } - /** - * Save a SongChartData object as a JSON file to an automatically generated path. - * Works great on HTML5 and desktop. - */ - public static function exportSongChartData(data:SongChartData) - { - var path = 'chart.json'; - exportSongChartDataAs(path, data); - } + /** + * Save a SongChartData object as a JSON file to an automatically generated path. + * Works great on HTML5 and desktop. + */ + public static function exportSongChartData(data:SongChartData) + { + var path = 'chart.json'; + exportSongChartDataAs(path, data); + } - /** - * Save a SongMetadata object as a JSON file to an automatically generated path. - * Works great on HTML5 and desktop. - */ - public static function exportSongMetadata(data:SongMetadata) - { - var path = 'metadata.json'; - exportSongMetadataAs(path, data); - } + /** + * Save a SongMetadata object as a JSON file to an automatically generated path. + * Works great on HTML5 and desktop. + */ + public static function exportSongMetadata(data:SongMetadata) + { + var path = 'metadata.json'; + exportSongMetadataAs(path, data); + } - /** - * Save a SongChartData object as a JSON file to a specified path. - * Works great on HTML5 and desktop. - * - * @param path The file path to save to. - */ - public static function exportSongChartDataAs(path:String, data:SongChartData) - { - var dataString = SerializerUtil.toJSON(data); + /** + * Save a SongChartData object as a JSON file to a specified path. + * Works great on HTML5 and desktop. + * + * @param path The file path to save to. + */ + public static function exportSongChartDataAs(path:String, data:SongChartData) + { + var dataString = SerializerUtil.toJSON(data); - writeFileReference(path, dataString); - } + writeFileReference(path, dataString); + } - /** - * Save a SongMetadata object as a JSON file to a specified path. - * Works great on HTML5 and desktop. - * - * @param path The file path to save to. - */ - public static function exportSongMetadataAs(path:String, data:SongMetadata) - { - var dataString = SerializerUtil.toJSON(data); + /** + * Save a SongMetadata object as a JSON file to a specified path. + * Works great on HTML5 and desktop. + * + * @param path The file path to save to. + */ + public static function exportSongMetadataAs(path:String, data:SongMetadata) + { + var dataString = SerializerUtil.toJSON(data); - writeFileReference(path, dataString); - } + writeFileReference(path, dataString); + } - /** - * Read the string contents of a file. - * Only works on desktop platforms. - * @param path The file path to read from. - */ - static function readFile(path:String):String - { - #if sys - var fileBytes:Bytes = sys.io.File.getBytes(path); + /** + * Read the string contents of a file. + * Only works on desktop platforms. + * @param path The file path to read from. + */ + static function readFile(path:String):String + { + #if sys + var fileBytes:Bytes = sys.io.File.getBytes(path); - if (fileBytes == null) - return null; + if (fileBytes == null) return null; - return fileBytes.toString(); - #end + return fileBytes.toString(); + #end - trace('ERROR: readFile not implemented for this platform'); - return null; - } + trace('ERROR: readFile not implemented for this platform'); + return null; + } - /** - * Write string contents to a file. - * Only works on desktop platforms. - * @param path The file path to read from. - */ - static function writeFile(path:String, data:String):Void - { - #if sys - sys.io.File.saveContent(path, data); - return; - #end - trace('ERROR: writeFile not implemented for this platform'); - return; - } + /** + * Write string contents to a file. + * Only works on desktop platforms. + * @param path The file path to read from. + */ + static function writeFile(path:String, data:String):Void + { + #if sys + sys.io.File.saveContent(path, data); + return; + #end + trace('ERROR: writeFile not implemented for this platform'); + return; + } - /** - * Browse for a file to read and execute a callback once we have a file reference. - * Works great on HTML5 or desktop. - * - * @param callback The function to call when the file is loaded. - */ - static function browseFileReference(callback:FileReference->Void) - { - var file = new FileReference(); + /** + * Browse for a file to read and execute a callback once we have a file reference. + * Works great on HTML5 or desktop. + * + * @param callback The function to call when the file is loaded. + */ + static function browseFileReference(callback:FileReference->Void) + { + var file = new FileReference(); - file.addEventListener(Event.SELECT, function(e) - { - var selectedFileRef:FileReference = e.target; - trace('Selected file: ' + selectedFileRef.name); - selectedFileRef.addEventListener(Event.COMPLETE, function(e) - { - var loadedFileRef:FileReference = e.target; - trace('Loaded file: ' + loadedFileRef.name); - callback(loadedFileRef); - }); - selectedFileRef.load(); - }); + file.addEventListener(Event.SELECT, function(e) + { + var selectedFileRef:FileReference = e.target; + trace('Selected file: ' + selectedFileRef.name); + selectedFileRef.addEventListener(Event.COMPLETE, function(e) + { + var loadedFileRef:FileReference = e.target; + trace('Loaded file: ' + loadedFileRef.name); + callback(loadedFileRef); + }); + selectedFileRef.load(); + }); - file.browse(); - } + file.browse(); + } - /** - * Prompts the user to save a file to their computer. - */ - static function writeFileReference(path:String, data:String) - { - var file = new FileReference(); - file.addEventListener(Event.COMPLETE, function(e:Event) - { - trace('Successfully wrote file.'); - }); - file.addEventListener(Event.CANCEL, function(e:Event) - { - trace('Cancelled writing file.'); - }); - file.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent) - { - trace('IO error writing file.'); - }); - file.save(data, path); - } + /** + * Prompts the user to save a file to their computer. + */ + static function writeFileReference(path:String, data:String) + { + var file = new FileReference(); + file.addEventListener(Event.COMPLETE, function(e:Event) + { + trace('Successfully wrote file.'); + }); + file.addEventListener(Event.CANCEL, function(e:Event) + { + trace('Cancelled writing file.'); + }); + file.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent) + { + trace('IO error writing file.'); + }); + file.save(data, path); + } } diff --git a/source/funkin/play/song/SongValidator.hx b/source/funkin/play/song/SongValidator.hx index 592ca818d..c065743ad 100644 --- a/source/funkin/play/song/SongValidator.hx +++ b/source/funkin/play/song/SongValidator.hx @@ -13,119 +13,119 @@ import funkin.util.Constants; */ class SongValidator { - public static final DEFAULT_SONGNAME:String = "Unknown"; - public static final DEFAULT_ARTIST:String = "Unknown"; - public static final DEFAULT_TIMEFORMAT:SongTimeFormat = SongTimeFormat.MILLISECONDS; - public static final DEFAULT_DIVISIONS:Int = -1; - public static final DEFAULT_LOOP:Bool = false; - public static final DEFAULT_STAGE:String = "mainStage"; - public static final DEFAULT_SCROLLSPEED:Float = 1.0; + public static final DEFAULT_SONGNAME:String = "Unknown"; + public static final DEFAULT_ARTIST:String = "Unknown"; + public static final DEFAULT_TIMEFORMAT:SongTimeFormat = SongTimeFormat.MILLISECONDS; + public static final DEFAULT_DIVISIONS:Int = -1; + public static final DEFAULT_LOOP:Bool = false; + public static final DEFAULT_STAGE:String = "mainStage"; + public static final DEFAULT_SCROLLSPEED:Float = 1.0; - public static var DEFAULT_GENERATEDBY(get, null):String; + public static var DEFAULT_GENERATEDBY(get, null):String; - static function get_DEFAULT_GENERATEDBY():String - { - return '${Constants.TITLE} - ${Constants.VERSION}'; - } + static function get_DEFAULT_GENERATEDBY():String + { + return '${Constants.TITLE} - ${Constants.VERSION}'; + } - /** - * Validates the fields of a SongMetadata object (excluding the version field). - * - * @param input The SongMetadata object to validate. - * @param songId The ID of the song being validated. Only used for error messages. - * @return The validated SongMetadata object. - */ - public static function validateSongMetadata(input:SongMetadata, songId:String = 'unknown'):SongMetadata - { - if (input == null) - { - trace('[SONGDATA] Could not parse metadata for song ${songId}'); - return null; - } + /** + * Validates the fields of a SongMetadata object (excluding the version field). + * + * @param input The SongMetadata object to validate. + * @param songId The ID of the song being validated. Only used for error messages. + * @return The validated SongMetadata object. + */ + public static function validateSongMetadata(input:SongMetadata, songId:String = 'unknown'):SongMetadata + { + if (input == null) + { + trace('[SONGDATA] Could not parse metadata for song ${songId}'); + return null; + } - if (input.songName == null) - { - trace('[SONGDATA] Song ${songId} is missing a songName field. '); - input.songName = DEFAULT_SONGNAME; - } - if (input.artist == null) - { - trace('[SONGDATA] Song ${songId} is missing an artist field. '); - input.artist = DEFAULT_ARTIST; - } - if (input.timeFormat == null) - { - trace('[SONGDATA] Song ${songId} is missing a timeFormat field. '); - input.timeFormat = DEFAULT_TIMEFORMAT; - } - if (input.generatedBy == null) - { - input.generatedBy = DEFAULT_GENERATEDBY; - } + if (input.songName == null) + { + trace('[SONGDATA] Song ${songId} is missing a songName field. '); + input.songName = DEFAULT_SONGNAME; + } + if (input.artist == null) + { + trace('[SONGDATA] Song ${songId} is missing an artist field. '); + input.artist = DEFAULT_ARTIST; + } + if (input.timeFormat == null) + { + trace('[SONGDATA] Song ${songId} is missing a timeFormat field. '); + input.timeFormat = DEFAULT_TIMEFORMAT; + } + if (input.generatedBy == null) + { + input.generatedBy = DEFAULT_GENERATEDBY; + } - input.timeChanges = validateTimeChanges(input.timeChanges, songId); - input.playData = validatePlayData(input.playData, songId); + input.timeChanges = validateTimeChanges(input.timeChanges, songId); + input.playData = validatePlayData(input.playData, songId); - input.variation = ''; + input.variation = ''; - return input; - } + return input; + } - /** - * Validates the fields of a SongPlayData object. - * - * @param input The SongPlayData object to validate. - * @param songId The ID of the song being validated. Only used for error messages. - * @return The validated SongPlayData object. - */ - public static function validatePlayData(input:SongPlayData, songId:String = 'unknown'):SongPlayData - { - return input; - } + /** + * Validates the fields of a SongPlayData object. + * + * @param input The SongPlayData object to validate. + * @param songId The ID of the song being validated. Only used for error messages. + * @return The validated SongPlayData object. + */ + public static function validatePlayData(input:SongPlayData, songId:String = 'unknown'):SongPlayData + { + return input; + } - /** - * Validates the fields of a TimeChange object. - * - * @param input The TimeChange object to validate. - * @param songId The ID of the song being validated. Only used for error messages. - * @return The validated TimeChange object. - */ - public static function validateTimeChange(input:SongTimeChange, songId:String = 'unknown'):SongTimeChange - { - return input; - } + /** + * Validates the fields of a TimeChange object. + * + * @param input The TimeChange object to validate. + * @param songId The ID of the song being validated. Only used for error messages. + * @return The validated TimeChange object. + */ + public static function validateTimeChange(input:SongTimeChange, songId:String = 'unknown'):SongTimeChange + { + return input; + } - /** - * Validates multiple TimeChange objects in an array. - */ - public static function validateTimeChanges(input:Array, songId:String = 'unknown'):Array - { - if (input == null) - { - trace('[SONGDATA] Song ${songId} is missing a timeChanges field. '); - return []; - } + /** + * Validates multiple TimeChange objects in an array. + */ + public static function validateTimeChanges(input:Array, songId:String = 'unknown'):Array + { + if (input == null) + { + trace('[SONGDATA] Song ${songId} is missing a timeChanges field. '); + return []; + } - input = input.map((timeChange) -> validateTimeChange(timeChange, songId)); + input = input.map((timeChange) -> validateTimeChange(timeChange, songId)); - return input; - } + return input; + } - /** - * Validates the fields of a SongChartData object (excluding the version field). - * - * @param input The SongChartData object to validate. - * @param songId The ID of the song being validated. Only used for error messages. - * @return The validated SongChartData object. - */ - public static function validateSongChartData(input:SongChartData, songId:String = 'unknown'):SongChartData - { - if (input == null) - { - trace('[SONGDATA] Could not parse chart data for song ${songId}'); - return null; - } + /** + * Validates the fields of a SongChartData object (excluding the version field). + * + * @param input The SongChartData object to validate. + * @param songId The ID of the song being validated. Only used for error messages. + * @return The validated SongChartData object. + */ + public static function validateSongChartData(input:SongChartData, songId:String = 'unknown'):SongChartData + { + if (input == null) + { + trace('[SONGDATA] Could not parse chart data for song ${songId}'); + return null; + } - return input; - } + return input; + } } diff --git a/source/funkin/play/stage/Bopper.hx b/source/funkin/play/stage/Bopper.hx index 298b38d43..cb33469b3 100644 --- a/source/funkin/play/stage/Bopper.hx +++ b/source/funkin/play/stage/Bopper.hx @@ -61,10 +61,8 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass function set_globalOffsets(value:Array) { - if (globalOffsets == null) - globalOffsets = [0, 0]; - if (globalOffsets == value) - return value; + if (globalOffsets == null) globalOffsets = [0, 0]; + if (globalOffsets == value) return value; var xDiff = globalOffsets[0] - value[0]; var yDiff = globalOffsets[1] - value[1]; @@ -74,16 +72,14 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass return animOffsets = value; } - private var animOffsets(default, set):Array = [0, 0]; + var animOffsets(default, set):Array = [0, 0]; public var originalPosition:FlxPoint = new FlxPoint(0, 0); function set_animOffsets(value:Array) { - if (animOffsets == null) - animOffsets = [0, 0]; - if (animOffsets == value) - return value; + if (animOffsets == null) animOffsets = [0, 0]; + if (animOffsets == value) return value; var xDiff = animOffsets[0] - value[0]; var yDiff = animOffsets[1] - value[1]; @@ -203,8 +199,7 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass public function hasAnimation(id:String):Bool { - if (this.animation == null) - return false; + if (this.animation == null) return false; return this.animation.getByName(id) != null; } @@ -217,8 +212,7 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass function correctAnimationName(name:String) { // If the animation exists, we're good. - if (hasAnimation(name)) - return name; + if (hasAnimation(name)) return name; trace('[BOPPER] Animation "$name" does not exist!'); @@ -253,12 +247,10 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass */ public function playAnimation(name:String, restart:Bool = false, ?ignoreOther:Bool = false):Void { - if (!canPlayOtherAnims && !ignoreOther) - return; + if (!canPlayOtherAnims && !ignoreOther) return; var correctName = correctAnimationName(name); - if (correctName == null) - return; + if (correctName == null) return; this.animation.play(correctName, restart, false, 0); @@ -280,12 +272,10 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass { // TODO: Might be nice to rework this function, maybe have a numbered priority system? - if (this.animation == null) - return; + if (this.animation == null) return; var correctName = correctAnimationName(name); - if (correctName == null) - return; + if (correctName == null) return; this.animation.play(correctName, false, false); applyAnimationOffsets(correctName); @@ -327,8 +317,7 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass */ public function getCurrentAnimation():String { - if (this.animation == null || this.animation.curAnim == null) - return ""; + if (this.animation == null || this.animation.curAnim == null) return ""; return this.animation.curAnim.name; } diff --git a/source/funkin/play/stage/ScriptedBopper.hx b/source/funkin/play/stage/ScriptedBopper.hx index ab69703fc..d35d53503 100644 --- a/source/funkin/play/stage/ScriptedBopper.hx +++ b/source/funkin/play/stage/ScriptedBopper.hx @@ -1,6 +1,8 @@ package funkin.play.stage; -import polymod.hscript.HScriptedClass; - +/** + * A script that can be tied to a Bopper. + * Create a scripted class that extends Bopper to use this. + */ @:hscriptClass -class ScriptedBopper extends Bopper implements HScriptedClass {} +class ScriptedBopper extends funkin.play.stage.Bopper implements polymod.hscript.HScriptedClass {} diff --git a/source/funkin/play/stage/ScriptedStage.hx b/source/funkin/play/stage/ScriptedStage.hx index 5534e94a2..95bdec50b 100644 --- a/source/funkin/play/stage/ScriptedStage.hx +++ b/source/funkin/play/stage/ScriptedStage.hx @@ -1,6 +1,9 @@ package funkin.play.stage; -import polymod.hscript.HScriptedClass; - +/** + * A script that can be tied to a Stage. + * Create a scripted class that extends Stage, + * and call `super('stageID')` in the constructor. + */ @:hscriptClass -class ScriptedStage extends Stage implements HScriptedClass {} +class ScriptedStage extends funkin.play.stage.Stage implements polymod.hscript.HScriptedClass {} diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index 83790e49d..66227c6a5 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -290,8 +290,7 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass // sprite.scrollFactor.copyFrom(scrollFactor); sprite.cameras = _cameras; // _cameras instead of cameras because get_cameras() will not return null - if (clipRect != null) - clipRectTransform(sprite, clipRect); + if (clipRect != null) clipRectTransform(sprite, clipRect); } var debugIconGroup:FlxSpriteGroup; @@ -301,8 +300,7 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass */ public function addCharacter(character:BaseCharacter, charType:CharacterType) { - if (character == null) - return; + if (character == null) return; #if debug // Temporary marker that shows where the character's location is relative to. diff --git a/source/funkin/play/stage/StageData.hx b/source/funkin/play/stage/StageData.hx index 84f33fa80..002606c6d 100644 --- a/source/funkin/play/stage/StageData.hx +++ b/source/funkin/play/stage/StageData.hx @@ -189,11 +189,12 @@ class StageDataParser static final DEFAULT_SCROLL:Array = [0, 0]; static final DEFAULT_ZINDEX:Int = 0; - static final DEFAULT_CHARACTER_DATA:StageDataCharacter = { - zIndex: DEFAULT_ZINDEX, - position: DEFAULT_POSITION, - cameraOffsets: DEFAULT_OFFSETS, - } + static final DEFAULT_CHARACTER_DATA:StageDataCharacter = + { + zIndex: DEFAULT_ZINDEX, + position: DEFAULT_POSITION, + cameraOffsets: DEFAULT_OFFSETS, + } /** * Set unspecified parameters to their defaults. @@ -377,10 +378,8 @@ class StageDataParser } if (inputCharacter.cameraOffsets == null || inputCharacter.cameraOffsets.length != 2) { - if (inputCharacter == input.characters.bf) - inputCharacter.cameraOffsets = DEFAULT_CAMERA_OFFSETS_BF; - else if (inputCharacter == input.characters.dad) - inputCharacter.cameraOffsets = DEFAULT_CAMERA_OFFSETS_DAD; + if (inputCharacter == input.characters.bf) inputCharacter.cameraOffsets = DEFAULT_CAMERA_OFFSETS_BF; + else if (inputCharacter == input.characters.dad) inputCharacter.cameraOffsets = DEFAULT_CAMERA_OFFSETS_DAD; else { inputCharacter.cameraOffsets = [0, 0]; diff --git a/source/funkin/shaderslmfao/AngleMask.hx b/source/funkin/shaderslmfao/AngleMask.hx index 1f16d63ca..0fe279ad6 100644 --- a/source/funkin/shaderslmfao/AngleMask.hx +++ b/source/funkin/shaderslmfao/AngleMask.hx @@ -4,7 +4,7 @@ import flixel.system.FlxAssets.FlxShader; class AngleMask extends FlxShader { - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform vec2 endPosition; void main() @@ -34,10 +34,10 @@ class AngleMask extends FlxShader gl_FragColor = vec4(0.0); }') - public function new() - { - super(); + public function new() + { + super(); - endPosition.value = [90, 100]; // 100 AS DEFAULT WORKS NICELY FOR FREEPLAY? - } + endPosition.value = [90, 100]; // 100 AS DEFAULT WORKS NICELY FOR FREEPLAY? + } } diff --git a/source/funkin/shaderslmfao/BlendModeEffect.hx b/source/funkin/shaderslmfao/BlendModeEffect.hx index bc242b3e3..8fe98f70a 100644 --- a/source/funkin/shaderslmfao/BlendModeEffect.hx +++ b/source/funkin/shaderslmfao/BlendModeEffect.hx @@ -5,30 +5,30 @@ import openfl.display.ShaderParameter; typedef BlendModeShader = { - var uBlendColor:ShaderParameter; + var uBlendColor:ShaderParameter; } class BlendModeEffect { - public var shader(default, null):BlendModeShader; + public var shader(default, null):BlendModeShader; - @:isVar - public var color(default, set):FlxColor; + @:isVar + public var color(default, set):FlxColor; - public function new(shader:BlendModeShader, color:FlxColor):Void - { - shader.uBlendColor.value = []; - this.shader = shader; - this.color = color; - } + public function new(shader:BlendModeShader, color:FlxColor):Void + { + shader.uBlendColor.value = []; + this.shader = shader; + this.color = color; + } - function set_color(color:FlxColor):FlxColor - { - shader.uBlendColor.value[0] = color.redFloat; - shader.uBlendColor.value[1] = color.greenFloat; - shader.uBlendColor.value[2] = color.blueFloat; - shader.uBlendColor.value[3] = color.alphaFloat; + function set_color(color:FlxColor):FlxColor + { + shader.uBlendColor.value[0] = color.redFloat; + shader.uBlendColor.value[1] = color.greenFloat; + shader.uBlendColor.value[2] = color.blueFloat; + shader.uBlendColor.value[3] = color.alphaFloat; - return this.color = color; - } + return this.color = color; + } } diff --git a/source/funkin/shaderslmfao/ColorSwap.hx b/source/funkin/shaderslmfao/ColorSwap.hx index 0738789be..684e48239 100644 --- a/source/funkin/shaderslmfao/ColorSwap.hx +++ b/source/funkin/shaderslmfao/ColorSwap.hx @@ -5,59 +5,59 @@ import flixel.util.FlxColor; class ColorSwap { - public var shader(default, null):ColorSwapShader; - public var colorToReplace(default, set):FlxColor; - public var newColor(default, set):FlxColor; - public var daTime(default, set):Float; + public var shader(default, null):ColorSwapShader; + public var colorToReplace(default, set):FlxColor; + public var newColor(default, set):FlxColor; + public var daTime(default, set):Float; - public var hasOutline(default, set):Bool = false; + public var hasOutline(default, set):Bool = false; - public var hueShit:Float = 0; + public var hueShit:Float = 0; - public function new():Void - { - shader = new ColorSwapShader(); - shader.uTime.value = [0]; - shader.money.value = [0]; - shader.awesomeOutline.value = [hasOutline]; - } + public function new():Void + { + shader = new ColorSwapShader(); + shader.uTime.value = [0]; + shader.money.value = [0]; + shader.awesomeOutline.value = [hasOutline]; + } - public function update(elapsed:Float):Void - { - shader.uTime.value[0] += elapsed; - hueShit += elapsed; - // trace(shader.money.value[0]); - } + public function update(elapsed:Float):Void + { + shader.uTime.value[0] += elapsed; + hueShit += elapsed; + // trace(shader.money.value[0]); + } - function set_colorToReplace(color:FlxColor):FlxColor - { - colorToReplace = color; + function set_colorToReplace(color:FlxColor):FlxColor + { + colorToReplace = color; - return color; - } + return color; + } - function set_hasOutline(lol:Bool):Bool - { - shader.awesomeOutline.value = [lol]; - return lol; - } + function set_hasOutline(lol:Bool):Bool + { + shader.awesomeOutline.value = [lol]; + return lol; + } - function set_daTime(daTime:Float):Float - { - return daTime; - } + function set_daTime(daTime:Float):Float + { + return daTime; + } - function set_newColor(color:FlxColor):FlxColor - { - newColor = color; + function set_newColor(color:FlxColor):FlxColor + { + newColor = color; - return color; - } + return color; + } } class ColorSwapShader extends FlxShader { - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform float uTime; @@ -152,8 +152,8 @@ class ColorSwapShader extends FlxShader } ') - public function new() - { - super(); - } + public function new() + { + super(); + } } diff --git a/source/funkin/shaderslmfao/LeftMaskShader.hx b/source/funkin/shaderslmfao/LeftMaskShader.hx index 091eba86e..e921a7f2b 100644 --- a/source/funkin/shaderslmfao/LeftMaskShader.hx +++ b/source/funkin/shaderslmfao/LeftMaskShader.hx @@ -5,36 +5,36 @@ import flixel.system.FlxAssets.FlxShader; class LeftMaskShader extends FlxShader { - public var swagMaskX(default, set):Float = 0; - public var swagSprX(default, set):Float = 0; - public var frameUV(default, set):FlxRect; + public var swagMaskX(default, set):Float = 0; + public var swagSprX(default, set):Float = 0; + public var frameUV(default, set):FlxRect; - function set_swagSprX(x:Float):Float - { - sprX.value[0] = x; + function set_swagSprX(x:Float):Float + { + sprX.value[0] = x; - return x; - } + return x; + } - function set_swagMaskX(x:Float):Float - { - maskX.value[0] = x; + function set_swagMaskX(x:Float):Float + { + maskX.value[0] = x; - return x; - } + return x; + } - function set_frameUV(uv:FlxRect):FlxRect - { - trace("SETTING FRAMEUV"); - trace(uv); + function set_frameUV(uv:FlxRect):FlxRect + { + trace("SETTING FRAMEUV"); + trace(uv); - uvFrameX.value[0] = uv.x; - uvFrameY.value[0] = uv.y; + uvFrameX.value[0] = uv.x; + uvFrameY.value[0] = uv.y; - return uv; - } + return uv; + } - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform float sprX; @@ -64,13 +64,13 @@ class LeftMaskShader extends FlxShader } ') - public function new() - { - super(); + public function new() + { + super(); - sprX.value = [0]; - maskX.value = [0]; - uvFrameX.value = [0]; - uvFrameY.value = [0]; - } + sprX.value = [0]; + maskX.value = [0]; + uvFrameX.value = [0]; + uvFrameY.value = [0]; + } } diff --git a/source/funkin/shaderslmfao/MultiplyShader.hx b/source/funkin/shaderslmfao/MultiplyShader.hx index 27ae60d3b..2868982a2 100644 --- a/source/funkin/shaderslmfao/MultiplyShader.hx +++ b/source/funkin/shaderslmfao/MultiplyShader.hx @@ -4,7 +4,7 @@ import flixel.system.FlxAssets.FlxShader; class MultiplyShader extends FlxShader { - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform sampler2D funnyImage; uniform vec4 uBlendColor; @@ -24,8 +24,8 @@ class MultiplyShader extends FlxShader vec4 base = texture2D(bitmap, openfl_TextureCoordv); gl_FragColor = blendMultiply(base, uBlendColor, uBlendColor.a); }') - public function new() - { - super(); - } + public function new() + { + super(); + } } diff --git a/source/funkin/shaderslmfao/OverlayBlend.hx b/source/funkin/shaderslmfao/OverlayBlend.hx index 162726f69..14a840451 100644 --- a/source/funkin/shaderslmfao/OverlayBlend.hx +++ b/source/funkin/shaderslmfao/OverlayBlend.hx @@ -6,25 +6,25 @@ import flixel.system.FlxAssets.FlxShader; @:keep class OverlayBlend extends FlxShader { - // these r copypaste - public var funnyX(default, set):Float = 0; - public var funnyY(default, set):Float = 0; + // these r copypaste + public var funnyX(default, set):Float = 0; + public var funnyY(default, set):Float = 0; - function set_funnyX(x:Float):Float - { - xPos.value[0] = x; + function set_funnyX(x:Float):Float + { + xPos.value[0] = x; - return x; - } + return x; + } - function set_funnyY(y:Float):Float - { - yPos.value[0] = y; + function set_funnyY(y:Float):Float + { + yPos.value[0] = y; - return y; - } + return y; + } - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform float alphaShit; @@ -59,11 +59,11 @@ class OverlayBlend extends FlxShader } ') - public function new() - { - super(); + public function new() + { + super(); - xPos.value = [0]; - yPos.value = [0]; - } + xPos.value = [0]; + yPos.value = [0]; + } } diff --git a/source/funkin/shaderslmfao/PureColor.hx b/source/funkin/shaderslmfao/PureColor.hx index 3546e7fda..767a29d0d 100644 --- a/source/funkin/shaderslmfao/PureColor.hx +++ b/source/funkin/shaderslmfao/PureColor.hx @@ -5,24 +5,24 @@ import flixel.util.FlxColor; class PureColor extends FlxShader { - public var col(default, set):FlxColor; - public var colorSet(default, set):Bool; + public var col(default, set):FlxColor; + public var colorSet(default, set):Bool; - function set_colorSet(bol:Bool):Bool - { - colSet.value = [bol]; + function set_colorSet(bol:Bool):Bool + { + colSet.value = [bol]; - return bol; - } + return bol; + } - function set_col(val:FlxColor):FlxColor - { - funnyColor.value = [val.red, val.green, val.blue, val.alpha]; + function set_col(val:FlxColor):FlxColor + { + funnyColor.value = [val.red, val.green, val.blue, val.alpha]; - return val; - } + return val; + } - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform vec4 funnyColor; @@ -38,11 +38,11 @@ class PureColor extends FlxShader gl_FragColor = color; } ') - public function new(colr:FlxColor) - { - super(); + public function new(colr:FlxColor) + { + super(); - this.col = colr; - this.colorSet = false; - } + this.col = colr; + this.colorSet = false; + } } diff --git a/source/funkin/shaderslmfao/ScreenWipeShader.hx b/source/funkin/shaderslmfao/ScreenWipeShader.hx index 37e6d604d..2ba035dc0 100644 --- a/source/funkin/shaderslmfao/ScreenWipeShader.hx +++ b/source/funkin/shaderslmfao/ScreenWipeShader.hx @@ -4,16 +4,16 @@ import flixel.system.FlxAssets.FlxShader; class ScreenWipeShader extends FlxShader { - public var daAlphaShit(default, set):Float = 0; + public var daAlphaShit(default, set):Float = 0; - function set_daAlphaShit(alpha:Float):Float - { - alphaShit.value[0] = alpha; + function set_daAlphaShit(alpha:Float):Float + { + alphaShit.value[0] = alpha; - return alpha; - } + return alpha; + } - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform float alphaShit; @@ -63,10 +63,10 @@ class ScreenWipeShader extends FlxShader gl_FragColor = color; } ') - public function new() - { - super(); + public function new() + { + super(); - alphaShit.value = [0]; - } + alphaShit.value = [0]; + } } diff --git a/source/funkin/shaderslmfao/StrokeShader.hx b/source/funkin/shaderslmfao/StrokeShader.hx index 575ff9419..d09b131a7 100644 --- a/source/funkin/shaderslmfao/StrokeShader.hx +++ b/source/funkin/shaderslmfao/StrokeShader.hx @@ -5,34 +5,34 @@ import flixel.util.FlxColor; class StrokeShader extends FlxShader { - // MOSTLY STOLEN FROM AUSTIN EAST LOL! - // https://gist.github.com/AustinEast/d3892fdf6a6079366fffde071f0c2bae - public var width(default, set):Float = 0; - public var height(default, set):Float = 0; + // MOSTLY STOLEN FROM AUSTIN EAST LOL! + // https://gist.github.com/AustinEast/d3892fdf6a6079366fffde071f0c2bae + public var width(default, set):Float = 0; + public var height(default, set):Float = 0; - public var col(default, set):FlxColor = 0xFFFFFFFF; + public var col(default, set):FlxColor = 0xFFFFFFFF; - function set_width(val):Float - { - size.value = [val, height]; + function set_width(val):Float + { + size.value = [val, height]; - return val; - } + return val; + } - function set_height(val):Float - { - size.value = [width, val]; - return val; - } + function set_height(val):Float + { + size.value = [width, val]; + return val; + } - function set_col(val:FlxColor):FlxColor - { - color.value = [val.red, val.green, val.blue, val.alpha]; + function set_col(val:FlxColor):FlxColor + { + color.value = [val.red, val.green, val.blue, val.alpha]; - return val; - } + return val; + } - @:glFragmentSource(' + @:glFragmentSource(' #pragma header uniform vec2 size; @@ -54,12 +54,12 @@ class StrokeShader extends FlxShader gl_FragColor = sample; } ') - public function new(color:FlxColor = 0xFFFFFFFF, width:Float = 1, height:Float = 1) - { - super(); + public function new(color:FlxColor = 0xFFFFFFFF, width:Float = 1, height:Float = 1) + { + super(); - col = color; - this.width = width; - this.height = height; - } + col = color; + this.width = width; + this.height = height; + } } diff --git a/source/funkin/shaderslmfao/TitleOutline.hx b/source/funkin/shaderslmfao/TitleOutline.hx index cabab767d..c10fce8c3 100644 --- a/source/funkin/shaderslmfao/TitleOutline.hx +++ b/source/funkin/shaderslmfao/TitleOutline.hx @@ -5,24 +5,24 @@ import flixel.system.FlxAssets.FlxShader; class TitleOutline extends FlxShader { - public var funnyX(default, set):Float = 0; - public var funnyY(default, set):Float = 0; + public var funnyX(default, set):Float = 0; + public var funnyY(default, set):Float = 0; - function set_funnyX(x:Float):Float - { - xPos.value[0] = x; + function set_funnyX(x:Float):Float + { + xPos.value[0] = x; - return x; - } + return x; + } - function set_funnyY(y:Float):Float - { - yPos.value[0] = y; + function set_funnyY(y:Float):Float + { + yPos.value[0] = y; - return y; - } + return y; + } - @:glFragmentSource(' + @:glFragmentSource(' #pragma header // uniform float alphaShit; @@ -64,11 +64,11 @@ class TitleOutline extends FlxShader } ') - public function new() - { - super(); + public function new() + { + super(); - xPos.value = [0]; - yPos.value = [0]; - } + xPos.value = [0]; + yPos.value = [0]; + } } diff --git a/source/funkin/shaderslmfao/WaveShader.hx b/source/funkin/shaderslmfao/WaveShader.hx index 14aa2b7b1..89171b089 100644 --- a/source/funkin/shaderslmfao/WaveShader.hx +++ b/source/funkin/shaderslmfao/WaveShader.hx @@ -4,7 +4,7 @@ import flixel.system.FlxAssets.FlxShader; class WaveShader extends FlxShader { - @:glFragmentSource(' + @:glFragmentSource(' #pragma header void main() @@ -15,8 +15,8 @@ class WaveShader extends FlxShader } ') - public function new() - { - super(); - } + public function new() + { + super(); + } } diff --git a/source/funkin/shaderslmfao/WiggleEffectRuntime.hx b/source/funkin/shaderslmfao/WiggleEffectRuntime.hx index cfa87f3d0..23f93b672 100644 --- a/source/funkin/shaderslmfao/WiggleEffectRuntime.hx +++ b/source/funkin/shaderslmfao/WiggleEffectRuntime.hx @@ -5,11 +5,11 @@ import openfl.Assets; enum WiggleEffectType { - DREAMY; // 0 - WAVY; // 1 - HEAT_WAVE_HORIZONTAL; // 2 - HEAT_WAVE_VERTICAL; // 3 - FLAG; // 4 + DREAMY; // 0 + WAVY; // 1 + HEAT_WAVE_HORIZONTAL; // 2 + HEAT_WAVE_VERTICAL; // 3 + FLAG; // 4 } /** @@ -20,65 +20,65 @@ enum WiggleEffectType */ class WiggleEffectRuntime extends FlxRuntimeShader { - public static function getEffectTypeId(v:WiggleEffectType):Int - { - return WiggleEffectType.getConstructors().indexOf(Std.string(v)); - } + public static function getEffectTypeId(v:WiggleEffectType):Int + { + return WiggleEffectType.getConstructors().indexOf(Std.string(v)); + } - public var effectType(default, set):WiggleEffectType = DREAMY; + public var effectType(default, set):WiggleEffectType = DREAMY; - function set_effectType(v:WiggleEffectType):WiggleEffectType - { - this.setInt('effectType', getEffectTypeId(v)); - return effectType = v; - } + function set_effectType(v:WiggleEffectType):WiggleEffectType + { + this.setInt('effectType', getEffectTypeId(v)); + return effectType = v; + } - public var waveSpeed(default, set):Float = 0; + public var waveSpeed(default, set):Float = 0; - function set_waveSpeed(v:Float):Float - { - this.setFloat('uSpeed', v); - return waveSpeed = v; - } + function set_waveSpeed(v:Float):Float + { + this.setFloat('uSpeed', v); + return waveSpeed = v; + } - public var waveFrequency(default, set):Float = 0; + public var waveFrequency(default, set):Float = 0; - function set_waveFrequency(v:Float):Float - { - this.setFloat('uFrequency', v); - return waveFrequency = v; - } + function set_waveFrequency(v:Float):Float + { + this.setFloat('uFrequency', v); + return waveFrequency = v; + } - public var waveAmplitude(default, set):Float = 0; + public var waveAmplitude(default, set):Float = 0; - function set_waveAmplitude(v:Float):Float - { - this.setFloat('uWaveAmplitude', v); - return waveAmplitude = v; - } + function set_waveAmplitude(v:Float):Float + { + this.setFloat('uWaveAmplitude', v); + return waveAmplitude = v; + } - var time(default, set):Float = 0; + var time(default, set):Float = 0; - function set_time(v:Float):Float - { - this.setFloat('uTime', v); - return time = v; - } + function set_time(v:Float):Float + { + this.setFloat('uTime', v); + return time = v; + } - public function new(speed:Float, freq:Float, amplitude:Float, ?effect:WiggleEffectType = DREAMY):Void - { - super(Assets.getText(Paths.frag('wiggle'))); + public function new(speed:Float, freq:Float, amplitude:Float, ?effect:WiggleEffectType = DREAMY):Void + { + super(Assets.getText(Paths.frag('wiggle'))); - // These values may not propagate to the shader until later. - this.waveSpeed = speed; - this.waveFrequency = freq; - this.waveAmplitude = amplitude; - this.effectType = effect; - } + // These values may not propagate to the shader until later. + this.waveSpeed = speed; + this.waveFrequency = freq; + this.waveAmplitude = amplitude; + this.effectType = effect; + } - public function update(elapsed:Float) - { - // The setter tied to this value automatically propagates the value to the shader. - this.time += elapsed; - } + public function update(elapsed:Float) + { + // The setter tied to this value automatically propagates the value to the shader. + this.time += elapsed; + } } diff --git a/source/funkin/ui/AtlasMenuList.hx b/source/funkin/ui/AtlasMenuList.hx index 053f387a1..028a00eef 100644 --- a/source/funkin/ui/AtlasMenuList.hx +++ b/source/funkin/ui/AtlasMenuList.hx @@ -10,30 +10,29 @@ typedef AtlasAsset = flixel.util.typeLimit.OneOfTwo; */ class AtlasMenuList extends MenuTypedList { - public var atlas:FlxAtlasFrames; + public var atlas:FlxAtlasFrames; - public function new(atlas, navControls:NavControls = Vertical, ?wrapMode) - { - super(navControls, wrapMode); + public function new(atlas, navControls:NavControls = Vertical, ?wrapMode) + { + super(navControls, wrapMode); - if (Std.isOfType(atlas, String)) - this.atlas = Paths.getSparrowAtlas(cast atlas); - else - this.atlas = cast atlas; - } + if (Std.isOfType(atlas, String)) this.atlas = Paths.getSparrowAtlas(cast atlas); + else + this.atlas = cast atlas; + } - public function createItem(x = 0.0, y = 0.0, name, callback, fireInstantly = false) - { - var item = new AtlasMenuItem(x, y, name, atlas, callback); - item.fireInstantly = fireInstantly; - return addItem(name, item); - } + public function createItem(x = 0.0, y = 0.0, name, callback, fireInstantly = false) + { + var item = new AtlasMenuItem(x, y, name, atlas, callback); + item.fireInstantly = fireInstantly; + return addItem(name, item); + } - override function destroy() - { - super.destroy(); - atlas = null; - } + override function destroy() + { + super.destroy(); + atlas = null; + } } /** @@ -41,56 +40,56 @@ class AtlasMenuList extends MenuTypedList */ class AtlasMenuItem extends MenuItem { - var atlas:FlxAtlasFrames; + var atlas:FlxAtlasFrames; - public var centered:Bool = false; + public var centered:Bool = false; - public function new(x = 0.0, y = 0.0, name:String, atlas, callback) - { - this.atlas = atlas; - super(x, y, name, callback); - } + public function new(x = 0.0, y = 0.0, name:String, atlas, callback) + { + this.atlas = atlas; + super(x, y, name, callback); + } - override function setData(name:String, ?callback:Void->Void) - { - frames = atlas; - animation.addByPrefix('idle', '$name idle', 24); - animation.addByPrefix('selected', '$name selected', 24); + override function setData(name:String, ?callback:Void->Void) + { + frames = atlas; + animation.addByPrefix('idle', '$name idle', 24); + animation.addByPrefix('selected', '$name selected', 24); - super.setData(name, callback); - } + super.setData(name, callback); + } - public function changeAnim(animName:String) - { - animation.play(animName); - updateHitbox(); + public function changeAnim(animName:String) + { + animation.play(animName); + updateHitbox(); - if (centered) - { - // position by center - centerOrigin(); - offset.copyFrom(origin); - } - } + if (centered) + { + // position by center + centerOrigin(); + offset.copyFrom(origin); + } + } - override function idle() - { - changeAnim('idle'); - } + override function idle() + { + changeAnim('idle'); + } - override function select() - { - changeAnim('selected'); - } + override function select() + { + changeAnim('selected'); + } - override function get_selected() - { - return animation.curAnim != null && animation.curAnim.name == "selected"; - } + override function get_selected() + { + return animation.curAnim != null && animation.curAnim.name == "selected"; + } - override function destroy() - { - super.destroy(); - atlas = null; - } + override function destroy() + { + super.destroy(); + atlas = null; + } } diff --git a/source/funkin/ui/AtlasText.hx b/source/funkin/ui/AtlasText.hx index b07aca240..857587a7b 100644 --- a/source/funkin/ui/AtlasText.hx +++ b/source/funkin/ui/AtlasText.hx @@ -11,272 +11,261 @@ import flixel.util.FlxStringUtil; */ class AtlasText extends FlxTypedSpriteGroup { - static var fonts = new Map(); - static var casesAllowed = new Map(); + static var fonts = new Map(); + static var casesAllowed = new Map(); - public var text(default, set):String = ""; + public var text(default, set):String = ""; - var font:AtlasFontData; + var font:AtlasFontData; - public var atlas(get, never):FlxAtlasFrames; + public var atlas(get, never):FlxAtlasFrames; - inline function get_atlas() - return font.atlas; + inline function get_atlas() + return font.atlas; - public var caseAllowed(get, never):Case; + public var caseAllowed(get, never):Case; - inline function get_caseAllowed() - return font.caseAllowed; + inline function get_caseAllowed() + return font.caseAllowed; - public var maxHeight(get, never):Float; + public var maxHeight(get, never):Float; - inline function get_maxHeight() - return font.maxHeight; + inline function get_maxHeight() + return font.maxHeight; - public function new(x = 0.0, y = 0.0, text:String, fontName:AtlasFont = AtlasFont.DEFAULT) - { - if (!fonts.exists(fontName)) - fonts[fontName] = new AtlasFontData(fontName); - font = fonts[fontName]; + public function new(x = 0.0, y = 0.0, text:String, fontName:AtlasFont = AtlasFont.DEFAULT) + { + if (!fonts.exists(fontName)) fonts[fontName] = new AtlasFontData(fontName); + font = fonts[fontName]; - super(x, y); + super(x, y); - this.text = text; - } + this.text = text; + } - function set_text(value:String) - { - if (value == null) - value = ""; + function set_text(value:String) + { + if (value == null) value = ""; - var caseValue = restrictCase(value); - var caseText = restrictCase(this.text); + var caseValue = restrictCase(value); + var caseText = restrictCase(this.text); - this.text = value; - if (caseText == caseValue) - return value; // cancel redraw + this.text = value; + if (caseText == caseValue) return value; // cancel redraw - if (caseValue.indexOf(caseText) == 0) - { - // new text is just old text with additions at the end, append the difference - appendTextCased(caseValue.substr(caseText.length)); - return this.text; - } + if (caseValue.indexOf(caseText) == 0) + { + // new text is just old text with additions at the end, append the difference + appendTextCased(caseValue.substr(caseText.length)); + return this.text; + } - value = caseValue; + value = caseValue; - group.kill(); + group.kill(); - if (value == "") - return this.text; + if (value == "") return this.text; - appendTextCased(caseValue); - return this.text; - } + appendTextCased(caseValue); + return this.text; + } - /** - * Adds new characters, without needing to redraw the previous characters - * @param text The text to add. - * @throws String if `text` is null. - */ - public function appendText(text:String) - { - if (text == null) - throw "cannot append null"; + /** + * Adds new characters, without needing to redraw the previous characters + * @param text The text to add. + * @throws String if `text` is null. + */ + public function appendText(text:String) + { + if (text == null) throw "cannot append null"; - if (text == "") - return; + if (text == "") return; - this.text = this.text + text; - } + this.text = this.text + text; + } - /** - * Converts all characters to fit the font's `allowedCase`. - * @param text - */ - function restrictCase(text:String) - { - return switch (caseAllowed) - { - case Both: text; - case Upper: text.toUpperCase(); - case Lower: text.toLowerCase(); - } - } + /** + * Converts all characters to fit the font's `allowedCase`. + * @param text + */ + function restrictCase(text:String) + { + return switch (caseAllowed) + { + case Both: text; + case Upper: text.toUpperCase(); + case Lower: text.toLowerCase(); + } + } - /** - * Adds new text on top of the existing text. Helper for other methods; DOESN'T CHANGE `this.text`. - * @param text The text to add, assumed to match the font's `caseAllowed`. - */ - function appendTextCased(text:String) - { - var charCount = group.countLiving(); - var xPos:Float = 0; - var yPos:Float = 0; - // `countLiving` returns -1 if group is empty - if (charCount == -1) - charCount = 0; - else if (charCount > 0) - { - var lastChar = group.members[charCount - 1]; - xPos = lastChar.x + lastChar.width - x; - yPos = lastChar.y + lastChar.height - maxHeight - y; - } + /** + * Adds new text on top of the existing text. Helper for other methods; DOESN'T CHANGE `this.text`. + * @param text The text to add, assumed to match the font's `caseAllowed`. + */ + function appendTextCased(text:String) + { + var charCount = group.countLiving(); + var xPos:Float = 0; + var yPos:Float = 0; + // `countLiving` returns -1 if group is empty + if (charCount == -1) charCount = 0; + else if (charCount > 0) + { + var lastChar = group.members[charCount - 1]; + xPos = lastChar.x + lastChar.width - x; + yPos = lastChar.y + lastChar.height - maxHeight - y; + } - var splitValues = text.split(""); - for (i in 0...splitValues.length) - { - switch (splitValues[i]) - { - case " ": - { - xPos += 40; - } - case "\n": - { - xPos = 0; - yPos += maxHeight; - } - case char: - { - var charSprite:AtlasChar; - if (group.members.length <= charCount) - charSprite = new AtlasChar(atlas, char); - else - { - charSprite = group.members[charCount]; - charSprite.revive(); - charSprite.char = char; - charSprite.alpha = 1; // gets multiplied when added - } - charSprite.x = xPos; - charSprite.y = yPos + maxHeight - charSprite.height; - add(charSprite); + var splitValues = text.split(""); + for (i in 0...splitValues.length) + { + switch (splitValues[i]) + { + case " ": + { + xPos += 40; + } + case "\n": + { + xPos = 0; + yPos += maxHeight; + } + case char: + { + var charSprite:AtlasChar; + if (group.members.length <= charCount) charSprite = new AtlasChar(atlas, char); + else + { + charSprite = group.members[charCount]; + charSprite.revive(); + charSprite.char = char; + charSprite.alpha = 1; // gets multiplied when added + } + charSprite.x = xPos; + charSprite.y = yPos + maxHeight - charSprite.height; + add(charSprite); - xPos += charSprite.width; - charCount++; - } - } - } - } + xPos += charSprite.width; + charCount++; + } + } + } + } - override function toString() - { - return "InputItem, " + FlxStringUtil.getDebugString([ - LabelValuePair.weak("x", x), - LabelValuePair.weak("y", y), - LabelValuePair.weak("text", text) - ]); - } + override function toString() + { + return "InputItem, " + FlxStringUtil.getDebugString([ + LabelValuePair.weak("x", x), + LabelValuePair.weak("y", y), + LabelValuePair.weak("text", text) + ]); + } } class AtlasChar extends FlxSprite { - public var char(default, set):String; + public var char(default, set):String; - public function new(x = 0.0, y = 0.0, atlas:FlxAtlasFrames, char:String) - { - super(x, y); - frames = atlas; - this.char = char; - antialiasing = true; - } + public function new(x = 0.0, y = 0.0, atlas:FlxAtlasFrames, char:String) + { + super(x, y); + frames = atlas; + this.char = char; + antialiasing = true; + } - function set_char(value:String) - { - if (this.char != value) - { - var prefix = getAnimPrefix(value); - animation.addByPrefix("anim", prefix, 24); - animation.play("anim"); - updateHitbox(); - } + function set_char(value:String) + { + if (this.char != value) + { + var prefix = getAnimPrefix(value); + animation.addByPrefix("anim", prefix, 24); + animation.play("anim"); + updateHitbox(); + } - return this.char = value; - } + return this.char = value; + } - function getAnimPrefix(char:String) - { - return switch (char) - { - case '&': return '-andpersand-'; - case "😠": '-angry faic-'; // TODO: Do multi-flag characters work? - case "'": '-apostraphie-'; - case "\\": '-back slash-'; - case ",": '-comma-'; - case '-': '-dash-'; - case '↓': '-down arrow-'; // U+2193 - case "”": '-end quote-'; // U+0022 - case "!": '-exclamation point-'; // U+0021 - case "/": '-forward slash-'; // U+002F - case '>': '-greater than-'; // U+003E - case '♥': '-heart-'; // U+2665 - case '♡': '-heart-'; - case '←': '-left arrow-'; // U+2190 - case '<': '-less than-'; // U+003C - case "*": '-multiply x-'; - case '.': '-period-'; // U+002E - case "?": '-question mark-'; - case '→': '-right arrow-'; // U+2192 - case "“": '-start quote-'; - case '↑': '-up arrow-'; // U+2191 + function getAnimPrefix(char:String) + { + return switch (char) + { + case '&': return '-andpersand-'; + case "😠": '-angry faic-'; // TODO: Do multi-flag characters work? + case "'": '-apostraphie-'; + case "\\": '-back slash-'; + case ",": '-comma-'; + case '-': '-dash-'; + case '↓': '-down arrow-'; // U+2193 + case "”": '-end quote-'; // U+0022 + case "!": '-exclamation point-'; // U+0021 + case "/": '-forward slash-'; // U+002F + case '>': '-greater than-'; // U+003E + case '♥': '-heart-'; // U+2665 + case '♡': '-heart-'; + case '←': '-left arrow-'; // U+2190 + case '<': '-less than-'; // U+003C + case "*": '-multiply x-'; + case '.': '-period-'; // U+002E + case "?": '-question mark-'; + case '→': '-right arrow-'; // U+2192 + case "“": '-start quote-'; + case '↑': '-up arrow-'; // U+2191 - // Default to getting the character itself. - default: char; - } - } + // Default to getting the character itself. + default: char; + } + } } private class AtlasFontData { - static public var upperChar = ~/^[A-Z]\d+$/; - static public var lowerChar = ~/^[a-z]\d+$/; + static public var upperChar = ~/^[A-Z]\d+$/; + static public var lowerChar = ~/^[a-z]\d+$/; - public var atlas:FlxAtlasFrames; - public var maxHeight:Float = 0.0; - public var caseAllowed:Case = Both; + public var atlas:FlxAtlasFrames; + public var maxHeight:Float = 0.0; + public var caseAllowed:Case = Both; - public function new(name:AtlasFont) - { - var fontName:String = name; - atlas = Paths.getSparrowAtlas('fonts/${fontName.toLowerCase()}'); - if (atlas == null) - { - FlxG.log.warn('Could not find font atlas for font "${fontName}".'); - return; - } + public function new(name:AtlasFont) + { + var fontName:String = name; + atlas = Paths.getSparrowAtlas('fonts/${fontName.toLowerCase()}'); + if (atlas == null) + { + FlxG.log.warn('Could not find font atlas for font "${fontName}".'); + return; + } - atlas.parent.destroyOnNoUse = false; - atlas.parent.persist = true; + atlas.parent.destroyOnNoUse = false; + atlas.parent.persist = true; - var containsUpper = false; - var containsLower = false; + var containsUpper = false; + var containsLower = false; - for (frame in atlas.frames) - { - maxHeight = Math.max(maxHeight, frame.frame.height); + for (frame in atlas.frames) + { + maxHeight = Math.max(maxHeight, frame.frame.height); - if (!containsUpper) - containsUpper = upperChar.match(frame.name); + if (!containsUpper) containsUpper = upperChar.match(frame.name); - if (!containsLower) - containsLower = lowerChar.match(frame.name); - } + if (!containsLower) containsLower = lowerChar.match(frame.name); + } - if (containsUpper != containsLower) - caseAllowed = containsUpper ? Upper : Lower; - } + if (containsUpper != containsLower) caseAllowed = containsUpper ? Upper : Lower; + } } enum Case { - Both; - Upper; - Lower; + Both; + Upper; + Lower; } enum abstract AtlasFont(String) from String to String { - var DEFAULT = "default"; - var BOLD = "bold"; + var DEFAULT = "default"; + var BOLD = "bold"; } diff --git a/source/funkin/ui/ColorsMenu.hx b/source/funkin/ui/ColorsMenu.hx index 84739058b..9ebccf1c9 100644 --- a/source/funkin/ui/ColorsMenu.hx +++ b/source/funkin/ui/ColorsMenu.hx @@ -8,64 +8,60 @@ import funkin.ui.OptionsState.Page; class ColorsMenu extends Page { - var curSelected:Int = 0; + var curSelected:Int = 0; - var grpNotes:FlxTypedGroup; + var grpNotes:FlxTypedGroup; - public function new() - { - super(); + public function new() + { + super(); - grpNotes = new FlxTypedGroup(); - add(grpNotes); + grpNotes = new FlxTypedGroup(); + add(grpNotes); - for (i in 0...4) - { - var note:Note = new Note(0, i); + for (i in 0...4) + { + var note:Note = new Note(0, i); - note.x = (100 * i) + i; - note.screenCenter(Y); + note.x = (100 * i) + i; + note.screenCenter(Y); - var _effectSpr:FlxEffectSprite = new FlxEffectSprite(note, [new FlxOutlineEffect(FlxOutlineMode.FAST, FlxColor.WHITE, 4, 1)]); - add(_effectSpr); - _effectSpr.y = 0; - _effectSpr.x = i * 130; - _effectSpr.antialiasing = true; - _effectSpr.scale.x = _effectSpr.scale.y = 0.7; - // _effectSpr.setGraphicSize(); - _effectSpr.height = note.height; - _effectSpr.width = note.width; + var _effectSpr:FlxEffectSprite = new FlxEffectSprite(note, [new FlxOutlineEffect(FlxOutlineMode.FAST, FlxColor.WHITE, 4, 1)]); + add(_effectSpr); + _effectSpr.y = 0; + _effectSpr.x = i * 130; + _effectSpr.antialiasing = true; + _effectSpr.scale.x = _effectSpr.scale.y = 0.7; + // _effectSpr.setGraphicSize(); + _effectSpr.height = note.height; + _effectSpr.width = note.width; - // _effectSpr.updateHitbox(); + // _effectSpr.updateHitbox(); - grpNotes.add(note); - } - } + grpNotes.add(note); + } + } - override function update(elapsed:Float) - { - if (controls.UI_RIGHT_P) - curSelected += 1; - if (controls.UI_LEFT_P) - curSelected -= 1; + override function update(elapsed:Float) + { + if (controls.UI_RIGHT_P) curSelected += 1; + if (controls.UI_LEFT_P) curSelected -= 1; - if (curSelected < 0) - curSelected = grpNotes.members.length - 1; - if (curSelected >= grpNotes.members.length) - curSelected = 0; + if (curSelected < 0) curSelected = grpNotes.members.length - 1; + if (curSelected >= grpNotes.members.length) curSelected = 0; - if (controls.UI_UP) - { - grpNotes.members[curSelected].colorSwap.update(elapsed * 0.3); - Note.arrowColors[curSelected] += elapsed * 0.3; - } + if (controls.UI_UP) + { + grpNotes.members[curSelected].colorSwap.update(elapsed * 0.3); + Note.arrowColors[curSelected] += elapsed * 0.3; + } - if (controls.UI_DOWN) - { - grpNotes.members[curSelected].colorSwap.update(-elapsed * 0.3); - Note.arrowColors[curSelected] += -elapsed * 0.3; - } + if (controls.UI_DOWN) + { + grpNotes.members[curSelected].colorSwap.update(-elapsed * 0.3); + Note.arrowColors[curSelected] += -elapsed * 0.3; + } - super.update(elapsed); - } + super.update(elapsed); + } } diff --git a/source/funkin/ui/ControlsMenu.hx b/source/funkin/ui/ControlsMenu.hx index e5e3e44b0..c9292d39e 100644 --- a/source/funkin/ui/ControlsMenu.hx +++ b/source/funkin/ui/ControlsMenu.hx @@ -14,340 +14,327 @@ import funkin.ui.TextMenuList; class ControlsMenu extends funkin.ui.OptionsState.Page { - inline static public var COLUMNS = 2; - static var controlList = Control.createAll(); - /* - * Defines groups of controls that cannot share inputs, like left and right. Say, if ACCEPT is Z, Back is X, - * if the player sets Back to Z it also set ACCEPT to X. This prevents the player from setting the controls in - * a way the prevents them from changing more controls or exiting the menu. - */ - static var controlGroups:Array> = [ - [NOTE_UP, NOTE_DOWN, NOTE_LEFT, NOTE_RIGHT], - [UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK] - ]; + inline static public var COLUMNS = 2; + static var controlList = Control.createAll(); + /* + * Defines groups of controls that cannot share inputs, like left and right. Say, if ACCEPT is Z, Back is X, + * if the player sets Back to Z it also set ACCEPT to X. This prevents the player from setting the controls in + * a way the prevents them from changing more controls or exiting the menu. + */ + static var controlGroups:Array> = [ + [NOTE_UP, NOTE_DOWN, NOTE_LEFT, NOTE_RIGHT], + [UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK] + ]; - var itemGroups:Array> = [for (i in 0...controlGroups.length) []]; + var itemGroups:Array> = [for (i in 0...controlGroups.length) []]; - var controlGrid:MenuTypedList; - var deviceList:TextMenuList; - var menuCamera:FlxCamera; - var prompt:Prompt; - var camFollow:FlxObject; - var labels:FlxTypedGroup; + var controlGrid:MenuTypedList; + var deviceList:TextMenuList; + var menuCamera:FlxCamera; + var prompt:Prompt; + var camFollow:FlxObject; + var labels:FlxTypedGroup; - var currentDevice:Device = Keys; - var deviceListSelected = false; + var currentDevice:Device = Keys; + var deviceListSelected = false; - public function new() - { - super(); + public function new() + { + super(); - menuCamera = new FlxCamera(); - FlxG.cameras.add(menuCamera, false); - menuCamera.bgColor = 0x0; - camera = menuCamera; + menuCamera = new FlxCamera(); + FlxG.cameras.add(menuCamera, false); + menuCamera.bgColor = 0x0; + camera = menuCamera; - labels = new FlxTypedGroup(); - var headers = new FlxTypedGroup(); - controlGrid = new MenuTypedList(Columns(COLUMNS), Vertical); + labels = new FlxTypedGroup(); + var headers = new FlxTypedGroup(); + controlGrid = new MenuTypedList(Columns(COLUMNS), Vertical); - add(labels); - add(headers); - add(controlGrid); + add(labels); + add(headers); + add(controlGrid); - if (FlxG.gamepads.numActiveGamepads > 0) - { - var devicesBg = new FlxSprite(); - devicesBg.makeGraphic(FlxG.width, 100, 0xFFfafd6d); - add(devicesBg); - deviceList = new TextMenuList(Horizontal, None); - add(deviceList); - deviceListSelected = true; + if (FlxG.gamepads.numActiveGamepads > 0) + { + var devicesBg = new FlxSprite(); + devicesBg.makeGraphic(FlxG.width, 100, 0xFFfafd6d); + add(devicesBg); + deviceList = new TextMenuList(Horizontal, None); + add(deviceList); + deviceListSelected = true; - var item; + var item; - item = deviceList.createItem("Keyboard", AtlasFont.BOLD, selectDevice.bind(Keys)); - item.x = FlxG.width / 2 - item.width - 30; - item.y = (devicesBg.height - item.height) / 2; + item = deviceList.createItem("Keyboard", AtlasFont.BOLD, selectDevice.bind(Keys)); + item.x = FlxG.width / 2 - item.width - 30; + item.y = (devicesBg.height - item.height) / 2; - item = deviceList.createItem("Gamepad", AtlasFont.BOLD, selectDevice.bind(Gamepad(FlxG.gamepads.firstActive.id))); - item.x = FlxG.width / 2 + 30; - item.y = (devicesBg.height - item.height) / 2; - } + item = deviceList.createItem("Gamepad", AtlasFont.BOLD, selectDevice.bind(Gamepad(FlxG.gamepads.firstActive.id))); + item.x = FlxG.width / 2 + 30; + item.y = (devicesBg.height - item.height) / 2; + } - // FlxG.debugger.drawDebug = true; - var y = deviceList == null ? 30 : 120; - var spacer = 70; - var currentHeader:String = null; - // list order is determined by enum order - for (i in 0...controlList.length) - { - var control = controlList[i]; - var name = control.getName(); - if (currentHeader != "UI_" && name.indexOf("UI_") == 0) - { - currentHeader = "UI_"; - headers.add(new AtlasText(0, y, "UI", AtlasFont.BOLD)).screenCenter(X); - y += spacer; - } - else if (currentHeader != "NOTE_" && name.indexOf("NOTE_") == 0) - { - currentHeader = "NOTE_"; - headers.add(new AtlasText(0, y, "NOTES", AtlasFont.BOLD)).screenCenter(X); - y += spacer; - } + // FlxG.debugger.drawDebug = true; + var y = deviceList == null ? 30 : 120; + var spacer = 70; + var currentHeader:String = null; + // list order is determined by enum order + for (i in 0...controlList.length) + { + var control = controlList[i]; + var name = control.getName(); + if (currentHeader != "UI_" && name.indexOf("UI_") == 0) + { + currentHeader = "UI_"; + headers.add(new AtlasText(0, y, "UI", AtlasFont.BOLD)).screenCenter(X); + y += spacer; + } + else if (currentHeader != "NOTE_" && name.indexOf("NOTE_") == 0) + { + currentHeader = "NOTE_"; + headers.add(new AtlasText(0, y, "NOTES", AtlasFont.BOLD)).screenCenter(X); + y += spacer; + } - if (currentHeader != null && name.indexOf(currentHeader) == 0) - name = name.substr(currentHeader.length); + if (currentHeader != null && name.indexOf(currentHeader) == 0) name = name.substr(currentHeader.length); - var label = labels.add(new AtlasText(150, y, name, AtlasFont.BOLD)); - label.alpha = 0.6; - for (i in 0...COLUMNS) - createItem(label.x + 400 + i * 300, y, control, i); + var label = labels.add(new AtlasText(150, y, name, AtlasFont.BOLD)); + label.alpha = 0.6; + for (i in 0...COLUMNS) + createItem(label.x + 400 + i * 300, y, control, i); - y += spacer; - } + y += spacer; + } - camFollow = new FlxObject(FlxG.width / 2, 0, 70, 70); - if (deviceList != null) - { - camFollow.y = deviceList.selectedItem.y; - controlGrid.selectedItem.idle(); - controlGrid.enabled = false; - } - else - camFollow.y = controlGrid.selectedItem.y; + camFollow = new FlxObject(FlxG.width / 2, 0, 70, 70); + if (deviceList != null) + { + camFollow.y = deviceList.selectedItem.y; + controlGrid.selectedItem.idle(); + controlGrid.enabled = false; + } + else + camFollow.y = controlGrid.selectedItem.y; - menuCamera.follow(camFollow, null, 0.06); - var margin = 100; - menuCamera.deadzone.set(0, margin, menuCamera.width, menuCamera.height - margin * 2); - menuCamera.minScrollY = 0; - controlGrid.onChange.add(function(selected) - { - camFollow.y = selected.y; + menuCamera.follow(camFollow, null, 0.06); + var margin = 100; + menuCamera.deadzone.set(0, margin, menuCamera.width, menuCamera.height - margin * 2); + menuCamera.minScrollY = 0; + controlGrid.onChange.add(function(selected) + { + camFollow.y = selected.y; - labels.forEach((label) -> label.alpha = 0.6); - labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0; - }); + labels.forEach((label) -> label.alpha = 0.6); + labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0; + }); - prompt = new Prompt("\nPress any key to rebind\n\n\n\n Escape to cancel", None); - prompt.create(); - prompt.createBgFromMargin(100, 0xFFfafd6d); - prompt.back.scrollFactor.set(0, 0); - prompt.exists = false; - add(prompt); - } + prompt = new Prompt("\nPress any key to rebind\n\n\n\n Escape to cancel", None); + prompt.create(); + prompt.createBgFromMargin(100, 0xFFfafd6d); + prompt.back.scrollFactor.set(0, 0); + prompt.exists = false; + add(prompt); + } - function createItem(x = 0.0, y = 0.0, control:Control, index:Int) - { - var item = new InputItem(x, y, currentDevice, control, index, onSelect); - for (i in 0...controlGroups.length) - { - if (controlGroups[i].contains(control)) - itemGroups[i].push(item); - } + function createItem(x = 0.0, y = 0.0, control:Control, index:Int) + { + var item = new InputItem(x, y, currentDevice, control, index, onSelect); + for (i in 0...controlGroups.length) + { + if (controlGroups[i].contains(control)) itemGroups[i].push(item); + } - return controlGrid.addItem(item.name, item); - } + return controlGrid.addItem(item.name, item); + } - function onSelect():Void - { - controlGrid.enabled = false; - canExit = false; - prompt.exists = true; - } + function onSelect():Void + { + controlGrid.enabled = false; + canExit = false; + prompt.exists = true; + } - function goToDeviceList() - { - controlGrid.selectedItem.idle(); - labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 0.6; - controlGrid.enabled = false; - deviceList.enabled = true; - canExit = true; - camFollow.y = deviceList.selectedItem.y; - deviceListSelected = true; - } + function goToDeviceList() + { + controlGrid.selectedItem.idle(); + labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 0.6; + controlGrid.enabled = false; + deviceList.enabled = true; + canExit = true; + camFollow.y = deviceList.selectedItem.y; + deviceListSelected = true; + } - function selectDevice(device:Device) - { - currentDevice = device; + function selectDevice(device:Device) + { + currentDevice = device; - for (item in controlGrid.members) - item.updateDevice(currentDevice); + for (item in controlGrid.members) + item.updateDevice(currentDevice); - var inputName = device == Keys ? "key" : "button"; - var cancel = device == Keys ? "Escape" : "Back"; - // todo: alignment - if (device == Keys) - prompt.setText('\nPress any key to rebind\n\n\n\n $cancel to cancel'); - else - prompt.setText('\nPress any button\n to rebind\n\n\n $cancel to cancel'); + var inputName = device == Keys ? "key" : "button"; + var cancel = device == Keys ? "Escape" : "Back"; + // todo: alignment + if (device == Keys) prompt.setText('\nPress any key to rebind\n\n\n\n $cancel to cancel'); + else + prompt.setText('\nPress any button\n to rebind\n\n\n $cancel to cancel'); - controlGrid.selectedItem.select(); - labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0; - controlGrid.enabled = true; - deviceList.enabled = false; - deviceListSelected = false; - canExit = false; - } + controlGrid.selectedItem.select(); + labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0; + controlGrid.enabled = true; + deviceList.enabled = false; + deviceListSelected = false; + canExit = false; + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - var controls = PlayerSettings.player1.controls; - if (controlGrid.enabled && deviceList != null && deviceListSelected == false && controls.BACK) - goToDeviceList(); + var controls = PlayerSettings.player1.controls; + if (controlGrid.enabled && deviceList != null && deviceListSelected == false && controls.BACK) goToDeviceList(); - if (prompt.exists) - { - switch (currentDevice) - { - case Keys: - { - // check released otherwise bugs can happen when you change the BACK key - var key = FlxG.keys.firstJustReleased(); - if (key != NONE) - { - if (key != ESCAPE) - onInputSelect(key); - closePrompt(); - } - } - case Gamepad(id): - { - var button = FlxG.gamepads.getByID(id).firstJustReleasedID(); - if (button != NONE) - { - if (button != BACK) - onInputSelect(button); - closePrompt(); - } - } - } - } - } + if (prompt.exists) + { + switch (currentDevice) + { + case Keys: + { + // check released otherwise bugs can happen when you change the BACK key + var key = FlxG.keys.firstJustReleased(); + if (key != NONE) + { + if (key != ESCAPE) onInputSelect(key); + closePrompt(); + } + } + case Gamepad(id): + { + var button = FlxG.gamepads.getByID(id).firstJustReleasedID(); + if (button != NONE) + { + if (button != BACK) onInputSelect(button); + closePrompt(); + } + } + } + } + } - function onInputSelect(input:Int) - { - var item = controlGrid.selectedItem; + function onInputSelect(input:Int) + { + var item = controlGrid.selectedItem; - // check if that key is already set for this - var column0 = Math.floor(controlGrid.selectedIndex / 2) * 2; - for (i in 0...COLUMNS) - { - if (controlGrid.members[column0 + i].input == input) - return; - } + // check if that key is already set for this + var column0 = Math.floor(controlGrid.selectedIndex / 2) * 2; + for (i in 0...COLUMNS) + { + if (controlGrid.members[column0 + i].input == input) return; + } - // Check if items in the same group already have the new input - for (group in itemGroups) - { - if (group.contains(item)) - { - for (otherItem in group) - { - if (otherItem != item && otherItem.input == input) - { - // replace that input with this items old input. - PlayerSettings.player1.controls.replaceBinding(otherItem.control, currentDevice, item.input, otherItem.input); - // Don't use resetItem() since items share names/labels - otherItem.input = item.input; - otherItem.label.text = item.label.text; - } - } - } - } + // Check if items in the same group already have the new input + for (group in itemGroups) + { + if (group.contains(item)) + { + for (otherItem in group) + { + if (otherItem != item && otherItem.input == input) + { + // replace that input with this items old input. + PlayerSettings.player1.controls.replaceBinding(otherItem.control, currentDevice, item.input, otherItem.input); + // Don't use resetItem() since items share names/labels + otherItem.input = item.input; + otherItem.label.text = item.label.text; + } + } + } + } - PlayerSettings.player1.controls.replaceBinding(item.control, currentDevice, input, item.input); - // Don't use resetItem() since items share names/labels - item.input = input; - item.label.text = item.getLabel(input); + PlayerSettings.player1.controls.replaceBinding(item.control, currentDevice, input, item.input); + // Don't use resetItem() since items share names/labels + item.input = input; + item.label.text = item.getLabel(input); - PlayerSettings.player1.saveControls(); - } + PlayerSettings.player1.saveControls(); + } - function closePrompt() - { - prompt.exists = false; - controlGrid.enabled = true; - if (deviceList == null) - canExit = true; - } + function closePrompt() + { + prompt.exists = false; + controlGrid.enabled = true; + if (deviceList == null) canExit = true; + } - override function destroy() - { - super.destroy(); + override function destroy() + { + super.destroy(); - itemGroups = null; + itemGroups = null; - if (FlxG.cameras.list.contains(menuCamera)) - FlxG.cameras.remove(menuCamera); - } + if (FlxG.cameras.list.contains(menuCamera)) FlxG.cameras.remove(menuCamera); + } - override function set_enabled(value:Bool) - { - if (value == false) - { - controlGrid.enabled = false; - if (deviceList != null) - deviceList.enabled = false; - } - else - { - controlGrid.enabled = !deviceListSelected; - if (deviceList != null) - deviceList.enabled = deviceListSelected; - } - return super.set_enabled(value); - } + override function set_enabled(value:Bool) + { + if (value == false) + { + controlGrid.enabled = false; + if (deviceList != null) deviceList.enabled = false; + } + else + { + controlGrid.enabled = !deviceListSelected; + if (deviceList != null) deviceList.enabled = deviceListSelected; + } + return super.set_enabled(value); + } } class InputItem extends TextMenuItem { - public var device(default, null):Device = Keys; - public var control:Control; - public var input:Int = -1; - public var index:Int = -1; + public var device(default, null):Device = Keys; + public var control:Control; + public var input:Int = -1; + public var index:Int = -1; - public function new(x = 0.0, y = 0.0, device, control, index, ?callback) - { - this.device = device; - this.control = control; - this.index = index; - this.input = getInput(); + public function new(x = 0.0, y = 0.0, device, control, index, ?callback) + { + this.device = device; + this.control = control; + this.index = index; + this.input = getInput(); - super(x, y, getLabel(input), DEFAULT, callback); - } + super(x, y, getLabel(input), DEFAULT, callback); + } - public function updateDevice(device:Device) - { - if (this.device != device) - { - this.device = device; - input = getInput(); - label.text = getLabel(input); - } - } + public function updateDevice(device:Device) + { + if (this.device != device) + { + this.device = device; + input = getInput(); + label.text = getLabel(input); + } + } - function getInput() - { - var list = PlayerSettings.player1.controls.getInputsFor(control, device); - if (list.length > index) - { - if (list[index] != FlxKey.ESCAPE || list[index] != FlxGamepadInputID.BACK) - return list[index]; + function getInput() + { + var list = PlayerSettings.player1.controls.getInputsFor(control, device); + if (list.length > index) + { + if (list[index] != FlxKey.ESCAPE || list[index] != FlxGamepadInputID.BACK) return list[index]; - if (list.length > ControlsMenu.COLUMNS) - // Escape isn't mappable, show a third option, instead. - return list[ControlsMenu.COLUMNS]; - } + if (list.length > ControlsMenu.COLUMNS) // Escape isn't mappable, show a third option, instead. + return list[ControlsMenu.COLUMNS]; + } - return -1; - } + return -1; + } - public function getLabel(input:Int) - { - return input == -1 ? "---" : InputFormatter.format(input, device); - } + public function getLabel(input:Int) + { + return input == -1 ? "---" : InputFormatter.format(input, device); + } } diff --git a/source/funkin/ui/CoolStatsGraph.hx b/source/funkin/ui/CoolStatsGraph.hx index 5857a29b5..d3c4c3895 100644 --- a/source/funkin/ui/CoolStatsGraph.hx +++ b/source/funkin/ui/CoolStatsGraph.hx @@ -19,144 +19,142 @@ import flixel.util.FlxDestroyUtil; #if FLX_DEBUG class CoolStatsGraph extends Sprite { - static inline var AXIS_COLOR:FlxColor = 0xffffff; - static inline var AXIS_ALPHA:Float = 0.5; - static inline var HISTORY_MAX:Int = 500; + static inline var AXIS_COLOR:FlxColor = 0xffffff; + static inline var AXIS_ALPHA:Float = 0.5; + static inline var HISTORY_MAX:Int = 500; - public var minLabel:TextField; - public var curLabel:TextField; - public var maxLabel:TextField; - public var avgLabel:TextField; + public var minLabel:TextField; + public var curLabel:TextField; + public var maxLabel:TextField; + public var avgLabel:TextField; - public var minValue:Float = FlxMath.MAX_VALUE_FLOAT; - public var maxValue:Float = FlxMath.MIN_VALUE_FLOAT; + public var minValue:Float = FlxMath.MAX_VALUE_FLOAT; + public var maxValue:Float = FlxMath.MIN_VALUE_FLOAT; - public var graphColor:FlxColor; + public var graphColor:FlxColor; - public var history:Array = []; + public var history:Array = []; - var _axis:Shape; - var _width:Int; - var _height:Int; - var _unit:String; - var _labelWidth:Int; - var _label:String; + var _axis:Shape; + var _width:Int; + var _height:Int; + var _unit:String; + var _labelWidth:Int; + var _label:String; - public function new(X:Int, Y:Int, Width:Int, Height:Int, GraphColor:FlxColor, Unit:String, LabelWidth:Int = 45, ?Label:String) - { - super(); - x = X; - y = Y; - _width = Width - LabelWidth; - _height = Height; - graphColor = GraphColor; - _unit = Unit; - _labelWidth = LabelWidth; - _label = (Label == null) ? "" : Label; + public function new(X:Int, Y:Int, Width:Int, Height:Int, GraphColor:FlxColor, Unit:String, LabelWidth:Int = 45, ?Label:String) + { + super(); + x = X; + y = Y; + _width = Width - LabelWidth; + _height = Height; + graphColor = GraphColor; + _unit = Unit; + _labelWidth = LabelWidth; + _label = (Label == null) ? "" : Label; - _axis = new Shape(); - _axis.x = _labelWidth + 10; + _axis = new Shape(); + _axis.x = _labelWidth + 10; - maxLabel = DebuggerUtil.createTextField(0, 0, Stats.LABEL_COLOR, Stats.TEXT_SIZE); - curLabel = DebuggerUtil.createTextField(0, (_height / 2) - (Stats.TEXT_SIZE / 2), graphColor, Stats.TEXT_SIZE); - minLabel = DebuggerUtil.createTextField(0, _height - Stats.TEXT_SIZE, Stats.LABEL_COLOR, Stats.TEXT_SIZE); + maxLabel = DebuggerUtil.createTextField(0, 0, Stats.LABEL_COLOR, Stats.TEXT_SIZE); + curLabel = DebuggerUtil.createTextField(0, (_height / 2) - (Stats.TEXT_SIZE / 2), graphColor, Stats.TEXT_SIZE); + minLabel = DebuggerUtil.createTextField(0, _height - Stats.TEXT_SIZE, Stats.LABEL_COLOR, Stats.TEXT_SIZE); - avgLabel = DebuggerUtil.createTextField(_labelWidth + 20, (_height / 2) - (Stats.TEXT_SIZE / 2) - 10, Stats.LABEL_COLOR, Stats.TEXT_SIZE); - avgLabel.width = _width; - avgLabel.defaultTextFormat.align = TextFormatAlign.CENTER; - avgLabel.alpha = 0.5; + avgLabel = DebuggerUtil.createTextField(_labelWidth + 20, (_height / 2) - (Stats.TEXT_SIZE / 2) - 10, Stats.LABEL_COLOR, Stats.TEXT_SIZE); + avgLabel.width = _width; + avgLabel.defaultTextFormat.align = TextFormatAlign.CENTER; + avgLabel.alpha = 0.5; - addChild(_axis); - addChild(maxLabel); - addChild(curLabel); - addChild(minLabel); - addChild(avgLabel); + addChild(_axis); + addChild(maxLabel); + addChild(curLabel); + addChild(minLabel); + addChild(avgLabel); - drawAxes(); - } + drawAxes(); + } - /** - * Redraws the axes of the graph. - */ - function drawAxes():Void - { - var gfx = _axis.graphics; - gfx.clear(); - gfx.lineStyle(1, AXIS_COLOR, AXIS_ALPHA); + /** + * Redraws the axes of the graph. + */ + function drawAxes():Void + { + var gfx = _axis.graphics; + gfx.clear(); + gfx.lineStyle(1, AXIS_COLOR, AXIS_ALPHA); - // y-Axis - gfx.moveTo(0, 0); - gfx.lineTo(0, _height); + // y-Axis + gfx.moveTo(0, 0); + gfx.lineTo(0, _height); - // x-Axis - gfx.moveTo(0, _height); - gfx.lineTo(_width, _height); - } + // x-Axis + gfx.moveTo(0, _height); + gfx.lineTo(_width, _height); + } - /** - * Redraws the graph based on the values stored in the history. - */ - function drawGraph():Void - { - var gfx:Graphics = graphics; - gfx.clear(); - gfx.lineStyle(1, graphColor, 1); + /** + * Redraws the graph based on the values stored in the history. + */ + function drawGraph():Void + { + var gfx:Graphics = graphics; + gfx.clear(); + gfx.lineStyle(1, graphColor, 1); - var inc:Float = _width / (HISTORY_MAX - 1); - var range:Float = Math.max(maxValue - minValue, maxValue * 0.1); - var graphX = _axis.x + 1; + var inc:Float = _width / (HISTORY_MAX - 1); + var range:Float = Math.max(maxValue - minValue, maxValue * 0.1); + var graphX = _axis.x + 1; - for (i in 0...history.length) - { - var value = (history[i] - minValue) / range; + for (i in 0...history.length) + { + var value = (history[i] - minValue) / range; - var pointY = (-value * _height - 1) + _height; - if (i == 0) - gfx.moveTo(graphX, _axis.y + pointY); - gfx.lineTo(graphX + (i * inc), pointY); - } - } + var pointY = (-value * _height - 1) + _height; + if (i == 0) gfx.moveTo(graphX, _axis.y + pointY); + gfx.lineTo(graphX + (i * inc), pointY); + } + } - public function update(Value:Float):Void - { - history.unshift(Value); - if (history.length > HISTORY_MAX) - history.pop(); + public function update(Value:Float):Void + { + history.unshift(Value); + if (history.length > HISTORY_MAX) history.pop(); - // Update range - maxValue = Math.max(maxValue, Value); - minValue = Math.min(minValue, Value); + // Update range + maxValue = Math.max(maxValue, Value); + minValue = Math.min(minValue, Value); - minLabel.text = formatValue(minValue); - curLabel.text = formatValue(Value); - maxLabel.text = formatValue(maxValue); + minLabel.text = formatValue(minValue); + curLabel.text = formatValue(Value); + maxLabel.text = formatValue(maxValue); - avgLabel.text = _label + "\nAvg: " + formatValue(average()); + avgLabel.text = _label + "\nAvg: " + formatValue(average()); - drawGraph(); - } + drawGraph(); + } - function formatValue(value:Float):String - { - return FlxMath.roundDecimal(value, Stats.DECIMALS) + " " + _unit; - } + function formatValue(value:Float):String + { + return FlxMath.roundDecimal(value, Stats.DECIMALS) + " " + _unit; + } - public function average():Float - { - var sum:Float = 0; - for (value in history) - sum += value; - return sum / history.length; - } + public function average():Float + { + var sum:Float = 0; + for (value in history) + sum += value; + return sum / history.length; + } - public function destroy():Void - { - _axis = FlxDestroyUtil.removeChild(this, _axis); - minLabel = FlxDestroyUtil.removeChild(this, minLabel); - curLabel = FlxDestroyUtil.removeChild(this, curLabel); - maxLabel = FlxDestroyUtil.removeChild(this, maxLabel); - avgLabel = FlxDestroyUtil.removeChild(this, avgLabel); - history = null; - } + public function destroy():Void + { + _axis = FlxDestroyUtil.removeChild(this, _axis); + minLabel = FlxDestroyUtil.removeChild(this, minLabel); + curLabel = FlxDestroyUtil.removeChild(this, curLabel); + maxLabel = FlxDestroyUtil.removeChild(this, maxLabel); + avgLabel = FlxDestroyUtil.removeChild(this, avgLabel); + history = null; + } } #end diff --git a/source/funkin/ui/MenuList.hx b/source/funkin/ui/MenuList.hx index 347415f70..61d44b960 100644 --- a/source/funkin/ui/MenuList.hx +++ b/source/funkin/ui/MenuList.hx @@ -8,370 +8,353 @@ import flixel.util.FlxSignal; class MenuTypedList extends FlxTypedGroup { - public var selectedIndex(default, null) = 0; - public var selectedItem(get, never):T; + public var selectedIndex(default, null) = 0; + public var selectedItem(get, never):T; - /** Called when a new item is highlighted */ - public var onChange(default, null) = new FlxTypedSignalVoid>(); + /** Called when a new item is highlighted */ + public var onChange(default, null) = new FlxTypedSignalVoid>(); - /** Called when an item is accepted */ - public var onAcceptPress(default, null) = new FlxTypedSignalVoid>(); + /** Called when an item is accepted */ + public var onAcceptPress(default, null) = new FlxTypedSignalVoid>(); - /** The navigation control scheme to use */ - public var navControls:NavControls; + /** The navigation control scheme to use */ + public var navControls:NavControls; - /** Set to false to disable nav control */ - public var enabled:Bool = true; + /** Set to false to disable nav control */ + public var enabled:Bool = true; - /** */ - public var wrapMode:WrapMode = Both; + /** */ + public var wrapMode:WrapMode = Both; - var byName = new Map(); + var byName = new Map(); - /** Set to true, internally to disable controls, without affecting vars like `enabled` */ - public var busy(default, null):Bool = false; + /** Set to true, internally to disable controls, without affecting vars like `enabled` */ + public var busy(default, null):Bool = false; - // bit awkward because BACK is also a menu control and this doesn't affect that + // bit awkward because BACK is also a menu control and this doesn't affect that - public function new(navControls:NavControls = Vertical, ?wrapMode:WrapMode) - { - this.navControls = navControls; + public function new(navControls:NavControls = Vertical, ?wrapMode:WrapMode) + { + this.navControls = navControls; - if (wrapMode != null) - this.wrapMode = wrapMode; - else - this.wrapMode = switch (navControls) - { - case Horizontal: Horizontal; - case Vertical: Vertical; - default: Both; - } - super(); - } + if (wrapMode != null) this.wrapMode = wrapMode; + else + this.wrapMode = switch (navControls) + { + case Horizontal: Horizontal; + case Vertical: Vertical; + default: Both; + } + super(); + } - public function addItem(name:String, item:T):T - { - if (length == selectedIndex) - item.select(); + public function addItem(name:String, item:T):T + { + if (length == selectedIndex) item.select(); - byName[name] = item; - return add(item); - } + byName[name] = item; + return add(item); + } - public function resetItem(oldName:String, newName:String, ?callback:Void->Void):T - { - if (!byName.exists(oldName)) - throw "No item named:" + oldName; + public function resetItem(oldName:String, newName:String, ?callback:Void->Void):T + { + if (!byName.exists(oldName)) throw "No item named:" + oldName; - var item = byName[oldName]; - byName.remove(oldName); - byName[newName] = item; - item.setItem(newName, callback); + var item = byName[oldName]; + byName.remove(oldName); + byName[newName] = item; + item.setItem(newName, callback); - return item; - } + return item; + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (enabled && !busy) - updateControls(); - } + if (enabled && !busy) updateControls(); + } - inline function updateControls() - { - var controls = PlayerSettings.player1.controls; + inline function updateControls() + { + var controls = PlayerSettings.player1.controls; - var wrapX = wrapMode.match(Horizontal | Both); - var wrapY = wrapMode.match(Vertical | Both); - var newIndex = switch (navControls) - { - case Vertical: navList(controls.UI_UP_P, controls.UI_DOWN_P, wrapY); - case Horizontal: navList(controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX); - case Both: navList(controls.UI_LEFT_P || controls.UI_UP_P, controls.UI_RIGHT_P || controls.UI_DOWN_P, !wrapMode.match(None)); + var wrapX = wrapMode.match(Horizontal | Both); + var wrapY = wrapMode.match(Vertical | Both); + var newIndex = switch (navControls) + { + case Vertical: navList(controls.UI_UP_P, controls.UI_DOWN_P, wrapY); + case Horizontal: navList(controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX); + case Both: navList(controls.UI_LEFT_P || controls.UI_UP_P, controls.UI_RIGHT_P || controls.UI_DOWN_P, !wrapMode.match(None)); - case Columns(num): navGrid(num, controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX, controls.UI_UP_P, controls.UI_DOWN_P, wrapY); - case Rows(num): navGrid(num, controls.UI_UP_P, controls.UI_DOWN_P, wrapY, controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX); - } + case Columns(num): navGrid(num, controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX, controls.UI_UP_P, controls.UI_DOWN_P, wrapY); + case Rows(num): navGrid(num, controls.UI_UP_P, controls.UI_DOWN_P, wrapY, controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX); + } - if (newIndex != selectedIndex) - { - FlxG.sound.play(Paths.sound('scrollMenu')); - selectItem(newIndex); - } + if (newIndex != selectedIndex) + { + FlxG.sound.play(Paths.sound('scrollMenu')); + selectItem(newIndex); + } - // Todo: bypass popup blocker on firefox - if (controls.ACCEPT) - accept(); - } + // Todo: bypass popup blocker on firefox + if (controls.ACCEPT) accept(); + } - function navAxis(index:Int, size:Int, prev:Bool, next:Bool, allowWrap:Bool):Int - { - if (prev == next) - return index; + function navAxis(index:Int, size:Int, prev:Bool, next:Bool, allowWrap:Bool):Int + { + if (prev == next) return index; - if (prev) - { - if (index > 0) - index--; - else if (allowWrap) - index = size - 1; - } - else - { - if (index < size - 1) - index++; - else if (allowWrap) - index = 0; - } + if (prev) + { + if (index > 0) index--; + else if (allowWrap) index = size - 1; + } + else + { + if (index < size - 1) index++; + else if (allowWrap) index = 0; + } - return index; - } + return index; + } - /** - * Controls navigation on a linear list of items such as Vertical. - * @param prev - * @param next - * @param allowWrap - */ - inline function navList(prev:Bool, next:Bool, allowWrap:Bool) - { - return navAxis(selectedIndex, length, prev, next, allowWrap); - } + /** + * Controls navigation on a linear list of items such as Vertical. + * @param prev + * @param next + * @param allowWrap + */ + inline function navList(prev:Bool, next:Bool, allowWrap:Bool) + { + return navAxis(selectedIndex, length, prev, next, allowWrap); + } - /** - * Controls navigation on a grid - * @param latSize The size of the fixed axis of the grid, or the "lateral axis" - * @param latPrev Whether the 'prev' key is pressed along the fixed-lengthed axis. eg: "left" in Column mode - * @param latNext Whether the 'next' key is pressed along the fixed-lengthed axis. eg: "right" in Column mode - * @param prev Whether the 'prev' key is pressed along the variable-lengthed axis. eg: "up" in Column mode - * @param next Whether the 'next' key is pressed along the variable-lengthed axis. eg: "down" in Column mode - * @param allowWrap unused - */ - function navGrid(latSize:Int, latPrev:Bool, latNext:Bool, latAllowWrap:Bool, prev:Bool, next:Bool, allowWrap:Bool):Int - { - // The grid lenth along the variable-length axis - var size = Math.ceil(length / latSize); - // The selected position along the variable-length axis - var index = Math.floor(selectedIndex / latSize); - // The selected position along the fixed axis - var latIndex = selectedIndex % latSize; + /** + * Controls navigation on a grid + * @param latSize The size of the fixed axis of the grid, or the "lateral axis" + * @param latPrev Whether the 'prev' key is pressed along the fixed-lengthed axis. eg: "left" in Column mode + * @param latNext Whether the 'next' key is pressed along the fixed-lengthed axis. eg: "right" in Column mode + * @param prev Whether the 'prev' key is pressed along the variable-lengthed axis. eg: "up" in Column mode + * @param next Whether the 'next' key is pressed along the variable-lengthed axis. eg: "down" in Column mode + * @param allowWrap unused + */ + function navGrid(latSize:Int, latPrev:Bool, latNext:Bool, latAllowWrap:Bool, prev:Bool, next:Bool, allowWrap:Bool):Int + { + // The grid lenth along the variable-length axis + var size = Math.ceil(length / latSize); + // The selected position along the variable-length axis + var index = Math.floor(selectedIndex / latSize); + // The selected position along the fixed axis + var latIndex = selectedIndex % latSize; - latIndex = navAxis(latIndex, latSize, latPrev, latNext, latAllowWrap); - index = navAxis(index, size, prev, next, allowWrap); + latIndex = navAxis(latIndex, latSize, latPrev, latNext, latAllowWrap); + index = navAxis(index, size, prev, next, allowWrap); - return Std.int(Math.min(length - 1, index * latSize + latIndex)); - } + return Std.int(Math.min(length - 1, index * latSize + latIndex)); + } - public function accept() - { - var selected = members[selectedIndex]; - onAcceptPress.dispatch(selected); + public function accept() + { + var selected = members[selectedIndex]; + onAcceptPress.dispatch(selected); - if (selected.fireInstantly) - selected.callback(); - else - { - busy = true; - FlxG.sound.play(Paths.sound('confirmMenu')); - FlxFlicker.flicker(selected, 1, 0.06, true, false, function(_) - { - busy = false; - selected.callback(); - }); - } - } + if (selected.fireInstantly) selected.callback(); + else + { + busy = true; + FlxG.sound.play(Paths.sound('confirmMenu')); + FlxFlicker.flicker(selected, 1, 0.06, true, false, function(_) + { + busy = false; + selected.callback(); + }); + } + } - public function selectItem(index:Int) - { - members[selectedIndex].idle(); + public function selectItem(index:Int) + { + members[selectedIndex].idle(); - selectedIndex = index; + selectedIndex = index; - var selected = members[selectedIndex]; - selected.select(); - onChange.dispatch(selected); - } + var selected = members[selectedIndex]; + selected.select(); + onChange.dispatch(selected); + } - public function has(name:String) - { - return byName.exists(name); - } + public function has(name:String) + { + return byName.exists(name); + } - public function getItem(name:String) - { - return byName[name]; - } + public function getItem(name:String) + { + return byName[name]; + } - override function destroy() - { - super.destroy(); - byName.clear(); - onChange.removeAll(); - onAcceptPress.removeAll(); - } + override function destroy() + { + super.destroy(); + byName.clear(); + onChange.removeAll(); + onAcceptPress.removeAll(); + } - inline function get_selectedItem():T - { - return members[selectedIndex]; - } + inline function get_selectedItem():T + { + return members[selectedIndex]; + } } class MenuItem extends FlxSprite { - public var callback:Void->Void; - public var name:String; + public var callback:Void->Void; + public var name:String; - /** - * Set to true for things like opening URLs otherwise, it may it get blocked. - */ - public var fireInstantly = false; + /** + * Set to true for things like opening URLs otherwise, it may it get blocked. + */ + public var fireInstantly = false; - public var selected(get, never):Bool; + public var selected(get, never):Bool; - function get_selected() - return alpha == 1.0; + function get_selected() + return alpha == 1.0; - public function new(x = 0.0, y = 0.0, name:String, callback) - { - super(x, y); + public function new(x = 0.0, y = 0.0, name:String, callback) + { + super(x, y); - antialiasing = true; - setData(name, callback); - idle(); - } + antialiasing = true; + setData(name, callback); + idle(); + } - function setData(name:String, ?callback:Void->Void) - { - this.name = name; + function setData(name:String, ?callback:Void->Void) + { + this.name = name; - if (callback != null) - this.callback = callback; - } + if (callback != null) this.callback = callback; + } - /** - * Calls setData and resets/redraws the state of the item - * @param name the label. - * @param callback Unchanged if null. - */ - public function setItem(name:String, ?callback:Void->Void) - { - setData(name, callback); + /** + * Calls setData and resets/redraws the state of the item + * @param name the label. + * @param callback Unchanged if null. + */ + public function setItem(name:String, ?callback:Void->Void) + { + setData(name, callback); - if (selected) - select(); - else - idle(); - } + if (selected) select(); + else + idle(); + } - public function idle() - { - alpha = 0.6; - } + public function idle() + { + alpha = 0.6; + } - public function select() - { - alpha = 1.0; - } + public function select() + { + alpha = 1.0; + } } class MenuTypedItem extends MenuItem { - public var label(default, set):T; + public var label(default, set):T; - public function new(x = 0.0, y = 0.0, label:T, name:String, callback) - { - super(x, y, name, callback); - // set label after super otherwise setters fuck up - this.label = label; - } + public function new(x = 0.0, y = 0.0, label:T, name:String, callback) + { + super(x, y, name, callback); + // set label after super otherwise setters fuck up + this.label = label; + } - /** - * Use this when you only want to show the label - */ - function setEmptyBackground() - { - var oldWidth = width; - var oldHeight = height; - makeGraphic(1, 1, 0x0); - width = oldWidth; - height = oldHeight; - } + /** + * Use this when you only want to show the label + */ + function setEmptyBackground() + { + var oldWidth = width; + var oldHeight = height; + makeGraphic(1, 1, 0x0); + width = oldWidth; + height = oldHeight; + } - function set_label(value:T) - { - if (value != null) - { - value.x = x; - value.y = y; - value.alpha = alpha; - } - return this.label = value; - } + function set_label(value:T) + { + if (value != null) + { + value.x = x; + value.y = y; + value.alpha = alpha; + } + return this.label = value; + } - override function update(elapsed:Float) - { - super.update(elapsed); - if (label != null) - label.update(elapsed); - } + override function update(elapsed:Float) + { + super.update(elapsed); + if (label != null) label.update(elapsed); + } - override function draw() - { - super.draw(); - if (label != null) - { - label.cameras = cameras; - label.scrollFactor.copyFrom(scrollFactor); - label.draw(); - } - } + override function draw() + { + super.draw(); + if (label != null) + { + label.cameras = cameras; + label.scrollFactor.copyFrom(scrollFactor); + label.draw(); + } + } - override function set_alpha(value:Float):Float - { - super.set_alpha(value); + override function set_alpha(value:Float):Float + { + super.set_alpha(value); - if (label != null) - label.alpha = alpha; + if (label != null) label.alpha = alpha; - return alpha; - } + return alpha; + } - override function set_x(value:Float):Float - { - super.set_x(value); + override function set_x(value:Float):Float + { + super.set_x(value); - if (label != null) - label.x = x; + if (label != null) label.x = x; - return x; - } + return x; + } - override function set_y(Value:Float):Float - { - super.set_y(Value); + override function set_y(Value:Float):Float + { + super.set_y(Value); - if (label != null) - label.y = y; + if (label != null) label.y = y; - return y; - } + return y; + } } enum NavControls { - Horizontal; - Vertical; - Both; - Columns(num:Int); - Rows(num:Int); + Horizontal; + Vertical; + Both; + Columns(num:Int); + Rows(num:Int); } enum WrapMode { - Horizontal; - Vertical; - Both; - None; + Horizontal; + Vertical; + Both; + None; } diff --git a/source/funkin/ui/ModMenu.hx b/source/funkin/ui/ModMenu.hx index 3d195e861..769d3eca2 100644 --- a/source/funkin/ui/ModMenu.hx +++ b/source/funkin/ui/ModMenu.hx @@ -9,127 +9,120 @@ import funkin.ui.OptionsState.Page; class ModMenu extends Page { - var grpMods:FlxTypedGroup; - var enabledMods:Array = []; - var detectedMods:Array = []; + var grpMods:FlxTypedGroup; + var enabledMods:Array = []; + var detectedMods:Array = []; - var curSelected:Int = 0; + var curSelected:Int = 0; - public function new():Void - { - super(); + public function new():Void + { + super(); - grpMods = new FlxTypedGroup(); - add(grpMods); + grpMods = new FlxTypedGroup(); + add(grpMods); - refreshModList(); - } + refreshModList(); + } - override function update(elapsed:Float) - { - if (FlxG.keys.justPressed.R) - refreshModList(); + override function update(elapsed:Float) + { + if (FlxG.keys.justPressed.R) refreshModList(); - selections(); + selections(); - if (controls.UI_UP_P) - selections(-1); - if (controls.UI_DOWN_P) - selections(1); + if (controls.UI_UP_P) selections(-1); + if (controls.UI_DOWN_P) selections(1); - if (FlxG.keys.justPressed.SPACE) - grpMods.members[curSelected].modEnabled = !grpMods.members[curSelected].modEnabled; + if (FlxG.keys.justPressed.SPACE) grpMods.members[curSelected].modEnabled = !grpMods.members[curSelected].modEnabled; - if (FlxG.keys.justPressed.I && curSelected != 0) - { - var oldOne = grpMods.members[curSelected - 1]; - grpMods.members[curSelected - 1] = grpMods.members[curSelected]; - grpMods.members[curSelected] = oldOne; - selections(-1); - } + if (FlxG.keys.justPressed.I && curSelected != 0) + { + var oldOne = grpMods.members[curSelected - 1]; + grpMods.members[curSelected - 1] = grpMods.members[curSelected]; + grpMods.members[curSelected] = oldOne; + selections(-1); + } - if (FlxG.keys.justPressed.K && curSelected < grpMods.members.length - 1) - { - var oldOne = grpMods.members[curSelected + 1]; - grpMods.members[curSelected + 1] = grpMods.members[curSelected]; - grpMods.members[curSelected] = oldOne; - selections(1); - } + if (FlxG.keys.justPressed.K && curSelected < grpMods.members.length - 1) + { + var oldOne = grpMods.members[curSelected + 1]; + grpMods.members[curSelected + 1] = grpMods.members[curSelected]; + grpMods.members[curSelected] = oldOne; + selections(1); + } - super.update(elapsed); - } + super.update(elapsed); + } - private function selections(change:Int = 0):Void - { - curSelected += change; + function selections(change:Int = 0):Void + { + curSelected += change; - if (curSelected >= detectedMods.length) - curSelected = 0; - if (curSelected < 0) - curSelected = detectedMods.length - 1; + if (curSelected >= detectedMods.length) curSelected = 0; + if (curSelected < 0) curSelected = detectedMods.length - 1; - for (txt in 0...grpMods.length) - { - if (txt == curSelected) - { - grpMods.members[txt].color = FlxColor.YELLOW; - } - else - grpMods.members[txt].color = FlxColor.WHITE; - } + for (txt in 0...grpMods.length) + { + if (txt == curSelected) + { + grpMods.members[txt].color = FlxColor.YELLOW; + } + else + grpMods.members[txt].color = FlxColor.WHITE; + } - organizeByY(); - } + organizeByY(); + } - private function refreshModList():Void - { - while (grpMods.members.length > 0) - { - grpMods.remove(grpMods.members[0], true); - } + function refreshModList():Void + { + while (grpMods.members.length > 0) + { + grpMods.remove(grpMods.members[0], true); + } - #if desktop - detectedMods = PolymodHandler.getAllMods(); + #if desktop + detectedMods = PolymodHandler.getAllMods(); - trace('ModMenu: Detected ${detectedMods.length} mods'); + trace('ModMenu: Detected ${detectedMods.length} mods'); - for (index in 0...detectedMods.length) - { - var modMetadata:ModMetadata = detectedMods[index]; - var modName:String = modMetadata.title; - var txt:ModMenuItem = new ModMenuItem(0, 10 + (40 * index), 0, modName, 32); - txt.text = modName; - grpMods.add(txt); - } - #end - } + for (index in 0...detectedMods.length) + { + var modMetadata:ModMetadata = detectedMods[index]; + var modName:String = modMetadata.title; + var txt:ModMenuItem = new ModMenuItem(0, 10 + (40 * index), 0, modName, 32); + txt.text = modName; + grpMods.add(txt); + } + #end + } - private function organizeByY():Void - { - for (i in 0...grpMods.length) - { - grpMods.members[i].y = 10 + (40 * i); - } - } + function organizeByY():Void + { + for (i in 0...grpMods.length) + { + grpMods.members[i].y = 10 + (40 * i); + } + } } class ModMenuItem extends FlxText { - public var modEnabled:Bool = false; - public var daMod:String; + public var modEnabled:Bool = false; + public var daMod:String; - public function new(x:Float, y:Float, w:Float, str:String, size:Int) - { - super(x, y, w, str, size); - } + public function new(x:Float, y:Float, w:Float, str:String, size:Int) + { + super(x, y, w, str, size); + } - override function update(elapsed:Float) - { - if (modEnabled) - alpha = 1; - else - alpha = 0.5; + override function update(elapsed:Float) + { + if (modEnabled) alpha = 1; + else + alpha = 0.5; - super.update(elapsed); - } + super.update(elapsed); + } } diff --git a/source/funkin/ui/NgPrompt.hx b/source/funkin/ui/NgPrompt.hx index 716880b11..9cb153fab 100644 --- a/source/funkin/ui/NgPrompt.hx +++ b/source/funkin/ui/NgPrompt.hx @@ -6,99 +6,99 @@ import funkin.ui.Prompt; class NgPrompt extends Prompt { - public function new(text:String, style:ButtonStyle = Yes_No) - { - super(text, style); - } + public function new(text:String, style:ButtonStyle = Yes_No) + { + super(text, style); + } - static public function showLogin() - { - return showLoginPrompt(true); - } + static public function showLogin() + { + return showLoginPrompt(true); + } - static public function showSavedSessionFailed() - { - return showLoginPrompt(false); - } + static public function showSavedSessionFailed() + { + return showLoginPrompt(false); + } - static function showLoginPrompt(fromUi:Bool) - { - var prompt = new NgPrompt("Talking to server...", None); - prompt.openCallback = NGio.login.bind(function popupLauncher(openPassportUrl) - { - var choiceMsg = fromUi ? #if web "Log in to Newgrounds?" #else null #end // User-input needed to allow popups - : "Your session has expired.\n Please login again."; + static function showLoginPrompt(fromUi:Bool) + { + var prompt = new NgPrompt("Talking to server...", None); + prompt.openCallback = NGio.login.bind(function popupLauncher(openPassportUrl) + { + var choiceMsg = fromUi ? #if web "Log in to Newgrounds?" #else null #end // User-input needed to allow popups + : "Your session has expired.\n Please login again."; - if (choiceMsg != null) - { - prompt.setText(choiceMsg); - prompt.setButtons(Yes_No); - #if web - prompt.buttons.getItem("yes").fireInstantly = true; - #end - prompt.onYes = function() - { - prompt.setText("Connecting..." #if web + "\n(check your popup blocker)" #end); - prompt.setButtons(None); - openPassportUrl(); - }; - prompt.onNo = function() - { - prompt.close(); - prompt = null; - NGio.cancelLogin(); - }; - } - else - { - prompt.setText("Connecting..."); - openPassportUrl(); - } - }, function onLoginComplete(result:ConnectionResult) - { - switch (result) - { - case Success: - { - prompt.setText("Login Successful"); - prompt.setButtons(Ok); - prompt.onYes = prompt.close; - } - case Fail(msg): - { - trace("Login Error:" + msg); - prompt.setText("Login failed"); - prompt.setButtons(Ok); - prompt.onYes = prompt.close; - } - case Cancelled: - { - if (prompt != null) - { - prompt.setText("Login cancelled by user"); - prompt.setButtons(Ok); - prompt.onYes = prompt.close; - } - else - trace("Login cancelled via prompt"); - } - } - }); + if (choiceMsg != null) + { + prompt.setText(choiceMsg); + prompt.setButtons(Yes_No); + #if web + prompt.buttons.getItem("yes").fireInstantly = true; + #end + prompt.onYes = function() + { + prompt.setText("Connecting..." #if web + "\n(check your popup blocker)" #end); + prompt.setButtons(None); + openPassportUrl(); + }; + prompt.onNo = function() + { + prompt.close(); + prompt = null; + NGio.cancelLogin(); + }; + } + else + { + prompt.setText("Connecting..."); + openPassportUrl(); + } + }, function onLoginComplete(result:ConnectionResult) + { + switch (result) + { + case Success: + { + prompt.setText("Login Successful"); + prompt.setButtons(Ok); + prompt.onYes = prompt.close; + } + case Fail(msg): + { + trace("Login Error:" + msg); + prompt.setText("Login failed"); + prompt.setButtons(Ok); + prompt.onYes = prompt.close; + } + case Cancelled: + { + if (prompt != null) + { + prompt.setText("Login cancelled by user"); + prompt.setButtons(Ok); + prompt.onYes = prompt.close; + } + else + trace("Login cancelled via prompt"); + } + } + }); - return prompt; - } + return prompt; + } - static public function showLogout() - { - var user = io.newgrounds.NG.core.user.name; - var prompt = new NgPrompt('Log out of $user?', Yes_No); - prompt.onYes = function() - { - NGio.logout(); - prompt.close(); - }; - prompt.onNo = prompt.close; - return prompt; - } + static public function showLogout() + { + var user = io.newgrounds.NG.core.user.name; + var prompt = new NgPrompt('Log out of $user?', Yes_No); + prompt.onYes = function() + { + NGio.logout(); + prompt.close(); + }; + prompt.onNo = prompt.close; + return prompt; + } } #end diff --git a/source/funkin/ui/OptionsState.hx b/source/funkin/ui/OptionsState.hx index a482394a1..2b93e7222 100644 --- a/source/funkin/ui/OptionsState.hx +++ b/source/funkin/ui/OptionsState.hx @@ -10,251 +10,246 @@ import funkin.util.WindowUtil; class OptionsState extends MusicBeatState { - var pages = new Map(); - var currentName:PageName = Options; - var currentPage(get, never):Page; + var pages = new Map(); + var currentName:PageName = Options; + var currentPage(get, never):Page; - inline function get_currentPage() - return pages[currentName]; + inline function get_currentPage() + return pages[currentName]; - override function create() - { - var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - menuBG.color = 0xFFea71fd; - menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); - menuBG.updateHitbox(); - menuBG.screenCenter(); - menuBG.scrollFactor.set(0, 0); - add(menuBG); + override function create() + { + var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + menuBG.color = 0xFFea71fd; + menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); + menuBG.updateHitbox(); + menuBG.screenCenter(); + menuBG.scrollFactor.set(0, 0); + add(menuBG); - var options = addPage(Options, new OptionsMenu()); - var preferences = addPage(Preferences, new PreferencesMenu()); - var controls = addPage(Controls, new ControlsMenu()); + var options = addPage(Options, new OptionsMenu()); + var preferences = addPage(Preferences, new PreferencesMenu()); + var controls = addPage(Controls, new ControlsMenu()); - if (options.hasMultipleOptions()) - { - options.onExit.add(exitToMainMenu); - controls.onExit.add(switchPage.bind(Options)); - preferences.onExit.add(switchPage.bind(Options)); - } - else - { - // No need to show Options page - controls.onExit.add(exitToMainMenu); - setPage(Controls); - } + if (options.hasMultipleOptions()) + { + options.onExit.add(exitToMainMenu); + controls.onExit.add(switchPage.bind(Options)); + preferences.onExit.add(switchPage.bind(Options)); + } + else + { + // No need to show Options page + controls.onExit.add(exitToMainMenu); + setPage(Controls); + } - // disable for intro transition - currentPage.enabled = false; - super.create(); - } + // disable for intro transition + currentPage.enabled = false; + super.create(); + } - function addPage(name:PageName, page:T) - { - page.onSwitch.add(switchPage); - pages[name] = page; - add(page); - page.exists = currentName == name; - return page; - } + function addPage(name:PageName, page:T) + { + page.onSwitch.add(switchPage); + pages[name] = page; + add(page); + page.exists = currentName == name; + return page; + } - function setPage(name:PageName) - { - if (pages.exists(currentName)) - { - currentPage.exists = false; - currentPage.visible = false; - } + function setPage(name:PageName) + { + if (pages.exists(currentName)) + { + currentPage.exists = false; + currentPage.visible = false; + } - currentName = name; + currentName = name; - if (pages.exists(currentName)) - { - currentPage.exists = true; - currentPage.visible = true; - } - } + if (pages.exists(currentName)) + { + currentPage.exists = true; + currentPage.visible = true; + } + } - override function finishTransIn() - { - super.finishTransIn(); + override function finishTransIn() + { + super.finishTransIn(); - currentPage.enabled = true; - } + currentPage.enabled = true; + } - function switchPage(name:PageName) - { - // Todo animate? - setPage(name); - } + function switchPage(name:PageName) + { + // Todo animate? + setPage(name); + } - function exitToMainMenu() - { - currentPage.enabled = false; - // TODO: Animate this transition? - FlxG.switchState(new MainMenuState()); - } + function exitToMainMenu() + { + currentPage.enabled = false; + // TODO: Animate this transition? + FlxG.switchState(new MainMenuState()); + } } class Page extends FlxGroup { - public var onSwitch(default, null) = new FlxTypedSignalVoid>(); - public var onExit(default, null) = new FlxSignal(); + public var onSwitch(default, null) = new FlxTypedSignalVoid>(); + public var onExit(default, null) = new FlxSignal(); - public var enabled(default, set) = true; - public var canExit = true; + public var enabled(default, set) = true; + public var canExit = true; - var controls(get, never):Controls; + var controls(get, never):Controls; - inline function get_controls() - return PlayerSettings.player1.controls; + inline function get_controls() + return PlayerSettings.player1.controls; - var subState:FlxSubState; + var subState:FlxSubState; - inline function switchPage(name:PageName) - { - onSwitch.dispatch(name); - } + inline function switchPage(name:PageName) + { + onSwitch.dispatch(name); + } - inline function exit() - { - onExit.dispatch(); - } + inline function exit() + { + onExit.dispatch(); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (enabled) - updateEnabled(elapsed); - } + if (enabled) updateEnabled(elapsed); + } - function updateEnabled(elapsed:Float) - { - if (canExit && controls.BACK) - { - FlxG.sound.play(Paths.sound('cancelMenu')); - exit(); - } - } + function updateEnabled(elapsed:Float) + { + if (canExit && controls.BACK) + { + FlxG.sound.play(Paths.sound('cancelMenu')); + exit(); + } + } - function set_enabled(value:Bool) - { - return this.enabled = value; - } + function set_enabled(value:Bool) + { + return this.enabled = value; + } - function openPrompt(prompt:Prompt, onClose:Void->Void) - { - enabled = false; - prompt.closeCallback = function() - { - enabled = true; - if (onClose != null) - onClose(); - } + function openPrompt(prompt:Prompt, onClose:Void->Void) + { + enabled = false; + prompt.closeCallback = function() + { + enabled = true; + if (onClose != null) onClose(); + } - FlxG.state.openSubState(prompt); - } + FlxG.state.openSubState(prompt); + } - override function destroy() - { - super.destroy(); - onSwitch.removeAll(); - } + override function destroy() + { + super.destroy(); + onSwitch.removeAll(); + } } class OptionsMenu extends Page { - var items:TextMenuList; + var items:TextMenuList; - public function new() - { - super(); + public function new() + { + super(); - add(items = new TextMenuList()); - createItem("PREFERENCES", function() switchPage(Preferences)); - createItem("CONTROLS", function() switchPage(Controls)); + add(items = new TextMenuList()); + createItem("PREFERENCES", function() switchPage(Preferences)); + createItem("CONTROLS", function() switchPage(Controls)); - #if newgrounds - if (NGio.isLoggedIn) - createItem("LOGOUT", selectLogout); - else - createItem("LOGIN", selectLogin); - #end - createItem("EXIT", exit); - } + #if newgrounds + if (NGio.isLoggedIn) createItem("LOGOUT", selectLogout); + else + createItem("LOGIN", selectLogin); + #end + createItem("EXIT", exit); + } - function createItem(name:String, callback:Void->Void, fireInstantly = false) - { - var item = items.createItem(0, 100 + items.length * 100, name, BOLD, callback); - item.fireInstantly = fireInstantly; - item.screenCenter(X); - return item; - } + function createItem(name:String, callback:Void->Void, fireInstantly = false) + { + var item = items.createItem(0, 100 + items.length * 100, name, BOLD, callback); + item.fireInstantly = fireInstantly; + item.screenCenter(X); + return item; + } - override function set_enabled(value:Bool) - { - items.enabled = value; - return super.set_enabled(value); - } + override function set_enabled(value:Bool) + { + items.enabled = value; + return super.set_enabled(value); + } - /** - * True if this page has multiple options, excluding the exit option. - * If false, there's no reason to ever show this page. - */ - public function hasMultipleOptions():Bool - { - return items.length > 2; - } + /** + * True if this page has multiple options, excluding the exit option. + * If false, there's no reason to ever show this page. + */ + public function hasMultipleOptions():Bool + { + return items.length > 2; + } - #if newgrounds - function selectLogin() - { - openNgPrompt(NgPrompt.showLogin()); - } + #if newgrounds + function selectLogin() + { + openNgPrompt(NgPrompt.showLogin()); + } - function selectLogout() - { - openNgPrompt(NgPrompt.showLogout()); - } + function selectLogout() + { + openNgPrompt(NgPrompt.showLogout()); + } - /** - * Calls openPrompt and redraws the login/logout button - * @param prompt - * @param onClose - */ - public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void) - { - var onPromptClose = checkLoginStatus; - if (onClose != null) - { - onPromptClose = function() - { - checkLoginStatus(); - onClose(); - } - } + /** + * Calls openPrompt and redraws the login/logout button + * @param prompt + * @param onClose + */ + public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void) + { + var onPromptClose = checkLoginStatus; + if (onClose != null) + { + onPromptClose = function() + { + checkLoginStatus(); + onClose(); + } + } - openPrompt(prompt, onPromptClose); - } + openPrompt(prompt, onPromptClose); + } - function checkLoginStatus() - { - // this shit don't work!! wtf!!!! - var prevLoggedIn = items.has("logout"); - if (prevLoggedIn && !NGio.isLoggedIn) - items.resetItem("logout", "login", selectLogin); - else if (!prevLoggedIn && NGio.isLoggedIn) - items.resetItem("login", "logout", selectLogout); - } - #end + function checkLoginStatus() + { + // this shit don't work!! wtf!!!! + var prevLoggedIn = items.has("logout"); + if (prevLoggedIn && !NGio.isLoggedIn) items.resetItem("logout", "login", selectLogin); + else if (!prevLoggedIn && NGio.isLoggedIn) items.resetItem("login", "logout", selectLogout); + } + #end } enum PageName { - Options; - Controls; - Colors; - Mods; - Preferences; + Options; + Controls; + Colors; + Mods; + Preferences; } diff --git a/source/funkin/ui/PopUpStuff.hx b/source/funkin/ui/PopUpStuff.hx index 8893e1fcd..4bcdde138 100644 --- a/source/funkin/ui/PopUpStuff.hx +++ b/source/funkin/ui/PopUpStuff.hx @@ -8,162 +8,162 @@ import funkin.util.Constants; class PopUpStuff extends FlxTypedGroup { - override public function new() - { - super(); - } + override public function new() + { + super(); + } - public function displayRating(daRating:String) - { - if (daRating == null) - daRating = "good"; + public function displayRating(daRating:String) + { + if (daRating == null) daRating = "good"; - var rating:FlxSprite = new FlxSprite(0, 0); - rating.scrollFactor.set(0.2, 0.2); + var rating:FlxSprite = new FlxSprite(0, 0); + rating.scrollFactor.set(0.2, 0.2); - rating.zIndex = 1000; - var ratingPath:String = daRating; + rating.zIndex = 1000; + var ratingPath:String = daRating; - if (PlayState.instance.currentStageId.startsWith('school')) - ratingPath = "weeb/pixelUI/" + ratingPath + "-pixel"; + if (PlayState.instance.currentStageId.startsWith('school')) ratingPath = "weeb/pixelUI/" + ratingPath + "-pixel"; - rating.loadGraphic(Paths.image(ratingPath)); - rating.x = FlxG.width * 0.50; - rating.x -= FlxG.camera.scroll.x * 0.2; - // make sure rating is visible lol! - // if (rating.x < FlxG.camera.scroll.x) - // rating.x = FlxG.camera.scroll.x; - // else if (rating.x > FlxG.camera.scroll.x + FlxG.camera.width - rating.width) - // rating.x = FlxG.camera.scroll.x + FlxG.camera.width - rating.width; + rating.loadGraphic(Paths.image(ratingPath)); + rating.x = FlxG.width * 0.50; + rating.x -= FlxG.camera.scroll.x * 0.2; + // make sure rating is visible lol! + // if (rating.x < FlxG.camera.scroll.x) + // rating.x = FlxG.camera.scroll.x; + // else if (rating.x > FlxG.camera.scroll.x + FlxG.camera.width - rating.width) + // rating.x = FlxG.camera.scroll.x + FlxG.camera.width - rating.width; - // FlxG.camera.scroll.y + - rating.y = FlxG.camera.height * 0.4 - 60; - rating.acceleration.y = 550; - rating.velocity.y -= FlxG.random.int(140, 175); - rating.velocity.x -= FlxG.random.int(0, 10); + // FlxG.camera.scroll.y + + rating.y = FlxG.camera.height * 0.4 - 60; + rating.acceleration.y = 550; + rating.velocity.y -= FlxG.random.int(140, 175); + rating.velocity.x -= FlxG.random.int(0, 10); - add(rating); + add(rating); - if (PlayState.instance.currentStageId.startsWith('school')) - { - rating.setGraphicSize(Std.int(rating.width * Constants.PIXEL_ART_SCALE * 0.7)); - } - else - { - rating.setGraphicSize(Std.int(rating.width * 0.7)); - rating.antialiasing = true; - } - rating.updateHitbox(); + if (PlayState.instance.currentStageId.startsWith('school')) + { + rating.setGraphicSize(Std.int(rating.width * Constants.PIXEL_ART_SCALE * 0.7)); + } + else + { + rating.setGraphicSize(Std.int(rating.width * 0.7)); + rating.antialiasing = true; + } + rating.updateHitbox(); - FlxTween.tween(rating, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - remove(rating, true); - rating.destroy(); - }, - startDelay: Conductor.crochet * 0.001 - }); - } + FlxTween.tween(rating, {alpha: 0}, 0.2, + { + onComplete: function(tween:FlxTween) + { + remove(rating, true); + rating.destroy(); + }, + startDelay: Conductor.crochet * 0.001 + }); + } - public function displayCombo(?combo:Int = 0):Int - { - if (combo == null) - combo = 0; + public function displayCombo(?combo:Int = 0):Int + { + if (combo == null) combo = 0; - var pixelShitPart1:String = ""; - var pixelShitPart2:String = ''; + var pixelShitPart1:String = ""; + var pixelShitPart2:String = ''; - if (PlayState.instance.currentStageId.startsWith('school')) - { - pixelShitPart1 = 'weeb/pixelUI/'; - pixelShitPart2 = '-pixel'; - } - var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); - comboSpr.y = FlxG.camera.height * 0.4 + 80; - comboSpr.x = FlxG.width * 0.50; - comboSpr.x -= FlxG.camera.scroll.x * 0.2; - // make sure combo is visible lol! - // 194 fits 4 combo digits - // if (comboSpr.x < FlxG.camera.scroll.x + 194) - // comboSpr.x = FlxG.camera.scroll.x + 194; - // else if (comboSpr.x > FlxG.camera.scroll.x + FlxG.camera.width - comboSpr.width) - // comboSpr.x = FlxG.camera.scroll.x + FlxG.camera.width - comboSpr.width; + if (PlayState.instance.currentStageId.startsWith('school')) + { + pixelShitPart1 = 'weeb/pixelUI/'; + pixelShitPart2 = '-pixel'; + } + var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'combo' + pixelShitPart2)); + comboSpr.y = FlxG.camera.height * 0.4 + 80; + comboSpr.x = FlxG.width * 0.50; + comboSpr.x -= FlxG.camera.scroll.x * 0.2; + // make sure combo is visible lol! + // 194 fits 4 combo digits + // if (comboSpr.x < FlxG.camera.scroll.x + 194) + // comboSpr.x = FlxG.camera.scroll.x + 194; + // else if (comboSpr.x > FlxG.camera.scroll.x + FlxG.camera.width - comboSpr.width) + // comboSpr.x = FlxG.camera.scroll.x + FlxG.camera.width - comboSpr.width; - comboSpr.acceleration.y = 600; - comboSpr.velocity.y -= 150; - comboSpr.velocity.x += FlxG.random.int(1, 10); + comboSpr.acceleration.y = 600; + comboSpr.velocity.y -= 150; + comboSpr.velocity.x += FlxG.random.int(1, 10); - add(comboSpr); + add(comboSpr); - if (PlayState.instance.currentStageId.startsWith('school')) - { - comboSpr.setGraphicSize(Std.int(comboSpr.width * Constants.PIXEL_ART_SCALE * 0.7)); - } - else - { - comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); - comboSpr.antialiasing = true; - } - comboSpr.updateHitbox(); + if (PlayState.instance.currentStageId.startsWith('school')) + { + comboSpr.setGraphicSize(Std.int(comboSpr.width * Constants.PIXEL_ART_SCALE * 0.7)); + } + else + { + comboSpr.setGraphicSize(Std.int(comboSpr.width * 0.7)); + comboSpr.antialiasing = true; + } + comboSpr.updateHitbox(); - FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - remove(comboSpr, true); - comboSpr.destroy(); - }, - startDelay: Conductor.crochet * 0.001 - }); + FlxTween.tween(comboSpr, {alpha: 0}, 0.2, + { + onComplete: function(tween:FlxTween) + { + remove(comboSpr, true); + comboSpr.destroy(); + }, + startDelay: Conductor.crochet * 0.001 + }); - var seperatedScore:Array = []; - var tempCombo:Int = combo; + var seperatedScore:Array = []; + var tempCombo:Int = combo; - while (tempCombo != 0) - { - seperatedScore.push(tempCombo % 10); - tempCombo = Std.int(tempCombo / 10); - } - while (seperatedScore.length < 3) - seperatedScore.push(0); + while (tempCombo != 0) + { + seperatedScore.push(tempCombo % 10); + tempCombo = Std.int(tempCombo / 10); + } + while (seperatedScore.length < 3) + seperatedScore.push(0); - // seperatedScore.reverse(); + // seperatedScore.reverse(); - var daLoop:Int = 1; - for (i in seperatedScore) - { - var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); - numScore.y = comboSpr.y; + var daLoop:Int = 1; + for (i in seperatedScore) + { + var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); + numScore.y = comboSpr.y; - if (PlayState.instance.currentStageId.startsWith('school')) - { - numScore.setGraphicSize(Std.int(numScore.width * Constants.PIXEL_ART_SCALE)); - } - else - { - numScore.antialiasing = true; - numScore.setGraphicSize(Std.int(numScore.width * 0.5)); - } - numScore.updateHitbox(); + if (PlayState.instance.currentStageId.startsWith('school')) + { + numScore.setGraphicSize(Std.int(numScore.width * Constants.PIXEL_ART_SCALE)); + } + else + { + numScore.antialiasing = true; + numScore.setGraphicSize(Std.int(numScore.width * 0.5)); + } + numScore.updateHitbox(); - numScore.x = comboSpr.x - (43 * daLoop); //- 90; - numScore.acceleration.y = FlxG.random.int(200, 300); - numScore.velocity.y -= FlxG.random.int(140, 160); - numScore.velocity.x = FlxG.random.float(-5, 5); + numScore.x = comboSpr.x - (43 * daLoop); //- 90; + numScore.acceleration.y = FlxG.random.int(200, 300); + numScore.velocity.y -= FlxG.random.int(140, 160); + numScore.velocity.x = FlxG.random.float(-5, 5); - add(numScore); + add(numScore); - FlxTween.tween(numScore, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - remove(numScore, true); - numScore.destroy(); - }, - startDelay: Conductor.crochet * 0.002 - }); + FlxTween.tween(numScore, {alpha: 0}, 0.2, + { + onComplete: function(tween:FlxTween) + { + remove(numScore, true); + numScore.destroy(); + }, + startDelay: Conductor.crochet * 0.002 + }); - daLoop++; - } + daLoop++; + } - return combo; - } + return combo; + } } diff --git a/source/funkin/ui/PreferencesMenu.hx b/source/funkin/ui/PreferencesMenu.hx index 94158bcce..1b6a6c6fd 100644 --- a/source/funkin/ui/PreferencesMenu.hx +++ b/source/funkin/ui/PreferencesMenu.hx @@ -9,209 +9,204 @@ import funkin.ui.TextMenuList.TextMenuItem; class PreferencesMenu extends Page { - public static var preferences:Map = new Map(); + public static var preferences:Map = new Map(); - var items:TextMenuList; + var items:TextMenuList; - var checkboxes:Array = []; - var menuCamera:FlxCamera; - var camFollow:FlxObject; + var checkboxes:Array = []; + var menuCamera:FlxCamera; + var camFollow:FlxObject; - public function new() - { - super(); + public function new() + { + super(); - menuCamera = new SwagCamera(); - FlxG.cameras.add(menuCamera, false); - menuCamera.bgColor = 0x0; - camera = menuCamera; + menuCamera = new SwagCamera(); + FlxG.cameras.add(menuCamera, false); + menuCamera.bgColor = 0x0; + camera = menuCamera; - add(items = new TextMenuList()); + add(items = new TextMenuList()); - createPrefItem('naughtyness', 'censor-naughty', true); - createPrefItem('downscroll', 'downscroll', false); - createPrefItem('flashing menu', 'flashing-menu', true); - createPrefItem('Camera Zooming on Beat', 'camera-zoom', true); - createPrefItem('FPS Counter', 'fps-counter', true); - createPrefItem('Auto Pause', 'auto-pause', false); + createPrefItem('naughtyness', 'censor-naughty', true); + createPrefItem('downscroll', 'downscroll', false); + createPrefItem('flashing menu', 'flashing-menu', true); + createPrefItem('Camera Zooming on Beat', 'camera-zoom', true); + createPrefItem('FPS Counter', 'fps-counter', true); + createPrefItem('Auto Pause', 'auto-pause', false); - camFollow = new FlxObject(FlxG.width / 2, 0, 140, 70); - if (items != null) - camFollow.y = items.selectedItem.y; + camFollow = new FlxObject(FlxG.width / 2, 0, 140, 70); + if (items != null) camFollow.y = items.selectedItem.y; - menuCamera.follow(camFollow, null, 0.06); - var margin = 160; - menuCamera.deadzone.set(0, margin, menuCamera.width, 40); - menuCamera.minScrollY = 0; + menuCamera.follow(camFollow, null, 0.06); + var margin = 160; + menuCamera.deadzone.set(0, margin, menuCamera.width, 40); + menuCamera.minScrollY = 0; - items.onChange.add(function(selected) - { - camFollow.y = selected.y; - }); - } + items.onChange.add(function(selected) + { + camFollow.y = selected.y; + }); + } - public static function getPref(pref:String):Dynamic - { - return preferences.get(pref); - } + public static function getPref(pref:String):Dynamic + { + return preferences.get(pref); + } - // easy shorthand? - public static function setPref(pref:String, value:Dynamic):Void - { - preferences.set(pref, value); - } + // easy shorthand? + public static function setPref(pref:String, value:Dynamic):Void + { + preferences.set(pref, value); + } - public static function initPrefs():Void - { - preferenceCheck('censor-naughty', true); - preferenceCheck('downscroll', false); - preferenceCheck('flashing-menu', true); - preferenceCheck('camera-zoom', true); - preferenceCheck('fps-counter', true); - preferenceCheck('auto-pause', false); - preferenceCheck('master-volume', 1); + public static function initPrefs():Void + { + preferenceCheck('censor-naughty', true); + preferenceCheck('downscroll', false); + preferenceCheck('flashing-menu', true); + preferenceCheck('camera-zoom', true); + preferenceCheck('fps-counter', true); + preferenceCheck('auto-pause', false); + preferenceCheck('master-volume', 1); - #if muted - setPref('master-volume', 0); - FlxG.sound.muted = true; - #end + #if muted + setPref('master-volume', 0); + FlxG.sound.muted = true; + #end - if (!getPref('fps-counter')) - FlxG.stage.removeChild(Main.fpsCounter); + if (!getPref('fps-counter')) FlxG.stage.removeChild(Main.fpsCounter); - FlxG.autoPause = getPref('auto-pause'); - } + FlxG.autoPause = getPref('auto-pause'); + } - private function createPrefItem(prefName:String, prefString:String, prefValue:Dynamic):Void - { - items.createItem(120, (120 * items.length) + 30, prefName, AtlasFont.BOLD, function() - { - preferenceCheck(prefString, prefValue); + function createPrefItem(prefName:String, prefString:String, prefValue:Dynamic):Void + { + items.createItem(120, (120 * items.length) + 30, prefName, AtlasFont.BOLD, function() + { + preferenceCheck(prefString, prefValue); - switch (Type.typeof(prefValue).getName()) - { - case 'TBool': - prefToggle(prefString); + switch (Type.typeof(prefValue).getName()) + { + case 'TBool': + prefToggle(prefString); - default: - trace('swag'); - } - }); + default: + trace('swag'); + } + }); - switch (Type.typeof(prefValue).getName()) - { - case 'TBool': - createCheckbox(prefString); + switch (Type.typeof(prefValue).getName()) + { + case 'TBool': + createCheckbox(prefString); - default: - trace('swag'); - } + default: + trace('swag'); + } - trace(Type.typeof(prefValue).getName()); - } + trace(Type.typeof(prefValue).getName()); + } - function createCheckbox(prefString:String) - { - var checkbox:CheckboxThingie = new CheckboxThingie(0, 120 * (items.length - 1), preferences.get(prefString)); - checkboxes.push(checkbox); - add(checkbox); - } + function createCheckbox(prefString:String) + { + var checkbox:CheckboxThingie = new CheckboxThingie(0, 120 * (items.length - 1), preferences.get(prefString)); + checkboxes.push(checkbox); + add(checkbox); + } - /** - * Assumes that the preference has already been checked/set? - */ - private function prefToggle(prefName:String) - { - var daSwap:Bool = preferences.get(prefName); - daSwap = !daSwap; - preferences.set(prefName, daSwap); - checkboxes[items.selectedIndex].daValue = daSwap; - trace('toggled? ' + preferences.get(prefName)); + /** + * Assumes that the preference has already been checked/set? + */ + function prefToggle(prefName:String) + { + var daSwap:Bool = preferences.get(prefName); + daSwap = !daSwap; + preferences.set(prefName, daSwap); + checkboxes[items.selectedIndex].daValue = daSwap; + trace('toggled? ' + preferences.get(prefName)); - switch (prefName) - { - case 'fps-counter': - if (getPref('fps-counter')) - FlxG.stage.addChild(Main.fpsCounter); - else - FlxG.stage.removeChild(Main.fpsCounter); - case 'auto-pause': - FlxG.autoPause = getPref('auto-pause'); - } + switch (prefName) + { + case 'fps-counter': + if (getPref('fps-counter')) FlxG.stage.addChild(Main.fpsCounter); + else + FlxG.stage.removeChild(Main.fpsCounter); + case 'auto-pause': + FlxG.autoPause = getPref('auto-pause'); + } - if (prefName == 'fps-counter') {} - } + if (prefName == 'fps-counter') {} + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - // menuCamera.followLerp = CoolUtil.camLerpShit(0.05); + // menuCamera.followLerp = CoolUtil.camLerpShit(0.05); - items.forEach(function(daItem:TextMenuItem) - { - if (items.selectedItem == daItem) - daItem.x = 150; - else - daItem.x = 120; - }); - } + items.forEach(function(daItem:TextMenuItem) + { + if (items.selectedItem == daItem) daItem.x = 150; + else + daItem.x = 120; + }); + } - private static function preferenceCheck(prefString:String, defaultValue:Dynamic):Void - { - if (preferences.get(prefString) == null) - { - // Set the value to default. - preferences.set(prefString, defaultValue); - trace('Set preference to default: ${prefString} = ${defaultValue}'); - } - else - { - trace('Found preference: ${prefString} = ${preferences.get(prefString)}'); - } - } + static function preferenceCheck(prefString:String, defaultValue:Dynamic):Void + { + if (preferences.get(prefString) == null) + { + // Set the value to default. + preferences.set(prefString, defaultValue); + trace('Set preference to default: ${prefString} = ${defaultValue}'); + } + else + { + trace('Found preference: ${prefString} = ${preferences.get(prefString)}'); + } + } } class CheckboxThingie extends FlxSprite { - public var daValue(default, set):Bool; + public var daValue(default, set):Bool; - public function new(x:Float, y:Float, daValue:Bool = false) - { - super(x, y); + public function new(x:Float, y:Float, daValue:Bool = false) + { + super(x, y); - frames = Paths.getSparrowAtlas('checkboxThingie'); - animation.addByPrefix('static', 'Check Box unselected', 24, false); - animation.addByPrefix('checked', 'Check Box selecting animation', 24, false); + frames = Paths.getSparrowAtlas('checkboxThingie'); + animation.addByPrefix('static', 'Check Box unselected', 24, false); + animation.addByPrefix('checked', 'Check Box selecting animation', 24, false); - antialiasing = true; + antialiasing = true; - setGraphicSize(Std.int(width * 0.7)); - updateHitbox(); + setGraphicSize(Std.int(width * 0.7)); + updateHitbox(); - this.daValue = daValue; - } + this.daValue = daValue; + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - switch (animation.curAnim.name) - { - case 'static': - offset.set(); - case 'checked': - offset.set(17, 70); - } - } + switch (animation.curAnim.name) + { + case 'static': + offset.set(); + case 'checked': + offset.set(17, 70); + } + } - function set_daValue(value:Bool):Bool - { - if (value) - animation.play('checked', true); - else - animation.play('static'); + function set_daValue(value:Bool):Bool + { + if (value) animation.play('checked', true); + else + animation.play('static'); - return value; - } + return value; + } } diff --git a/source/funkin/ui/Prompt.hx b/source/funkin/ui/Prompt.hx index 76d85744b..eebeb5aea 100644 --- a/source/funkin/ui/Prompt.hx +++ b/source/funkin/ui/Prompt.hx @@ -9,114 +9,114 @@ import funkin.ui.MenuList; */ class Prompt extends flixel.FlxSubState { - inline static var MARGIN = 100; + inline static var MARGIN = 100; - public var onYes:Void->Void; - public var onNo:Void->Void; - public var buttons:TextMenuList; - public var field:AtlasText; - public var back:FlxSprite; + public var onYes:Void->Void; + public var onNo:Void->Void; + public var buttons:TextMenuList; + public var field:AtlasText; + public var back:FlxSprite; - var style:ButtonStyle; + var style:ButtonStyle; - public function new(text:String, style:ButtonStyle = Ok) - { - this.style = style; - super(0x80000000); + public function new(text:String, style:ButtonStyle = Ok) + { + this.style = style; + super(0x80000000); - buttons = new TextMenuList(Horizontal); + buttons = new TextMenuList(Horizontal); - field = new AtlasText(text, AtlasFont.BOLD); - field.scrollFactor.set(0, 0); - } + field = new AtlasText(text, AtlasFont.BOLD); + field.scrollFactor.set(0, 0); + } - override function create() - { - super.create(); + override function create() + { + super.create(); - field.y = MARGIN; - field.screenCenter(X); - add(field); + field.y = MARGIN; + field.screenCenter(X); + add(field); - createButtons(); - add(buttons); - } + createButtons(); + add(buttons); + } - public function createBg(width:Int, height:Int, color = 0xFF808080) - { - back = new FlxSprite(); - back.makeGraphic(width, height, color, false, "prompt-bg"); - back.screenCenter(XY); - add(back); - members.unshift(members.pop()); // bring to front - } + public function createBg(width:Int, height:Int, color = 0xFF808080) + { + back = new FlxSprite(); + back.makeGraphic(width, height, color, false, "prompt-bg"); + back.screenCenter(XY); + add(back); + members.unshift(members.pop()); // bring to front + } - public function createBgFromMargin(margin = MARGIN, color = 0xFF808080) - { - createBg(Std.int(FlxG.width - margin * 2), Std.int(FlxG.height - margin * 2), color); - } + public function createBgFromMargin(margin = MARGIN, color = 0xFF808080) + { + createBg(Std.int(FlxG.width - margin * 2), Std.int(FlxG.height - margin * 2), color); + } - public function setButtons(style:ButtonStyle) - { - if (this.style != style) - { - this.style = style; - createButtons(); - } - } + public function setButtons(style:ButtonStyle) + { + if (this.style != style) + { + this.style = style; + createButtons(); + } + } - function createButtons() - { - // destroy previous buttons - while (buttons.members.length > 0) - { - buttons.remove(buttons.members[0], true).destroy(); - } + function createButtons() + { + // destroy previous buttons + while (buttons.members.length > 0) + { + buttons.remove(buttons.members[0], true).destroy(); + } - switch (style) - { - case Yes_No: - createButtonsHelper("yes", "no"); - case Ok: - createButtonsHelper("ok"); - case Custom(yes, no): - createButtonsHelper(yes, no); - case None: - buttons.exists = false; - }; - } + switch (style) + { + case Yes_No: + createButtonsHelper("yes", "no"); + case Ok: + createButtonsHelper("ok"); + case Custom(yes, no): + createButtonsHelper(yes, no); + case None: + buttons.exists = false; + }; + } - function createButtonsHelper(yes:String, ?no:String) - { - buttons.exists = true; - // pass anonymous functions rather than the current callbacks, in case they change later - var yesButton = buttons.createItem(yes, function() onYes()); - yesButton.screenCenter(X); - yesButton.y = FlxG.height - yesButton.height - MARGIN; - yesButton.scrollFactor.set(0, 0); - if (no != null) - { - // place right - yesButton.x = FlxG.width - yesButton.width - MARGIN; + function createButtonsHelper(yes:String, ?no:String) + { + buttons.exists = true; + // pass anonymous functions rather than the current callbacks, in case they change later + var yesButton = buttons.createItem(yes, function() onYes()); + yesButton.screenCenter(X); + yesButton.y = FlxG.height - yesButton.height - MARGIN; + yesButton.scrollFactor.set(0, 0); + if (no != null) + { + // place right + yesButton.x = FlxG.width - yesButton.width - MARGIN; - var noButton = buttons.createItem(no, function() onNo()); - noButton.x = MARGIN; - noButton.y = FlxG.height - noButton.height - MARGIN; - noButton.scrollFactor.set(0, 0); - } - } + var noButton = buttons.createItem(no, function() onNo()); + noButton.x = MARGIN; + noButton.y = FlxG.height - noButton.height - MARGIN; + noButton.scrollFactor.set(0, 0); + } + } - public function setText(text:String) - { - field.text = text; - field.screenCenter(X); - } + public function setText(text:String) + { + field.text = text; + field.screenCenter(X); + } } enum ButtonStyle { - Ok; - Yes_No; - Custom(yes:String, no:Null); // Todo: more than 2 - None; + Ok; + Yes_No; + Custom(yes:String, no:Null); // Todo: more than 2 + None; } diff --git a/source/funkin/ui/TallyCounter.hx b/source/funkin/ui/TallyCounter.hx index 386179b1c..bcc39ca7b 100644 --- a/source/funkin/ui/TallyCounter.hx +++ b/source/funkin/ui/TallyCounter.hx @@ -12,77 +12,75 @@ import flixel.tweens.FlxTween; */ class TallyCounter extends FlxTypedSpriteGroup { - public var curNumber:Float = 0; + public var curNumber:Float = 0; - public var neededNumber:Int = 0; - public var flavour:Int = 0xFFFFFFFF; + public var neededNumber:Int = 0; + public var flavour:Int = 0xFFFFFFFF; - public function new(x:Float, y:Float, neededNumber:Int = 0, ?flavour:Int = 0xFFFFFFFF) - { - super(x, y); + public function new(x:Float, y:Float, neededNumber:Int = 0, ?flavour:Int = 0xFFFFFFFF) + { + super(x, y); - this.flavour = flavour; + this.flavour = flavour; - this.neededNumber = neededNumber; - drawNumbers(); - } + this.neededNumber = neededNumber; + drawNumbers(); + } - var tmr:Float = 0; + var tmr:Float = 0; - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (curNumber < neededNumber) - drawNumbers(); - } + if (curNumber < neededNumber) drawNumbers(); + } - function drawNumbers() - { - var seperatedScore:Array = []; - var tempCombo:Int = Math.round(curNumber); + function drawNumbers() + { + var seperatedScore:Array = []; + var tempCombo:Int = Math.round(curNumber); - while (tempCombo != 0) - { - seperatedScore.push(tempCombo % 10); - tempCombo = Math.floor(tempCombo / 10); - } + while (tempCombo != 0) + { + seperatedScore.push(tempCombo % 10); + tempCombo = Math.floor(tempCombo / 10); + } - if (seperatedScore.length == 0) - seperatedScore.push(0); + if (seperatedScore.length == 0) seperatedScore.push(0); - seperatedScore.reverse(); + seperatedScore.reverse(); - for (ind => num in seperatedScore) - { - if (ind >= members.length) - { - var numb:TallyNumber = new TallyNumber(ind * 43, 0, num); - add(numb); - numb.color = flavour; - } - else - { - members[ind].animation.play(Std.string(num)); - members[ind].color = flavour; - } - } - } + for (ind => num in seperatedScore) + { + if (ind >= members.length) + { + var numb:TallyNumber = new TallyNumber(ind * 43, 0, num); + add(numb); + numb.color = flavour; + } + else + { + members[ind].animation.play(Std.string(num)); + members[ind].color = flavour; + } + } + } } class TallyNumber extends FlxSprite { - public function new(x:Float, y:Float, digit:Int) - { - super(x, y); + public function new(x:Float, y:Float, digit:Int) + { + super(x, y); - frames = Paths.getSparrowAtlas("resultScreen/tallieNumber"); + frames = Paths.getSparrowAtlas("resultScreen/tallieNumber"); - for (i in 0...10) - animation.addByPrefix(Std.string(i), i + " small", 24, false); + for (i in 0...10) + animation.addByPrefix(Std.string(i), i + " small", 24, false); - animation.play(Std.string(digit)); - antialiasing = true; - updateHitbox(); - } + animation.play(Std.string(digit)); + antialiasing = true; + updateHitbox(); + } } diff --git a/source/funkin/ui/TextMenuList.hx b/source/funkin/ui/TextMenuList.hx index fe1a13a7c..0c9f9eb8b 100644 --- a/source/funkin/ui/TextMenuList.hx +++ b/source/funkin/ui/TextMenuList.hx @@ -5,52 +5,52 @@ import funkin.ui.MenuList; class TextMenuList extends MenuTypedList { - public function new(navControls:NavControls = Vertical, ?wrapMode) - { - super(navControls, wrapMode); - } + public function new(navControls:NavControls = Vertical, ?wrapMode) + { + super(navControls, wrapMode); + } - public function createItem(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, callback, fireInstantly = false) - { - var item = new TextMenuItem(x, y, name, font, callback); - item.fireInstantly = fireInstantly; - return addItem(name, item); - } + public function createItem(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, callback, fireInstantly = false) + { + var item = new TextMenuItem(x, y, name, font, callback); + item.fireInstantly = fireInstantly; + return addItem(name, item); + } } class TextMenuItem extends TextTypedMenuItem { - public function new(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, callback) - { - super(x, y, new AtlasText(0, 0, name, font), name, callback); - setEmptyBackground(); - } + public function new(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, callback) + { + super(x, y, new AtlasText(0, 0, name, font), name, callback); + setEmptyBackground(); + } } class TextTypedMenuItem extends MenuTypedItem { - public function new(x = 0.0, y = 0.0, label:T, name:String, callback) - { - super(x, y, label, name, callback); - } + public function new(x = 0.0, y = 0.0, label:T, name:String, callback) + { + super(x, y, label, name, callback); + } - override function setItem(name:String, ?callback:Void->Void) - { - if (label != null) - { - label.text = name; - label.alpha = alpha; - width = label.width; - height = label.height; - } + override function setItem(name:String, ?callback:Void->Void) + { + if (label != null) + { + label.text = name; + label.alpha = alpha; + width = label.width; + height = label.height; + } - super.setItem(name, callback); - } + super.setItem(name, callback); + } - override function set_label(value:T):T - { - super.set_label(value); - setItem(name, callback); - return value; - } + override function set_label(value:T):T + { + super.set_label(value); + setItem(name, callback); + return value; + } } diff --git a/source/funkin/ui/animDebugShit/DebugBoundingState.hx b/source/funkin/ui/animDebugShit/DebugBoundingState.hx index af84ed117..339bf15ac 100644 --- a/source/funkin/ui/animDebugShit/DebugBoundingState.hx +++ b/source/funkin/ui/animDebugShit/DebugBoundingState.hx @@ -44,526 +44,511 @@ import sys.io.File; class DebugBoundingState extends FlxState { - /* - TODAY'S TO-DO - - Cleaner UI - */ - var bg:FlxSprite; - var fileInfo:FlxText; + /* + TODAY'S TO-DO + - Cleaner UI + */ + var bg:FlxSprite; + var fileInfo:FlxText; - var txtGrp:FlxGroup; + var txtGrp:FlxGroup; - var hudCam:FlxCamera; + var hudCam:FlxCamera; - var curView:ANIMDEBUGVIEW = SPRITESHEET; + var curView:ANIMDEBUGVIEW = SPRITESHEET; - var spriteSheetView:FlxGroup; - var offsetView:FlxGroup; - var animDropDownMenu:FlxUIDropDownMenu; - var dropDownSetup:Bool = false; + var spriteSheetView:FlxGroup; + var offsetView:FlxGroup; + var animDropDownMenu:FlxUIDropDownMenu; + var dropDownSetup:Bool = false; - var onionSkinChar:FlxSprite; - var txtOffsetShit:FlxText; + var onionSkinChar:FlxSprite; + var txtOffsetShit:FlxText; - var uiStuff:Component; + var uiStuff:Component; - override function create() - { - Paths.setCurrentLevel('week1'); + override function create() + { + Paths.setCurrentLevel('week1'); - var str = Paths.xml('ui/offset-editor-view'); - uiStuff = RuntimeComponentBuilder.fromAsset(str); + var str = Paths.xml('ui/offset-editor-view'); + uiStuff = RuntimeComponentBuilder.fromAsset(str); - // uiStuff.findComponent("btnViewSpriteSheet").onClick = _ -> curView = SPRITESHEET; - var dropdown:DropDown = cast uiStuff.findComponent("swapper"); - dropdown.onChange = function(e:UIEvent) - { - trace(e.type); - curView = cast e.data.curView; - trace(e.data); - // trace(e.data); - }; - // lv. - // lv.onChange = function(e:UIEvent) - // { - // trace(e.type); - // // trace(e.data.curView); - // // var item:haxe.ui.core.ItemRenderer = cast e.target; - // trace(e.target); - // // if (e.type == "change") - // // { - // // curView = cast e.data; - // // } - // }; + // uiStuff.findComponent("btnViewSpriteSheet").onClick = _ -> curView = SPRITESHEET; + var dropdown:DropDown = cast uiStuff.findComponent("swapper"); + dropdown.onChange = function(e:UIEvent) + { + trace(e.type); + curView = cast e.data.curView; + trace(e.data); + // trace(e.data); + }; + // lv. + // lv.onChange = function(e:UIEvent) + // { + // trace(e.type); + // // trace(e.data.curView); + // // var item:haxe.ui.core.ItemRenderer = cast e.target; + // trace(e.target); + // // if (e.type == "change") + // // { + // // curView = cast e.data; + // // } + // }; - hudCam = new FlxCamera(); - hudCam.bgColor.alpha = 0; + hudCam = new FlxCamera(); + hudCam.bgColor.alpha = 0; - FlxG.cameras.add(hudCam, false); + FlxG.cameras.add(hudCam, false); - bg = FlxGridOverlay.create(10, 10); - // bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.GREEN); + bg = FlxGridOverlay.create(10, 10); + // bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.GREEN); - bg.scrollFactor.set(); - add(bg); + bg.scrollFactor.set(); + add(bg); - initSpritesheetView(); - initOffsetView(); + initSpritesheetView(); + initOffsetView(); - uiStuff.cameras = [hudCam]; + uiStuff.cameras = [hudCam]; - add(uiStuff); + add(uiStuff); - super.create(); - } + super.create(); + } - var bf:FlxSprite; - var swagOutlines:FlxSprite; + var bf:FlxSprite; + var swagOutlines:FlxSprite; - function initSpritesheetView():Void - { - spriteSheetView = new FlxGroup(); - add(spriteSheetView); + function initSpritesheetView():Void + { + spriteSheetView = new FlxGroup(); + add(spriteSheetView); - var tex = Paths.getSparrowAtlas('characters/temp'); - // tex.frames[0].uv - - bf = new FlxSprite(); - bf.loadGraphic(tex.parent); - spriteSheetView.add(bf); - - swagOutlines = new FlxSprite().makeGraphic(tex.parent.width, tex.parent.height, FlxColor.TRANSPARENT); - - generateOutlines(tex.frames); - - txtGrp = new FlxGroup(); - txtGrp.cameras = [hudCam]; - spriteSheetView.add(txtGrp); - - addInfo('boyfriend.xml', ""); - addInfo('Width', bf.width); - addInfo('Height', bf.height); - - swagOutlines.antialiasing = true; - spriteSheetView.add(swagOutlines); - - FlxG.stage.window.onDropFile.add(function(path:String) - { - // WACKY ASS TESTING SHIT FOR WEB FILE LOADING?? - #if web - var swagList:FileList = cast path; + var tex = Paths.getSparrowAtlas('characters/temp'); + // tex.frames[0].uv + + bf = new FlxSprite(); + bf.loadGraphic(tex.parent); + spriteSheetView.add(bf); + + swagOutlines = new FlxSprite().makeGraphic(tex.parent.width, tex.parent.height, FlxColor.TRANSPARENT); - var objShit = js.html.URL.createObjectURL(swagList.item(0)); - trace(objShit); - - var funnysound = new FlxSound().loadStream('https://cdn.discordapp.com/attachments/767500676166451231/817821618251759666/Flutter.mp3', false, - false, null, function() - { - trace('LOADED SHIT??'); - }); - - funnysound.volume = 1; - funnysound.play(); - - var urlShit = new URLLoader(new URLRequest(objShit)); - - new FlxTimer().start(3, function(tmr:FlxTimer) - { - // music lol! - if (urlShit.dataFormat == BINARY) - { - // var daSwagBytes:ByteArray = urlShit.data; - - // FlxG.sound.playMusic(); - - // trace('is binary!!'); - } - trace(urlShit.dataFormat); - }); - - // remove(bf); - // FlxG.bitmap.removeByKey(Paths.image('characters/temp')); - // Assets.cache.clear(); - - // bf.loadGraphic(objShit); - // add(bf); - - // trace(swagList.item(0).name); - // var urlShit = js.html.URL.createObjectURL(path); - #end - - #if sys - trace("DROPPED FILE FROM: " + Std.string(path)); - var newPath = "./" + Paths.image('characters/temp'); - File.copy(path, newPath); - - var swag = Paths.image('characters/temp'); + generateOutlines(tex.frames); + + txtGrp = new FlxGroup(); + txtGrp.cameras = [hudCam]; + spriteSheetView.add(txtGrp); + + addInfo('boyfriend.xml', ""); + addInfo('Width', bf.width); + addInfo('Height', bf.height); + + swagOutlines.antialiasing = true; + spriteSheetView.add(swagOutlines); - if (bf != null) - remove(bf); - FlxG.bitmap.removeByKey(Paths.image('characters/temp')); - Assets.cache.clear(); - - bf.loadGraphic(Paths.image('characters/temp')); - add(bf); - #end - }); - } - - function generateOutlines(frameShit:Array):Void - { - // swagOutlines.width = frameShit[0].parent.width; - // swagOutlines.height = frameShit[0].parent.height; - swagOutlines.pixels.fillRect(new Rectangle(0, 0, swagOutlines.width, swagOutlines.height), 0x00000000); - - for (i in frameShit) - { - var lineStyle:LineStyle = {color: FlxColor.RED, thickness: 2}; - - var uvW:Float = (i.uv.width * i.parent.width) - (i.uv.x * i.parent.width); - var uvH:Float = (i.uv.height * i.parent.height) - (i.uv.y * i.parent.height); - - // trace(Std.int(i.uv.width * i.parent.width)); - swagOutlines.drawRect(i.uv.x * i.parent.width, i.uv.y * i.parent.height, uvW, uvH, FlxColor.TRANSPARENT, lineStyle); - // swagGraphic.setPosition(, ); - // trace(uvH); - } - } - - function initOffsetView():Void - { - offsetView = new FlxGroup(); - add(offsetView); - - onionSkinChar = new FlxSprite().makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.TRANSPARENT); - onionSkinChar.visible = false; - offsetView.add(onionSkinChar); - - txtOffsetShit = new FlxText(20, 20, 0, "", 20); - txtOffsetShit.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - txtOffsetShit.cameras = [hudCam]; - offsetView.add(txtOffsetShit); - - animDropDownMenu = new FlxUIDropDownMenu(630, 20, FlxUIDropDownMenu.makeStrIdLabelArray(['weed'], true)); - animDropDownMenu.cameras = [hudCam]; - offsetView.add(animDropDownMenu); - - var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); - - var charDropdown:DropDown = cast uiStuff.findComponent('characterDropdown'); - for (char in characters) - { - charDropdown.dataSource.add({text: char}); - } - - charDropdown.onChange = function(e:UIEvent) - { - loadAnimShit(e.data.text); - }; - } - - public var mouseOffset:FlxPoint = FlxPoint.get(0, 0); - public var oldPos:FlxPoint = FlxPoint.get(0, 0); - - function mouseOffsetMovement() - { - if (swagChar != null) - { - if (FlxG.mouse.justPressed) - { - mouseOffset.set(FlxG.mouse.x - -swagChar.offset.x, FlxG.mouse.y - -swagChar.offset.y); - // oldPos.set(swagChar.offset.x, swagChar.offset.y); - // oldPos.set(FlxG.mouse.x, FlxG.mouse.y); - } - - if (FlxG.mouse.pressed) - { - swagChar.offset.x = (FlxG.mouse.x - mouseOffset.x) * -1; - swagChar.offset.y = (FlxG.mouse.y - mouseOffset.y) * -1; - - swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, [Std.int(swagChar.offset.x), Std.int(swagChar.offset.y)]); - - txtOffsetShit.text = 'Offset: ' + swagChar.offset; - } - } - } - - function addInfo(str:String, value:Dynamic) - { - var swagText:FlxText = new FlxText(10, 10 + (28 * txtGrp.length)); - swagText.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - swagText.scrollFactor.set(); - txtGrp.add(swagText); - - swagText.text = str + ": " + Std.string(value); - } - - function checkLibrary(library:String) - { - trace(Assets.hasLibrary(library)); - if (Assets.getLibrary(library) == null) - { - @:privateAccess - if (!LimeAssets.libraryPaths.exists(library)) - throw "Missing library: " + library; - - // var callback = callbacks.add("library:" + library); - Assets.loadLibrary(library).onComplete(function(_) - { - trace('LOADED... awesomeness...'); - // callback(); - }); - } - } - - override function update(elapsed:Float) - { - if (FlxG.keys.justPressed.ONE) - { - var lv:DropDown = cast uiStuff.findComponent("swapper"); - lv.selectedIndex = 0; - curView = SPRITESHEET; - } - - if (FlxG.keys.justReleased.TWO) - { - var lv:DropDown = cast uiStuff.findComponent("swapper"); - lv.selectedIndex = 1; - curView = OFFSETSHIT; - if (swagChar != null) - { - FlxG.camera.focusOn(swagChar.getMidpoint()); - FlxG.camera.zoom = 0.95; - } - } - - switch (curView) - { - case SPRITESHEET: - spriteSheetView.visible = true; - offsetView.visible = false; - offsetView.active = false; - case OFFSETSHIT: - spriteSheetView.visible = false; - offsetView.visible = true; - offsetView.active = true; - offsetControls(); - mouseOffsetMovement(); - } - - if (FlxG.keys.justPressed.H) - hudCam.visible = !hudCam.visible; - - CoolUtil.mouseCamDrag(); - CoolUtil.mouseWheelZoom(); - - // bg.scale.x = FlxG.camera.zoom; - // bg.scale.y = FlxG.camera.zoom; - - bg.setGraphicSize(Std.int(bg.width / FlxG.camera.zoom)); - - super.update(elapsed); - } - - function offsetControls():Void - { - if (FlxG.keys.justPressed.RBRACKET || FlxG.keys.justPressed.E) - { - if (Std.parseInt(animDropDownMenu.selectedId) + 1 <= animDropDownMenu.length) - animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) + 1); - else - animDropDownMenu.selectedId = Std.string(0); - animDropDownMenu.callback(animDropDownMenu.selectedId); - } - if (FlxG.keys.justPressed.LBRACKET || FlxG.keys.justPressed.Q) - { - if (Std.parseInt(animDropDownMenu.selectedId) - 1 >= 0) - animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) - 1); - else - animDropDownMenu.selectedId = Std.string(animDropDownMenu.length - 1); - animDropDownMenu.callback(animDropDownMenu.selectedId); - } - - // Keyboards controls for general WASD "movement" - // modifies the animDropDownMenu so that it's properly updated and shit - // and then it's just played and updated from the animDropDownMenu callback, which is set in the loadAnimShit() function probabbly - if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S || FlxG.keys.justPressed.D || FlxG.keys.justPressed.A) - { - var missShit:String = ''; - - if (FlxG.keys.pressed.SHIFT) - missShit = 'miss'; - - if (FlxG.keys.justPressed.W) - animDropDownMenu.selectedLabel = 'singUP' + missShit; - if (FlxG.keys.justPressed.S) - animDropDownMenu.selectedLabel = 'singDOWN' + missShit; - if (FlxG.keys.justPressed.A) - animDropDownMenu.selectedLabel = 'singLEFT' + missShit; - if (FlxG.keys.justPressed.D) - animDropDownMenu.selectedLabel = 'singRIGHT' + missShit; - - animDropDownMenu.callback(animDropDownMenu.selectedId); - } - - if (FlxG.keys.justPressed.F) - { - onionSkinChar.visible = !onionSkinChar.visible; - } - - // Plays the idle animation - if (FlxG.keys.justPressed.SPACE) - { - animDropDownMenu.selectedLabel = 'idle'; - animDropDownMenu.callback(animDropDownMenu.selectedId); - } - - // Playback the animation - if (FlxG.keys.justPressed.ENTER) - animDropDownMenu.callback(animDropDownMenu.selectedId); - - if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.UP || FlxG.keys.justPressed.DOWN) - { - var animName = animDropDownMenu.selectedLabel; - var coolValues:Array = swagChar.animationOffsets.get(animName); - - var multiplier:Int = 5; - - if (FlxG.keys.pressed.CONTROL) - multiplier = 1; - - if (FlxG.keys.pressed.SHIFT) - multiplier = 10; - - if (FlxG.keys.justPressed.RIGHT) - coolValues[0] -= 1 * multiplier; - else if (FlxG.keys.justPressed.LEFT) - coolValues[0] += 1 * multiplier; - else if (FlxG.keys.justPressed.UP) - coolValues[1] += 1 * multiplier; - else if (FlxG.keys.justPressed.DOWN) - coolValues[1] -= 1 * multiplier; - - swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, coolValues); - swagChar.playAnimation(animName); - - txtOffsetShit.text = 'Offset: ' + coolValues; - - trace(animName); - } - - if (FlxG.keys.justPressed.ESCAPE) - { - var outputString:String = ""; - - for (i in swagChar.animationOffsets.keys()) - { - outputString += i + " " + swagChar.animationOffsets.get(i)[0] + " " + swagChar.animationOffsets.get(i)[1] + "\n"; - } - - outputString.trim(); - saveOffsets(outputString); - } - } - - var swagChar:BaseCharacter; - - /* - Called when animation dropdown is changed! - */ - function loadAnimShit(char:String) - { - if (swagChar != null) - { - offsetView.remove(swagChar); - swagChar.destroy(); - } - - swagChar = CharacterDataParser.fetchCharacter(char); - swagChar.x = 100; - swagChar.y = 100; - // swagChar.debugMode = true; - offsetView.add(swagChar); - - generateOutlines(swagChar.frames.frames); - bf.pixels = swagChar.pixels; - - var animThing:Array = []; - - for (i in swagChar.animationOffsets.keys()) - { - animThing.push(i); - trace(i); - trace(swagChar.animationOffsets[i]); - } - - animDropDownMenu.setData(FlxUIDropDownMenu.makeStrIdLabelArray(animThing, true)); - animDropDownMenu.callback = function(str:String) - { - // clears the canvas - onionSkinChar.pixels.fillRect(new Rectangle(0, 0, FlxG.width * 2, FlxG.height * 2), 0x00000000); - - onionSkinChar.stamp(swagChar, Std.int(swagChar.x - swagChar.offset.x), Std.int(swagChar.y - swagChar.offset.y)); - onionSkinChar.alpha = 0.6; - - var animName = animThing[Std.parseInt(str)]; - swagChar.playAnimation(animName, true); // trace(); - trace(swagChar.animationOffsets.get(animName)); - - txtOffsetShit.text = 'Offset: ' + swagChar.offset; - }; - dropDownSetup = true; - } - - var _file:FileReference; - - private function saveOffsets(saveString:String) - { - if ((saveString != null) && (saveString.length > 0)) - { - _file = new FileReference(); - _file.addEventListener(Event.COMPLETE, onSaveComplete); - _file.addEventListener(Event.CANCEL, onSaveCancel); - _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file.save(saveString, swagChar.characterId + "Offsets.txt"); - } - } - - function onSaveComplete(_):Void - { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - FlxG.log.notice("Successfully saved LEVEL DATA."); - } - - /** - * Called when the save file dialog is cancelled. - */ - function onSaveCancel(_):Void - { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - } - - /** - * Called if there is an error while saving the gameplay recording. - */ - function onSaveError(_):Void - { - _file.removeEventListener(Event.COMPLETE, onSaveComplete); - _file.removeEventListener(Event.CANCEL, onSaveCancel); - _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); - _file = null; - FlxG.log.error("Problem saving Level data"); - } + FlxG.stage.window.onDropFile.add(function(path:String) + { + // WACKY ASS TESTING SHIT FOR WEB FILE LOADING?? + #if web + var swagList:FileList = cast path; + + var objShit = js.html.URL.createObjectURL(swagList.item(0)); + trace(objShit); + + var funnysound = new FlxSound().loadStream('https://cdn.discordapp.com/attachments/767500676166451231/817821618251759666/Flutter.mp3', false, false, + null, function() + { + trace('LOADED SHIT??'); + }); + + funnysound.volume = 1; + funnysound.play(); + + var urlShit = new URLLoader(new URLRequest(objShit)); + + new FlxTimer().start(3, function(tmr:FlxTimer) + { + // music lol! + if (urlShit.dataFormat == BINARY) + { + // var daSwagBytes:ByteArray = urlShit.data; + + // FlxG.sound.playMusic(); + + // trace('is binary!!'); + } + trace(urlShit.dataFormat); + }); + + // remove(bf); + // FlxG.bitmap.removeByKey(Paths.image('characters/temp')); + // Assets.cache.clear(); + + // bf.loadGraphic(objShit); + // add(bf); + + // trace(swagList.item(0).name); + // var urlShit = js.html.URL.createObjectURL(path); + #end + + #if sys + trace("DROPPED FILE FROM: " + Std.string(path)); + var newPath = "./" + Paths.image('characters/temp'); + File.copy(path, newPath); + + var swag = Paths.image('characters/temp'); + + if (bf != null) remove(bf); + FlxG.bitmap.removeByKey(Paths.image('characters/temp')); + Assets.cache.clear(); + + bf.loadGraphic(Paths.image('characters/temp')); + add(bf); + #end + }); + } + + function generateOutlines(frameShit:Array):Void + { + // swagOutlines.width = frameShit[0].parent.width; + // swagOutlines.height = frameShit[0].parent.height; + swagOutlines.pixels.fillRect(new Rectangle(0, 0, swagOutlines.width, swagOutlines.height), 0x00000000); + + for (i in frameShit) + { + var lineStyle:LineStyle = {color: FlxColor.RED, thickness: 2}; + + var uvW:Float = (i.uv.width * i.parent.width) - (i.uv.x * i.parent.width); + var uvH:Float = (i.uv.height * i.parent.height) - (i.uv.y * i.parent.height); + + // trace(Std.int(i.uv.width * i.parent.width)); + swagOutlines.drawRect(i.uv.x * i.parent.width, i.uv.y * i.parent.height, uvW, uvH, FlxColor.TRANSPARENT, lineStyle); + // swagGraphic.setPosition(, ); + // trace(uvH); + } + } + + function initOffsetView():Void + { + offsetView = new FlxGroup(); + add(offsetView); + + onionSkinChar = new FlxSprite().makeGraphic(FlxG.width * 2, FlxG.height * 2, FlxColor.TRANSPARENT); + onionSkinChar.visible = false; + offsetView.add(onionSkinChar); + + txtOffsetShit = new FlxText(20, 20, 0, "", 20); + txtOffsetShit.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + txtOffsetShit.cameras = [hudCam]; + offsetView.add(txtOffsetShit); + + animDropDownMenu = new FlxUIDropDownMenu(630, 20, FlxUIDropDownMenu.makeStrIdLabelArray(['weed'], true)); + animDropDownMenu.cameras = [hudCam]; + offsetView.add(animDropDownMenu); + + var characters:Array = CoolUtil.coolTextFile(Paths.txt('characterList')); + + var charDropdown:DropDown = cast uiStuff.findComponent('characterDropdown'); + for (char in characters) + { + charDropdown.dataSource.add({text: char}); + } + + charDropdown.onChange = function(e:UIEvent) + { + loadAnimShit(e.data.text); + }; + } + + public var mouseOffset:FlxPoint = FlxPoint.get(0, 0); + public var oldPos:FlxPoint = FlxPoint.get(0, 0); + + function mouseOffsetMovement() + { + if (swagChar != null) + { + if (FlxG.mouse.justPressed) + { + mouseOffset.set(FlxG.mouse.x - -swagChar.offset.x, FlxG.mouse.y - -swagChar.offset.y); + // oldPos.set(swagChar.offset.x, swagChar.offset.y); + // oldPos.set(FlxG.mouse.x, FlxG.mouse.y); + } + + if (FlxG.mouse.pressed) + { + swagChar.offset.x = (FlxG.mouse.x - mouseOffset.x) * -1; + swagChar.offset.y = (FlxG.mouse.y - mouseOffset.y) * -1; + + swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, [Std.int(swagChar.offset.x), Std.int(swagChar.offset.y)]); + + txtOffsetShit.text = 'Offset: ' + swagChar.offset; + } + } + } + + function addInfo(str:String, value:Dynamic) + { + var swagText:FlxText = new FlxText(10, 10 + (28 * txtGrp.length)); + swagText.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + swagText.scrollFactor.set(); + txtGrp.add(swagText); + + swagText.text = str + ": " + Std.string(value); + } + + function checkLibrary(library:String) + { + trace(Assets.hasLibrary(library)); + if (Assets.getLibrary(library) == null) + { + @:privateAccess + if (!LimeAssets.libraryPaths.exists(library)) throw "Missing library: " + library; + + // var callback = callbacks.add("library:" + library); + Assets.loadLibrary(library).onComplete(function(_) + { + trace('LOADED... awesomeness...'); + // callback(); + }); + } + } + + override function update(elapsed:Float) + { + if (FlxG.keys.justPressed.ONE) + { + var lv:DropDown = cast uiStuff.findComponent("swapper"); + lv.selectedIndex = 0; + curView = SPRITESHEET; + } + + if (FlxG.keys.justReleased.TWO) + { + var lv:DropDown = cast uiStuff.findComponent("swapper"); + lv.selectedIndex = 1; + curView = OFFSETSHIT; + if (swagChar != null) + { + FlxG.camera.focusOn(swagChar.getMidpoint()); + FlxG.camera.zoom = 0.95; + } + } + + switch (curView) + { + case SPRITESHEET: + spriteSheetView.visible = true; + offsetView.visible = false; + offsetView.active = false; + case OFFSETSHIT: + spriteSheetView.visible = false; + offsetView.visible = true; + offsetView.active = true; + offsetControls(); + mouseOffsetMovement(); + } + + if (FlxG.keys.justPressed.H) hudCam.visible = !hudCam.visible; + + CoolUtil.mouseCamDrag(); + CoolUtil.mouseWheelZoom(); + + // bg.scale.x = FlxG.camera.zoom; + // bg.scale.y = FlxG.camera.zoom; + + bg.setGraphicSize(Std.int(bg.width / FlxG.camera.zoom)); + + super.update(elapsed); + } + + function offsetControls():Void + { + if (FlxG.keys.justPressed.RBRACKET || FlxG.keys.justPressed.E) + { + if (Std.parseInt(animDropDownMenu.selectedId) + 1 <= animDropDownMenu.length) + animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) + + 1); + else + animDropDownMenu.selectedId = Std.string(0); + animDropDownMenu.callback(animDropDownMenu.selectedId); + } + if (FlxG.keys.justPressed.LBRACKET || FlxG.keys.justPressed.Q) + { + if (Std.parseInt(animDropDownMenu.selectedId) - 1 >= 0) animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) - 1); + else + animDropDownMenu.selectedId = Std.string(animDropDownMenu.length - 1); + animDropDownMenu.callback(animDropDownMenu.selectedId); + } + + // Keyboards controls for general WASD "movement" + // modifies the animDropDownMenu so that it's properly updated and shit + // and then it's just played and updated from the animDropDownMenu callback, which is set in the loadAnimShit() function probabbly + if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S || FlxG.keys.justPressed.D || FlxG.keys.justPressed.A) + { + var missShit:String = ''; + + if (FlxG.keys.pressed.SHIFT) missShit = 'miss'; + + if (FlxG.keys.justPressed.W) animDropDownMenu.selectedLabel = 'singUP' + missShit; + if (FlxG.keys.justPressed.S) animDropDownMenu.selectedLabel = 'singDOWN' + missShit; + if (FlxG.keys.justPressed.A) animDropDownMenu.selectedLabel = 'singLEFT' + missShit; + if (FlxG.keys.justPressed.D) animDropDownMenu.selectedLabel = 'singRIGHT' + missShit; + + animDropDownMenu.callback(animDropDownMenu.selectedId); + } + + if (FlxG.keys.justPressed.F) + { + onionSkinChar.visible = !onionSkinChar.visible; + } + + // Plays the idle animation + if (FlxG.keys.justPressed.SPACE) + { + animDropDownMenu.selectedLabel = 'idle'; + animDropDownMenu.callback(animDropDownMenu.selectedId); + } + + // Playback the animation + if (FlxG.keys.justPressed.ENTER) animDropDownMenu.callback(animDropDownMenu.selectedId); + + if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.UP || FlxG.keys.justPressed.DOWN) + { + var animName = animDropDownMenu.selectedLabel; + var coolValues:Array = swagChar.animationOffsets.get(animName); + + var multiplier:Int = 5; + + if (FlxG.keys.pressed.CONTROL) multiplier = 1; + + if (FlxG.keys.pressed.SHIFT) multiplier = 10; + + if (FlxG.keys.justPressed.RIGHT) coolValues[0] -= 1 * multiplier; + else if (FlxG.keys.justPressed.LEFT) coolValues[0] += 1 * multiplier; + else if (FlxG.keys.justPressed.UP) coolValues[1] += 1 * multiplier; + else if (FlxG.keys.justPressed.DOWN) coolValues[1] -= 1 * multiplier; + + swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, coolValues); + swagChar.playAnimation(animName); + + txtOffsetShit.text = 'Offset: ' + coolValues; + + trace(animName); + } + + if (FlxG.keys.justPressed.ESCAPE) + { + var outputString:String = ""; + + for (i in swagChar.animationOffsets.keys()) + { + outputString += i + " " + swagChar.animationOffsets.get(i)[0] + " " + swagChar.animationOffsets.get(i)[1] + "\n"; + } + + outputString.trim(); + saveOffsets(outputString); + } + } + + var swagChar:BaseCharacter; + + /* + Called when animation dropdown is changed! + */ + function loadAnimShit(char:String) + { + if (swagChar != null) + { + offsetView.remove(swagChar); + swagChar.destroy(); + } + + swagChar = CharacterDataParser.fetchCharacter(char); + swagChar.x = 100; + swagChar.y = 100; + // swagChar.debugMode = true; + offsetView.add(swagChar); + + generateOutlines(swagChar.frames.frames); + bf.pixels = swagChar.pixels; + + var animThing:Array = []; + + for (i in swagChar.animationOffsets.keys()) + { + animThing.push(i); + trace(i); + trace(swagChar.animationOffsets[i]); + } + + animDropDownMenu.setData(FlxUIDropDownMenu.makeStrIdLabelArray(animThing, true)); + animDropDownMenu.callback = function(str:String) + { + // clears the canvas + onionSkinChar.pixels.fillRect(new Rectangle(0, 0, FlxG.width * 2, FlxG.height * 2), 0x00000000); + + onionSkinChar.stamp(swagChar, Std.int(swagChar.x - swagChar.offset.x), Std.int(swagChar.y - swagChar.offset.y)); + onionSkinChar.alpha = 0.6; + + var animName = animThing[Std.parseInt(str)]; + swagChar.playAnimation(animName, true); // trace(); + trace(swagChar.animationOffsets.get(animName)); + + txtOffsetShit.text = 'Offset: ' + swagChar.offset; + }; + dropDownSetup = true; + } + + var _file:FileReference; + + function saveOffsets(saveString:String) + { + if ((saveString != null) && (saveString.length > 0)) + { + _file = new FileReference(); + _file.addEventListener(Event.COMPLETE, onSaveComplete); + _file.addEventListener(Event.CANCEL, onSaveCancel); + _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file.save(saveString, swagChar.characterId + "Offsets.txt"); + } + } + + function onSaveComplete(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.notice("Successfully saved LEVEL DATA."); + } + + /** + * Called when the save file dialog is cancelled. + */ + function onSaveCancel(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + } + + /** + * Called if there is an error while saving the gameplay recording. + */ + function onSaveError(_):Void + { + _file.removeEventListener(Event.COMPLETE, onSaveComplete); + _file.removeEventListener(Event.CANCEL, onSaveCancel); + _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); + _file = null; + FlxG.log.error("Problem saving Level data"); + } } enum abstract ANIMDEBUGVIEW(String) { - var SPRITESHEET; - var OFFSETSHIT; + var SPRITESHEET; + var OFFSETSHIT; } diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index b7a3993d3..476f0ae9d 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -8,89 +8,89 @@ import funkin.ui.debug.charting.ChartEditorState; class DebugMenuSubState extends MusicBeatSubstate { - var items:TextMenuList; + var items:TextMenuList; - /** - * Camera focus point - */ - var camFocusPoint:FlxObject; + /** + * Camera focus point + */ + var camFocusPoint:FlxObject; - override function create() - { - super.create(); + override function create() + { + super.create(); - // Create an object for the camera to track. - camFocusPoint = new FlxObject(0, 0); - add(camFocusPoint); + // Create an object for the camera to track. + camFocusPoint = new FlxObject(0, 0); + add(camFocusPoint); - // Follow the camera focus as we scroll. - FlxG.camera.follow(camFocusPoint, null, 0.06); + // Follow the camera focus as we scroll. + FlxG.camera.follow(camFocusPoint, null, 0.06); - // Create the green background. - var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat')); - menuBG.color = 0xFF4CAF50; - menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); - menuBG.updateHitbox(); - menuBG.screenCenter(); - menuBG.scrollFactor.set(0, 0); - add(menuBG); + // Create the green background. + var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat')); + menuBG.color = 0xFF4CAF50; + menuBG.setGraphicSize(Std.int(menuBG.width * 1.1)); + menuBG.updateHitbox(); + menuBG.screenCenter(); + menuBG.scrollFactor.set(0, 0); + add(menuBG); - // Create the list for menu items. - items = new TextMenuList(); - // Move the camera when the menu is scrolled. - items.onChange.add(onMenuChange); - add(items); + // Create the list for menu items. + items = new TextMenuList(); + // Move the camera when the menu is scrolled. + items.onChange.add(onMenuChange); + add(items); - // Create each menu item. - // Call onMenuChange when the first item is created to move the camera . - onMenuChange(createItem("CHART EDITOR", openChartEditor)); - createItem("ANIMATION EDITOR", openAnimationEditor); - createItem("STAGE EDITOR", openStageEditor); - } + // Create each menu item. + // Call onMenuChange when the first item is created to move the camera . + onMenuChange(createItem("CHART EDITOR", openChartEditor)); + createItem("ANIMATION EDITOR", openAnimationEditor); + createItem("STAGE EDITOR", openStageEditor); + } - function onMenuChange(selected:TextMenuItem) - { - camFocusPoint.setPosition(selected.x + selected.width / 2, selected.y + selected.height / 2); - } + function onMenuChange(selected:TextMenuItem) + { + camFocusPoint.setPosition(selected.x + selected.width / 2, selected.y + selected.height / 2); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (controls.BACK) - { - FlxG.sound.play(Paths.sound('cancelMenu')); - exitDebugMenu(); - } - } + if (controls.BACK) + { + FlxG.sound.play(Paths.sound('cancelMenu')); + exitDebugMenu(); + } + } - function createItem(name:String, callback:Void->Void, fireInstantly = false) - { - var item = items.createItem(0, 100 + items.length * 100, name, BOLD, callback); - item.fireInstantly = fireInstantly; - item.screenCenter(X); - return item; - } + function createItem(name:String, callback:Void->Void, fireInstantly = false) + { + var item = items.createItem(0, 100 + items.length * 100, name, BOLD, callback); + item.fireInstantly = fireInstantly; + item.screenCenter(X); + return item; + } - function openChartEditor() - { - FlxG.switchState(new ChartEditorState()); - } + function openChartEditor() + { + FlxG.switchState(new ChartEditorState()); + } - function openAnimationEditor() - { - FlxG.switchState(new funkin.ui.animDebugShit.DebugBoundingState()); - trace('Animation Editor'); - } + function openAnimationEditor() + { + FlxG.switchState(new funkin.ui.animDebugShit.DebugBoundingState()); + trace('Animation Editor'); + } - function openStageEditor() - { - trace('Stage Editor'); - } + function openStageEditor() + { + trace('Stage Editor'); + } - function exitDebugMenu() - { - // TODO: Add a transition? - this.close(); - } + function exitDebugMenu() + { + // TODO: Add a transition? + this.close(); + } } diff --git a/source/funkin/ui/debug/charting/ChartEditorCommand.hx b/source/funkin/ui/debug/charting/ChartEditorCommand.hx index 3e3f3774f..bf4d710dd 100644 --- a/source/funkin/ui/debug/charting/ChartEditorCommand.hx +++ b/source/funkin/ui/debug/charting/ChartEditorCommand.hx @@ -15,139 +15,139 @@ using Lambda; */ interface ChartEditorCommand { - /** - * Calling this function should perform the action that this command represents. - * @param state The ChartEditorState to perform the action on. - */ - public function execute(state:ChartEditorState):Void; + /** + * Calling this function should perform the action that this command represents. + * @param state The ChartEditorState to perform the action on. + */ + public function execute(state:ChartEditorState):Void; - /** - * Calling this function should perform the inverse of the action that this command represents, - * effectively undoing the action. - * @param state The ChartEditorState to undo the action on. - */ - public function undo(state:ChartEditorState):Void; + /** + * Calling this function should perform the inverse of the action that this command represents, + * effectively undoing the action. + * @param state The ChartEditorState to undo the action on. + */ + public function undo(state:ChartEditorState):Void; - /** - * Get a short description of the action (for the UI). - * For example, return `Add Left Note` to display `Undo Add Left Note` in the menu. - */ - public function toString():String; + /** + * Get a short description of the action (for the UI). + * For example, return `Add Left Note` to display `Undo Add Left Note` in the menu. + */ + public function toString():String; } class AddNotesCommand implements ChartEditorCommand { - private var notes:Array; - private var appendToSelection:Bool; + var notes:Array; + var appendToSelection:Bool; - public function new(notes:Array, appendToSelection:Bool = false) - { - this.notes = notes; - this.appendToSelection = appendToSelection; - } + public function new(notes:Array, appendToSelection:Bool = false) + { + this.notes = notes; + this.appendToSelection = appendToSelection; + } - public function execute(state:ChartEditorState):Void - { - for (note in notes) - { - state.currentSongChartNoteData.push(note); - } + public function execute(state:ChartEditorState):Void + { + for (note in notes) + { + state.currentSongChartNoteData.push(note); + } - if (appendToSelection) - { - state.currentNoteSelection = state.currentNoteSelection.concat(notes); - } - else - { - state.currentNoteSelection = notes; - state.currentEventSelection = []; - } + if (appendToSelection) + { + state.currentNoteSelection = state.currentNoteSelection.concat(notes); + } + else + { + state.currentNoteSelection = notes; + state.currentEventSelection = []; + } - state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); + state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); - state.currentNoteSelection = []; - state.currentEventSelection = []; - state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); + public function undo(state:ChartEditorState):Void + { + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); + state.currentNoteSelection = []; + state.currentEventSelection = []; + state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - if (notes.length == 1) - { - var dir:String = notes[0].getDirectionName(); - return 'Add $dir Note'; - } + public function toString():String + { + if (notes.length == 1) + { + var dir:String = notes[0].getDirectionName(); + return 'Add $dir Note'; + } - return 'Add ${notes.length} Notes'; - } + return 'Add ${notes.length} Notes'; + } } class RemoveNotesCommand implements ChartEditorCommand { - private var notes:Array; + var notes:Array; - public function new(notes:Array) - { - this.notes = notes; - } + public function new(notes:Array) + { + this.notes = notes; + } - public function execute(state:ChartEditorState):Void - { - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); - state.currentNoteSelection = []; - state.currentEventSelection = []; - state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); + public function execute(state:ChartEditorState):Void + { + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); + state.currentNoteSelection = []; + state.currentEventSelection = []; + state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - for (note in notes) - { - state.currentSongChartNoteData.push(note); - } - state.currentNoteSelection = notes; - state.currentEventSelection = []; - state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); + public function undo(state:ChartEditorState):Void + { + for (note in notes) + { + state.currentSongChartNoteData.push(note); + } + state.currentNoteSelection = notes; + state.currentEventSelection = []; + state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - if (notes.length == 1 && notes[0] != null) - { - var dir:String = notes[0].getDirectionName(); - return 'Remove $dir Note'; - } + public function toString():String + { + if (notes.length == 1 && notes[0] != null) + { + var dir:String = notes[0].getDirectionName(); + return 'Remove $dir Note'; + } - return 'Remove ${notes.length} Notes'; - } + return 'Remove ${notes.length} Notes'; + } } /** @@ -155,323 +155,323 @@ class RemoveNotesCommand implements ChartEditorCommand */ class SelectItemsCommand implements ChartEditorCommand { - private var notes:Array; - private var events:Array; + var notes:Array; + var events:Array; - public function new(notes:Array, events:Array) - { - this.notes = notes; - this.events = events; - } + public function new(notes:Array, events:Array) + { + this.notes = notes; + this.events = events; + } - public function execute(state:ChartEditorState):Void - { - for (note in this.notes) - { - state.currentNoteSelection.push(note); - } + public function execute(state:ChartEditorState):Void + { + for (note in this.notes) + { + state.currentNoteSelection.push(note); + } - for (event in this.events) - { - state.currentEventSelection.push(event); - } + for (event in this.events) + { + state.currentEventSelection.push(event); + } - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentNoteSelection, this.notes); - state.currentEventSelection = SongDataUtils.subtractEvents(state.currentEventSelection, this.events); + public function undo(state:ChartEditorState):Void + { + state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentNoteSelection, this.notes); + state.currentEventSelection = SongDataUtils.subtractEvents(state.currentEventSelection, this.events); - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - var len:Int = notes.length + events.length; + public function toString():String + { + var len:Int = notes.length + events.length; - if (notes.length == 0) - { - if (events.length == 1) - { - return 'Select Event'; - } - else - { - return 'Select ${events.length} Events'; - } - } - else if (events.length == 0) - { - if (notes.length == 1) - { - return 'Select Note'; - } - else - { - return 'Select ${notes.length} Notes'; - } - } + if (notes.length == 0) + { + if (events.length == 1) + { + return 'Select Event'; + } + else + { + return 'Select ${events.length} Events'; + } + } + else if (events.length == 0) + { + if (notes.length == 1) + { + return 'Select Note'; + } + else + { + return 'Select ${notes.length} Notes'; + } + } - return 'Select ${len} Items'; - } + return 'Select ${len} Items'; + } } class AddEventsCommand implements ChartEditorCommand { - private var events:Array; - private var appendToSelection:Bool; + var events:Array; + var appendToSelection:Bool; - public function new(events:Array, ?appendToSelection:Bool = false) - { - this.events = events; - this.appendToSelection = appendToSelection; - } + public function new(events:Array, ?appendToSelection:Bool = false) + { + this.events = events; + this.appendToSelection = appendToSelection; + } - public function execute(state:ChartEditorState):Void - { - for (event in events) - { - state.currentSongChartEventData.push(event); - } + public function execute(state:ChartEditorState):Void + { + for (event in events) + { + state.currentSongChartEventData.push(event); + } - if (appendToSelection) - { - state.currentEventSelection = state.currentEventSelection.concat(events); - } - else - { - state.currentNoteSelection = []; - state.currentEventSelection = events; - } + if (appendToSelection) + { + state.currentEventSelection = state.currentEventSelection.concat(events); + } + else + { + state.currentNoteSelection = []; + state.currentEventSelection = events; + } - state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); + state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); + public function undo(state:ChartEditorState):Void + { + state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); - state.currentNoteSelection = []; - state.currentEventSelection = []; + state.currentNoteSelection = []; + state.currentEventSelection = []; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - var len:Int = events.length; - return 'Add $len Events'; - } + public function toString():String + { + var len:Int = events.length; + return 'Add $len Events'; + } } class RemoveEventsCommand implements ChartEditorCommand { - private var events:Array; + var events:Array; - public function new(events:Array) - { - this.events = events; - } + public function new(events:Array) + { + this.events = events; + } - public function execute(state:ChartEditorState):Void - { - state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); - state.currentEventSelection = []; - state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); + public function execute(state:ChartEditorState):Void + { + state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); + state.currentEventSelection = []; + state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - for (event in events) - { - state.currentSongChartEventData.push(event); - } - state.currentEventSelection = events; - state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); + public function undo(state:ChartEditorState):Void + { + for (event in events) + { + state.currentSongChartEventData.push(event); + } + state.currentEventSelection = events; + state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - if (events.length == 1 && events[0] != null) - { - return 'Remove Event'; - } + public function toString():String + { + if (events.length == 1 && events[0] != null) + { + return 'Remove Event'; + } - return 'Remove ${events.length} Events'; - } + return 'Remove ${events.length} Events'; + } } class RemoveItemsCommand implements ChartEditorCommand { - private var notes:Array; - private var events:Array; + var notes:Array; + var events:Array; - public function new(notes:Array, events:Array) - { - this.notes = notes; - this.events = events; - } + public function new(notes:Array, events:Array) + { + this.notes = notes; + this.events = events; + } - public function execute(state:ChartEditorState):Void - { - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); - state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); + public function execute(state:ChartEditorState):Void + { + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); + state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); - state.currentNoteSelection = []; - state.currentEventSelection = []; + state.currentNoteSelection = []; + state.currentEventSelection = []; - state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); + state.playSound(Paths.sound('funnyNoise/funnyNoise-01')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - for (note in notes) - { - state.currentSongChartNoteData.push(note); - } + public function undo(state:ChartEditorState):Void + { + for (note in notes) + { + state.currentSongChartNoteData.push(note); + } - for (event in events) - { - state.currentSongChartEventData.push(event); - } + for (event in events) + { + state.currentSongChartEventData.push(event); + } - state.currentNoteSelection = notes; - state.currentEventSelection = events; + state.currentNoteSelection = notes; + state.currentEventSelection = events; - state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); + state.playSound(Paths.sound('funnyNoise/funnyNoise-08')); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - return 'Remove ${notes.length + events.length} Items'; - } + public function toString():String + { + return 'Remove ${notes.length + events.length} Items'; + } } class SwitchDifficultyCommand implements ChartEditorCommand { - private var prevDifficulty:String; - private var newDifficulty:String; - private var prevVariation:String; - private var newVariation:String; + var prevDifficulty:String; + var newDifficulty:String; + var prevVariation:String; + var newVariation:String; - public function new(prevDifficulty:String, newDifficulty:String, prevVariation:String, newVariation:String) - { - this.prevDifficulty = prevDifficulty; - this.newDifficulty = newDifficulty; - this.prevVariation = prevVariation; - this.newVariation = newVariation; - } + public function new(prevDifficulty:String, newDifficulty:String, prevVariation:String, newVariation:String) + { + this.prevDifficulty = prevDifficulty; + this.newDifficulty = newDifficulty; + this.prevVariation = prevVariation; + this.newVariation = newVariation; + } - public function execute(state:ChartEditorState):Void - { - state.selectedVariation = newVariation != null ? newVariation : prevVariation; - state.selectedDifficulty = newDifficulty != null ? newDifficulty : prevDifficulty; + public function execute(state:ChartEditorState):Void + { + state.selectedVariation = newVariation != null ? newVariation : prevVariation; + state.selectedDifficulty = newDifficulty != null ? newDifficulty : prevDifficulty; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - state.selectedVariation = prevVariation != null ? prevVariation : newVariation; - state.selectedDifficulty = prevDifficulty != null ? prevDifficulty : newDifficulty; + public function undo(state:ChartEditorState):Void + { + state.selectedVariation = prevVariation != null ? prevVariation : newVariation; + state.selectedDifficulty = prevDifficulty != null ? prevDifficulty : newDifficulty; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - return 'Switch Difficulty'; - } + public function toString():String + { + return 'Switch Difficulty'; + } } class DeselectItemsCommand implements ChartEditorCommand { - private var notes:Array; - private var events:Array; + var notes:Array; + var events:Array; - public function new(notes:Array, events:Array) - { - this.notes = notes; - this.events = events; - } + public function new(notes:Array, events:Array) + { + this.notes = notes; + this.events = events; + } - public function execute(state:ChartEditorState):Void - { - state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentNoteSelection, this.notes); - state.currentEventSelection = SongDataUtils.subtractEvents(state.currentEventSelection, this.events); + public function execute(state:ChartEditorState):Void + { + state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentNoteSelection, this.notes); + state.currentEventSelection = SongDataUtils.subtractEvents(state.currentEventSelection, this.events); - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - for (note in this.notes) - { - state.currentNoteSelection.push(note); - } + public function undo(state:ChartEditorState):Void + { + for (note in this.notes) + { + state.currentNoteSelection.push(note); + } - for (event in this.events) - { - state.currentEventSelection.push(event); - } + for (event in this.events) + { + state.currentEventSelection.push(event); + } - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - var noteCount = notes.length + events.length; + public function toString():String + { + var noteCount = notes.length + events.length; - if (noteCount == 1) - { - var dir:String = notes[0].getDirectionName(); - return 'Deselect $dir Items'; - } + if (noteCount == 1) + { + var dir:String = notes[0].getDirectionName(); + return 'Deselect $dir Items'; + } - return 'Deselect ${noteCount} Items'; - } + return 'Deselect ${noteCount} Items'; + } } /** @@ -480,353 +480,350 @@ class DeselectItemsCommand implements ChartEditorCommand */ class SetItemSelectionCommand implements ChartEditorCommand { - private var notes:Array; - private var events:Array; - private var previousNoteSelection:Array; - private var previousEventSelection:Array; + var notes:Array; + var events:Array; + var previousNoteSelection:Array; + var previousEventSelection:Array; - public function new(notes:Array, events:Array, previousNoteSelection:Array, - previousEventSelection:Array) - { - this.notes = notes; - this.events = events; - this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; - this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; - } + public function new(notes:Array, events:Array, previousNoteSelection:Array, + previousEventSelection:Array) + { + this.notes = notes; + this.events = events; + this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; + this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; + } - public function execute(state:ChartEditorState):Void - { - state.currentNoteSelection = notes; - state.currentEventSelection = events; + public function execute(state:ChartEditorState):Void + { + state.currentNoteSelection = notes; + state.currentEventSelection = events; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - state.currentNoteSelection = previousNoteSelection; - state.currentEventSelection = previousEventSelection; + public function undo(state:ChartEditorState):Void + { + state.currentNoteSelection = previousNoteSelection; + state.currentEventSelection = previousEventSelection; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - return 'Select ${notes.length} Items'; - } + public function toString():String + { + return 'Select ${notes.length} Items'; + } } class SelectAllItemsCommand implements ChartEditorCommand { - private var previousNoteSelection:Array; - private var previousEventSelection:Array; + var previousNoteSelection:Array; + var previousEventSelection:Array; - public function new(?previousNoteSelection:Array, ?previousEventSelection:Array) - { - this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; - this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; - } + public function new(?previousNoteSelection:Array, ?previousEventSelection:Array) + { + this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; + this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; + } - public function execute(state:ChartEditorState):Void - { - state.currentNoteSelection = state.currentSongChartNoteData; - state.currentEventSelection = state.currentSongChartEventData; + public function execute(state:ChartEditorState):Void + { + state.currentNoteSelection = state.currentSongChartNoteData; + state.currentEventSelection = state.currentSongChartEventData; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - state.currentNoteSelection = previousNoteSelection; - state.currentEventSelection = previousEventSelection; + public function undo(state:ChartEditorState):Void + { + state.currentNoteSelection = previousNoteSelection; + state.currentEventSelection = previousEventSelection; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - return 'Select All Items'; - } + public function toString():String + { + return 'Select All Items'; + } } class InvertSelectedItemsCommand implements ChartEditorCommand { - private var previousNoteSelection:Array; - private var previousEventSelection:Array; + var previousNoteSelection:Array; + var previousEventSelection:Array; - public function new(?previousNoteSelection:Array, ?previousEventSelection:Array) - { - this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; - this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; - } + public function new(?previousNoteSelection:Array, ?previousEventSelection:Array) + { + this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; + this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; + } - public function execute(state:ChartEditorState):Void - { - state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentSongChartNoteData, previousNoteSelection); - state.currentEventSelection = SongDataUtils.subtractEvents(state.currentSongChartEventData, previousEventSelection); - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + public function execute(state:ChartEditorState):Void + { + state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentSongChartNoteData, previousNoteSelection); + state.currentEventSelection = SongDataUtils.subtractEvents(state.currentSongChartEventData, previousEventSelection); + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - state.currentNoteSelection = previousNoteSelection; - state.currentEventSelection = previousEventSelection; + public function undo(state:ChartEditorState):Void + { + state.currentNoteSelection = previousNoteSelection; + state.currentEventSelection = previousEventSelection; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - return 'Invert Selected Items'; - } + public function toString():String + { + return 'Invert Selected Items'; + } } class DeselectAllItemsCommand implements ChartEditorCommand { - private var previousNoteSelection:Array; - private var previousEventSelection:Array; + var previousNoteSelection:Array; + var previousEventSelection:Array; - public function new(?previousNoteSelection:Array, ?previousEventSelection:Array) - { - this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; - this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; - } + public function new(?previousNoteSelection:Array, ?previousEventSelection:Array) + { + this.previousNoteSelection = previousNoteSelection == null ? [] : previousNoteSelection; + this.previousEventSelection = previousEventSelection == null ? [] : previousEventSelection; + } - public function execute(state:ChartEditorState):Void - { - state.currentNoteSelection = []; - state.currentEventSelection = []; + public function execute(state:ChartEditorState):Void + { + state.currentNoteSelection = []; + state.currentEventSelection = []; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function undo(state:ChartEditorState):Void - { - state.currentNoteSelection = previousNoteSelection; - state.currentEventSelection = previousEventSelection; + public function undo(state:ChartEditorState):Void + { + state.currentNoteSelection = previousNoteSelection; + state.currentEventSelection = previousEventSelection; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - } + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + } - public function toString():String - { - return 'Deselect All Items'; - } + public function toString():String + { + return 'Deselect All Items'; + } } class CutItemsCommand implements ChartEditorCommand { - private var notes:Array; - private var events:Array; + var notes:Array; + var events:Array; - public function new(notes:Array, events:Array) - { - this.notes = notes; - this.events = events; - } + public function new(notes:Array, events:Array) + { + this.notes = notes; + this.events = events; + } - public function execute(state:ChartEditorState):Void - { - // Copy the notes. - SongDataUtils.writeItemsToClipboard({ - notes: SongDataUtils.buildNoteClipboard(notes), - events: SongDataUtils.buildEventClipboard(events) - }); + public function execute(state:ChartEditorState):Void + { + // Copy the notes. + SongDataUtils.writeItemsToClipboard( + { + notes: SongDataUtils.buildNoteClipboard(notes), + events: SongDataUtils.buildEventClipboard(events) + }); - // Delete the notes. - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); - state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); - state.currentNoteSelection = []; - state.currentEventSelection = []; + // Delete the notes. + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); + state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, events); + state.currentNoteSelection = []; + state.currentEventSelection = []; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - state.sortChartData(); - } + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - state.currentSongChartNoteData = state.currentSongChartNoteData.concat(notes); - state.currentSongChartEventData = state.currentSongChartEventData.concat(events); + public function undo(state:ChartEditorState):Void + { + state.currentSongChartNoteData = state.currentSongChartNoteData.concat(notes); + state.currentSongChartEventData = state.currentSongChartEventData.concat(events); - state.currentNoteSelection = notes; - state.currentEventSelection = events; + state.currentNoteSelection = notes; + state.currentEventSelection = events; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - state.sortChartData(); - } + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + state.sortChartData(); + } - public function toString():String - { - var len:Int = notes.length + events.length; + public function toString():String + { + var len:Int = notes.length + events.length; - if (notes.length == 0) - return 'Cut $len Events to Clipboard'; - else if (events.length == 0) - return 'Cut $len Notes to Clipboard'; - else - return 'Cut $len Items to Clipboard'; - } + if (notes.length == 0) return 'Cut $len Events to Clipboard'; + else if (events.length == 0) return 'Cut $len Notes to Clipboard'; + else + return 'Cut $len Items to Clipboard'; + } } class FlipNotesCommand implements ChartEditorCommand { - private var notes:Array; - private var flippedNotes:Array; + var notes:Array; + var flippedNotes:Array; - public function new(notes:Array) - { - this.notes = notes; - } + public function new(notes:Array) + { + this.notes = notes; + } - public function execute(state:ChartEditorState):Void - { - // Delete the notes. - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); + public function execute(state:ChartEditorState):Void + { + // Delete the notes. + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); - // Add the flipped notes. - flippedNotes = SongDataUtils.flipNotes(notes); - state.currentSongChartNoteData = state.currentSongChartNoteData.concat(flippedNotes); + // Add the flipped notes. + flippedNotes = SongDataUtils.flipNotes(notes); + state.currentSongChartNoteData = state.currentSongChartNoteData.concat(flippedNotes); - state.currentNoteSelection = flippedNotes; - state.currentEventSelection = []; + state.currentNoteSelection = flippedNotes; + state.currentEventSelection = []; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; - state.sortChartData(); - } + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, flippedNotes); - state.currentSongChartNoteData = state.currentSongChartNoteData.concat(notes); + public function undo(state:ChartEditorState):Void + { + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, flippedNotes); + state.currentSongChartNoteData = state.currentSongChartNoteData.concat(notes); - state.currentNoteSelection = notes; - state.currentEventSelection = []; + state.currentNoteSelection = notes; + state.currentEventSelection = []; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - var len:Int = notes.length; - return 'Flip $len Notes'; - } + public function toString():String + { + var len:Int = notes.length; + return 'Flip $len Notes'; + } } class PasteItemsCommand implements ChartEditorCommand { - private var targetTimestamp:Float; - // Notes we added with this command, for undo. - private var addedNotes:Array; - private var addedEvents:Array; + var targetTimestamp:Float; + // Notes we added with this command, for undo. + var addedNotes:Array; + var addedEvents:Array; - public function new(targetTimestamp:Float) - { - this.targetTimestamp = targetTimestamp; - } + public function new(targetTimestamp:Float) + { + this.targetTimestamp = targetTimestamp; + } - public function execute(state:ChartEditorState):Void - { - var currentClipboard:SongClipboardItems = SongDataUtils.readItemsFromClipboard(); + public function execute(state:ChartEditorState):Void + { + var currentClipboard:SongClipboardItems = SongDataUtils.readItemsFromClipboard(); - addedNotes = SongDataUtils.offsetSongNoteData(currentClipboard.notes, Std.int(targetTimestamp)); - addedEvents = SongDataUtils.offsetSongEventData(currentClipboard.events, Std.int(targetTimestamp)); + addedNotes = SongDataUtils.offsetSongNoteData(currentClipboard.notes, Std.int(targetTimestamp)); + addedEvents = SongDataUtils.offsetSongEventData(currentClipboard.events, Std.int(targetTimestamp)); - state.currentSongChartNoteData = state.currentSongChartNoteData.concat(addedNotes); - state.currentSongChartEventData = state.currentSongChartEventData.concat(addedEvents); - state.currentNoteSelection = addedNotes.copy(); - state.currentEventSelection = addedEvents.copy(); + state.currentSongChartNoteData = state.currentSongChartNoteData.concat(addedNotes); + state.currentSongChartEventData = state.currentSongChartEventData.concat(addedEvents); + state.currentNoteSelection = addedNotes.copy(); + state.currentEventSelection = addedEvents.copy(); - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, addedNotes); - state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, addedEvents); - state.currentNoteSelection = []; - state.currentEventSelection = []; + public function undo(state:ChartEditorState):Void + { + state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, addedNotes); + state.currentSongChartEventData = SongDataUtils.subtractEvents(state.currentSongChartEventData, addedEvents); + state.currentNoteSelection = []; + state.currentEventSelection = []; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - var currentClipboard:SongClipboardItems = SongDataUtils.readItemsFromClipboard(); + public function toString():String + { + var currentClipboard:SongClipboardItems = SongDataUtils.readItemsFromClipboard(); - var len:Int = currentClipboard.notes.length + currentClipboard.events.length; + var len:Int = currentClipboard.notes.length + currentClipboard.events.length; - if (currentClipboard.notes.length == 0) - return 'Paste $len Events'; - else if (currentClipboard.events.length == 0) - return 'Paste $len Notes'; - else - return 'Paste $len Items'; - } + if (currentClipboard.notes.length == 0) return 'Paste $len Events'; + else if (currentClipboard.events.length == 0) return 'Paste $len Notes'; + else + return 'Paste $len Items'; + } } class ExtendNoteLengthCommand implements ChartEditorCommand { - private var note:SongNoteData; - private var oldLength:Float; - private var newLength:Float; + var note:SongNoteData; + var oldLength:Float; + var newLength:Float; - public function new(note:SongNoteData, newLength:Float) - { - this.note = note; - this.oldLength = note.length; - this.newLength = newLength; - } + public function new(note:SongNoteData, newLength:Float) + { + this.note = note; + this.oldLength = note.length; + this.newLength = newLength; + } - public function execute(state:ChartEditorState):Void - { - note.length = newLength; + public function execute(state:ChartEditorState):Void + { + note.length = newLength; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function undo(state:ChartEditorState):Void - { - note.length = oldLength; + public function undo(state:ChartEditorState):Void + { + note.length = oldLength; - state.saveDataDirty = true; - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + state.saveDataDirty = true; + state.noteDisplayDirty = true; + state.notePreviewDirty = true; - state.sortChartData(); - } + state.sortChartData(); + } - public function toString():String - { - return 'Extend Note Length'; - } + public function toString():String + { + return 'Extend Note Length'; + } } diff --git a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx index 0b49dd201..99b03381e 100644 --- a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx @@ -29,469 +29,465 @@ using Lambda; class ChartEditorDialogHandler { - static final CHART_EDITOR_DIALOG_ABOUT_LAYOUT = Paths.ui('chart-editor/dialogs/about'); - static final CHART_EDITOR_DIALOG_WELCOME_LAYOUT = Paths.ui('chart-editor/dialogs/welcome'); - static final CHART_EDITOR_DIALOG_UPLOAD_INST_LAYOUT = Paths.ui('chart-editor/dialogs/upload-inst'); - static final CHART_EDITOR_DIALOG_SONG_METADATA_LAYOUT = Paths.ui('chart-editor/dialogs/song-metadata'); - static final CHART_EDITOR_DIALOG_SONG_METADATA_CHARGROUP_LAYOUT = Paths.ui('chart-editor/dialogs/song-metadata-chargroup'); - static final CHART_EDITOR_DIALOG_UPLOAD_VOCALS_LAYOUT = Paths.ui('chart-editor/dialogs/upload-vocals'); - static final CHART_EDITOR_DIALOG_UPLOAD_VOCALS_ENTRY_LAYOUT = Paths.ui('chart-editor/dialogs/upload-vocals-entry'); - static final CHART_EDITOR_DIALOG_USER_GUIDE_LAYOUT = Paths.ui('chart-editor/dialogs/user-guide'); - - /** - * - */ - public static inline function openAboutDialog(state:ChartEditorState):Dialog - { - return openDialog(state, CHART_EDITOR_DIALOG_ABOUT_LAYOUT, true, true); - } - - /** - * Builds and opens a dialog letting the user create a new chart, open a recent chart, or load from a template. - */ - public static function openWelcomeDialog(state:ChartEditorState, closable:Bool = true):Dialog - { - var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_WELCOME_LAYOUT, true, closable); - - // TODO: Add callbacks to the dialog buttons - - // Switch the graphic for frames. - var bfSpritePlaceholder:Image = dialog.findComponent('bfSprite', Image); - - // TODO: Replace this bullshit with a custom HaxeUI component that loads the sprite from the game's assets. - - if (bfSpritePlaceholder != null) - { - var bfSprite:FlxSprite = new FlxSprite(0, 0); - - bfSprite.visible = false; - - var frames = Paths.getSparrowAtlas(bfSpritePlaceholder.resource); - bfSprite.frames = frames; - - bfSprite.animation.addByPrefix('idle', 'Boyfriend DJ0', 24, true); - bfSprite.animation.play('idle'); - - bfSpritePlaceholder.rootComponent.add(bfSprite); - bfSpritePlaceholder.visible = false; - - new FlxTimer().start(0.10, (_timer:FlxTimer) -> - { - bfSprite.x = bfSpritePlaceholder.screenLeft; - bfSprite.y = bfSpritePlaceholder.screenTop; - bfSprite.setGraphicSize(Std.int(bfSpritePlaceholder.width), Std.int(bfSpritePlaceholder.height)); - bfSprite.visible = true; - }); - } - - // Add handlers to the "Create From Song" section. - var linkCreateBasic:Link = dialog.findComponent('splashCreateFromSongBasic', Link); - linkCreateBasic.onClick = (_event) -> - { - dialog.hideDialog(DialogButton.CANCEL); - - // Create song wizard - var uploadInstDialog = openUploadInstDialog(state, false); - uploadInstDialog.onDialogClosed = (_event) -> - { - state.isHaxeUIDialogOpen = false; - if (_event.button == DialogButton.APPLY) - { - var songMetadataDialog = openSongMetadataDialog(state); - songMetadataDialog.onDialogClosed = (_event) -> - { - state.isHaxeUIDialogOpen = false; - if (_event.button == DialogButton.APPLY) - { - var uploadVocalsDialog = openUploadVocalsDialog(state); - } - }; - } - }; - } - - // TODO: Get the list of songs and insert them as links into the "Create From Song" section. - - /* - var linkTemplateDadBattle:Link = dialog.findComponent('splashTemplateDadBattle', Link); - linkTemplateDadBattle.onClick = (_event) -> - { - dialog.hideDialog(DialogButton.CANCEL); - - // Load song from template - state.loadSongAsTemplate('dadbattle'); - } - var linkTemplateBopeebo:Link = dialog.findComponent('splashTemplateBopeebo', Link); - linkTemplateBopeebo.onClick = (_event) -> - { - dialog.hideDialog(DialogButton.CANCEL); - - // Load song from template - state.loadSongAsTemplate('bopeebo'); - } - */ - - var splashTemplateContainer:VBox = dialog.findComponent('splashTemplateContainer', VBox); - - var songList:Array = SongDataParser.listSongIds(); - - for (targetSongId in songList) { - var songData = SongDataParser.fetchSong(targetSongId); - - if (songData == null) - continue; - - var songName = songData.getDifficulty().songName; - - var linkTemplateSong:Link = new Link(); - linkTemplateSong.text = songName; - linkTemplateSong.onClick = (_event) -> - { - dialog.hideDialog(DialogButton.CANCEL); - - // Load song from template - state.loadSongAsTemplate(targetSongId); - } - - splashTemplateContainer.addComponent(linkTemplateSong); - } - - return dialog; - } - - public static function openUploadInstDialog(state:ChartEditorState, ?closable:Bool = true):Dialog - { - var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_UPLOAD_INST_LAYOUT, true, closable); - - var instrumentalBox:Box = dialog.findComponent('instrumentalBox', Box); - - instrumentalBox.onMouseOver = (_event) -> - { - instrumentalBox.swapClass('upload-bg', 'upload-bg-hover'); - Cursor.cursorMode = Pointer; - } - - instrumentalBox.onMouseOut = (_event) -> - { - instrumentalBox.swapClass('upload-bg-hover', 'upload-bg'); - Cursor.cursorMode = Default; - } - - var onDropFile:String->Void; - - instrumentalBox.onClick = (_event) -> - { - Dialogs.openBinaryFile("Open Instrumental", [{label: "Audio File (.ogg)", extension: "ogg"}], function(selectedFile) - { - if (selectedFile != null) - { - trace('Selected file: ' + selectedFile); - state.loadInstrumentalFromBytes(selectedFile.bytes); - dialog.hideDialog(DialogButton.APPLY); - removeDropHandler(onDropFile); - } - }); - } - - onDropFile = (path:String) -> - { - trace('Dropped file: ' + path); - state.loadInstrumentalFromPath(path); - dialog.hideDialog(DialogButton.APPLY); - removeDropHandler(onDropFile); - }; - - addDropHandler(onDropFile); - - return dialog; - } - - static function addDropHandler(handler:String->Void) - { - #if desktop - FlxG.stage.window.onDropFile.add(handler); - #else - trace('addDropHandler not implemented for this platform'); - #end - } - - static function removeDropHandler(handler:String->Void) - { - #if desktop - FlxG.stage.window.onDropFile.remove(handler); - #end - } - - public static function openSongMetadataDialog(state:ChartEditorState):Dialog - { - var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_SONG_METADATA_LAYOUT, true, false); - - var dialogSongName:TextField = dialog.findComponent('dialogSongName', TextField); - dialogSongName.onChange = (event:UIEvent) -> - { - var valid = event.target.text != null && event.target.text != ""; - - if (valid) - { - dialogSongName.removeClass('invalid-value'); - state.currentSongMetadata.songName = event.target.text; - } - else - { - state.currentSongMetadata.songName = null; - } - }; - state.currentSongMetadata.songName = null; - - var dialogSongArtist:TextField = dialog.findComponent('dialogSongArtist', TextField); - dialogSongArtist.onChange = (event:UIEvent) -> - { - var valid = event.target.text != null && event.target.text != ""; - - if (valid) - { - dialogSongArtist.removeClass('invalid-value'); - state.currentSongMetadata.artist = event.target.text; - } - else - { - state.currentSongMetadata.artist = null; - } - }; - state.currentSongMetadata.artist = null; - - var dialogStage:DropDown = dialog.findComponent('dialogStage', DropDown); - dialogStage.onChange = (event:UIEvent) -> - { - var valid = event.data != null && event.data.id != null; - - if (event.data.id == null) - return; - state.currentSongMetadata.playData.stage = event.data.id; - }; - state.currentSongMetadata.playData.stage = null; - - var dialogNoteSkin:DropDown = dialog.findComponent('dialogNoteSkin', DropDown); - dialogNoteSkin.onChange = (event:UIEvent) -> - { - if (event.data.id == null) - return; - state.currentSongMetadata.playData.noteSkin = event.data.id; - }; - state.currentSongMetadata.playData.noteSkin = null; - - var dialogBPM:NumberStepper = dialog.findComponent('dialogBPM', NumberStepper); - dialogBPM.onChange = (event:UIEvent) -> - { - if (event.value == null || event.value <= 0) - return; - - var timeChanges = state.currentSongMetadata.timeChanges; - if (timeChanges == null || timeChanges.length == 0) - { - timeChanges = [new SongTimeChange(-1, 0, event.value, 4, 4, [4, 4, 4, 4])]; - } - else - { - timeChanges[0].bpm = event.value; - } - - Conductor.forceBPM(event.value); - - state.currentSongMetadata.timeChanges = timeChanges; - }; - - var dialogCharGrid:PropertyGrid = dialog.findComponent('dialogCharGrid', PropertyGrid); - var dialogCharAdd:Button = dialog.findComponent('dialogCharAdd', Button); - dialogCharAdd.onClick = (_event) -> - { - var charGroup:PropertyGroup; - charGroup = buildCharGroup(state, null, () -> - { - dialogCharGrid.removeComponent(charGroup); - }); - dialogCharGrid.addComponent(charGroup); - }; - - // Empty the character list. - state.currentSongMetadata.playData.playableChars = {}; - // Add at least one character group with no Remove button. - dialogCharGrid.addComponent(buildCharGroup(state, 'bf', null)); - - var dialogContinue:Button = dialog.findComponent('dialogContinue', Button); - dialogContinue.onClick = (_event) -> - { - dialog.hideDialog(DialogButton.APPLY); - }; - - return dialog; - } - - static function buildCharGroup(state:ChartEditorState, ?key:String = null, removeFunc:Void->Void):PropertyGroup - { - var groupKey = key; - - var getCharData = () -> - { - if (groupKey == null) - groupKey = 'newChar${state.currentSongMetadata.playData.playableChars.keys().count()}'; - - var result = state.currentSongMetadata.playData.playableChars.get(groupKey); - if (result == null) - { - result = new SongPlayableChar('', 'dad'); - state.currentSongMetadata.playData.playableChars.set(groupKey, result); - } - return result; - } - - var moveCharGroup = (target:String) -> - { - var charData = getCharData(); - state.currentSongMetadata.playData.playableChars.remove(groupKey); - state.currentSongMetadata.playData.playableChars.set(target, charData); - groupKey = target; - } - - var removeGroup = () -> - { - state.currentSongMetadata.playData.playableChars.remove(groupKey); - removeFunc(); - } - - var charData = getCharData(); - - var charGroup:PropertyGroup = cast state.buildComponent(CHART_EDITOR_DIALOG_SONG_METADATA_CHARGROUP_LAYOUT); - - var charGroupPlayer:DropDown = charGroup.findComponent('charGroupPlayer', DropDown); - charGroupPlayer.onChange = (event:UIEvent) -> - { - charGroup.text = event.data.text; - moveCharGroup(event.data.id); - }; - - if (key == null) - { - // Find the next available player character. - trace(charGroupPlayer.dataSource.data); - } - - var charGroupOpponent:DropDown = charGroup.findComponent('charGroupOpponent', DropDown); - charGroupOpponent.onChange = (event:UIEvent) -> - { - charData.opponent = event.data.id; - }; - charGroupOpponent.value = getCharData().opponent; - - var charGroupGirlfriend:DropDown = charGroup.findComponent('charGroupGirlfriend', DropDown); - charGroupGirlfriend.onChange = (event:UIEvent) -> - { - charData.girlfriend = event.data.id; - }; - charGroupGirlfriend.value = getCharData().girlfriend; - - var charGroupRemove:Button = charGroup.findComponent('charGroupRemove', Button); - charGroupRemove.onClick = (_event:MouseEvent) -> - { - removeGroup(); - }; - - if (removeFunc == null) - charGroupRemove.hidden = true; - - return charGroup; - } - - public static function openUploadVocalsDialog(state:ChartEditorState, ?closable:Bool = true):Dialog - { - var charIdsForVocals = []; - - for (charKey in state.currentSongMetadata.playData.playableChars.keys()) - { - var charData = state.currentSongMetadata.playData.playableChars.get(charKey); - charIdsForVocals.push(charKey); - if (charData.opponent != null) - charIdsForVocals.push(charData.opponent); - } - - var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_UPLOAD_VOCALS_LAYOUT, true, closable); - - var dialogContainer = dialog.findComponent('vocalContainer'); - - var onDropFile:String->Void; - - for (charKey in charIdsForVocals) - { - trace('Adding vocal upload for character ${charKey}'); - var charMetadata:BaseCharacter = CharacterDataParser.fetchCharacter(charKey); - var charName:String = charMetadata.characterName; - - var vocalsEntry = state.buildComponent(CHART_EDITOR_DIALOG_UPLOAD_VOCALS_ENTRY_LAYOUT); - - var vocalsEntryLabel:Label = vocalsEntry.findComponent('vocalsEntryLabel', Label); - vocalsEntryLabel.text = 'Click to browse for a vocal track for $charName.'; - - vocalsEntry.onClick = (_event) -> - { - Dialogs.openBinaryFile('Open $charName Vocals', [{label: "Audio File (.ogg)", extension: "ogg"}], function(selectedFile) - { - if (selectedFile != null) - { - trace('Selected file: ' + selectedFile.name + "~" + selectedFile.fullPath); - vocalsEntryLabel.text = 'Vocals for $charName (click to browse)\n${selectedFile.name}'; - state.loadVocalsFromBytes(selectedFile.bytes); - removeDropHandler(onDropFile); - } - }); - } - - dialogContainer.addComponent(vocalsEntry); - } - - var dialogContinue:Button = dialog.findComponent('dialogContinue', Button); - dialogContinue.onClick = (_event) -> - { - dialog.hideDialog(DialogButton.APPLY); - }; - - // TODO: Redo the logic for file drop handler to be more robust. - // We need to distinguish which component the mouse is over when the file is dropped. - - onDropFile = (path:String) -> - { - trace('Dropped file: ' + path); - }; - addDropHandler(onDropFile); - - return dialog; - } - - /** - * Builds and opens a dialog displaying the user guide, providing guidance and help on how to use the chart editor. - */ - public static inline function openUserGuideDialog(state:ChartEditorState):Dialog - { - return openDialog(state, CHART_EDITOR_DIALOG_USER_GUIDE_LAYOUT, true, true); - } - - /** - * Builds and opens a dialog from a given layout path. - * @param modal Makes the background uninteractable while the dialog is open. - * @param closable Hides the close button on the dialog, preventing it from being closed unless the user interacts with the dialog. - */ - static function openDialog(state:ChartEditorState, key:String, modal:Bool = true, closable:Bool = true):Dialog - { - var dialog:Dialog = cast state.buildComponent(key); - dialog.destroyOnClose = true; - dialog.closable = closable; - dialog.showDialog(modal); - - state.isHaxeUIDialogOpen = true; - dialog.onDialogClosed = (_event) -> - { - state.isHaxeUIDialogOpen = false; - }; - - return dialog; - } + static final CHART_EDITOR_DIALOG_ABOUT_LAYOUT = Paths.ui('chart-editor/dialogs/about'); + static final CHART_EDITOR_DIALOG_WELCOME_LAYOUT = Paths.ui('chart-editor/dialogs/welcome'); + static final CHART_EDITOR_DIALOG_UPLOAD_INST_LAYOUT = Paths.ui('chart-editor/dialogs/upload-inst'); + static final CHART_EDITOR_DIALOG_SONG_METADATA_LAYOUT = Paths.ui('chart-editor/dialogs/song-metadata'); + static final CHART_EDITOR_DIALOG_SONG_METADATA_CHARGROUP_LAYOUT = Paths.ui('chart-editor/dialogs/song-metadata-chargroup'); + static final CHART_EDITOR_DIALOG_UPLOAD_VOCALS_LAYOUT = Paths.ui('chart-editor/dialogs/upload-vocals'); + static final CHART_EDITOR_DIALOG_UPLOAD_VOCALS_ENTRY_LAYOUT = Paths.ui('chart-editor/dialogs/upload-vocals-entry'); + static final CHART_EDITOR_DIALOG_USER_GUIDE_LAYOUT = Paths.ui('chart-editor/dialogs/user-guide'); + + /** + * + */ + public static inline function openAboutDialog(state:ChartEditorState):Dialog + { + return openDialog(state, CHART_EDITOR_DIALOG_ABOUT_LAYOUT, true, true); + } + + /** + * Builds and opens a dialog letting the user create a new chart, open a recent chart, or load from a template. + */ + public static function openWelcomeDialog(state:ChartEditorState, closable:Bool = true):Dialog + { + var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_WELCOME_LAYOUT, true, closable); + + // TODO: Add callbacks to the dialog buttons + + // Switch the graphic for frames. + var bfSpritePlaceholder:Image = dialog.findComponent('bfSprite', Image); + + // TODO: Replace this bullshit with a custom HaxeUI component that loads the sprite from the game's assets. + + if (bfSpritePlaceholder != null) + { + var bfSprite:FlxSprite = new FlxSprite(0, 0); + + bfSprite.visible = false; + + var frames = Paths.getSparrowAtlas(bfSpritePlaceholder.resource); + bfSprite.frames = frames; + + bfSprite.animation.addByPrefix('idle', 'Boyfriend DJ0', 24, true); + bfSprite.animation.play('idle'); + + bfSpritePlaceholder.rootComponent.add(bfSprite); + bfSpritePlaceholder.visible = false; + + new FlxTimer().start(0.10, (_timer:FlxTimer) -> + { + bfSprite.x = bfSpritePlaceholder.screenLeft; + bfSprite.y = bfSpritePlaceholder.screenTop; + bfSprite.setGraphicSize(Std.int(bfSpritePlaceholder.width), Std.int(bfSpritePlaceholder.height)); + bfSprite.visible = true; + }); + } + + // Add handlers to the "Create From Song" section. + var linkCreateBasic:Link = dialog.findComponent('splashCreateFromSongBasic', Link); + linkCreateBasic.onClick = (_event) -> + { + dialog.hideDialog(DialogButton.CANCEL); + + // Create song wizard + var uploadInstDialog = openUploadInstDialog(state, false); + uploadInstDialog.onDialogClosed = (_event) -> + { + state.isHaxeUIDialogOpen = false; + if (_event.button == DialogButton.APPLY) + { + var songMetadataDialog = openSongMetadataDialog(state); + songMetadataDialog.onDialogClosed = (_event) -> + { + state.isHaxeUIDialogOpen = false; + if (_event.button == DialogButton.APPLY) + { + var uploadVocalsDialog = openUploadVocalsDialog(state); + } + }; + } + }; + } + + // TODO: Get the list of songs and insert them as links into the "Create From Song" section. + + /* + var linkTemplateDadBattle:Link = dialog.findComponent('splashTemplateDadBattle', Link); + linkTemplateDadBattle.onClick = (_event) -> + { + dialog.hideDialog(DialogButton.CANCEL); + + // Load song from template + state.loadSongAsTemplate('dadbattle'); + } + var linkTemplateBopeebo:Link = dialog.findComponent('splashTemplateBopeebo', Link); + linkTemplateBopeebo.onClick = (_event) -> + { + dialog.hideDialog(DialogButton.CANCEL); + + // Load song from template + state.loadSongAsTemplate('bopeebo'); + } + */ + + var splashTemplateContainer:VBox = dialog.findComponent('splashTemplateContainer', VBox); + + var songList:Array = SongDataParser.listSongIds(); + + for (targetSongId in songList) + { + var songData = SongDataParser.fetchSong(targetSongId); + + if (songData == null) continue; + + var songName = songData.getDifficulty().songName; + + var linkTemplateSong:Link = new Link(); + linkTemplateSong.text = songName; + linkTemplateSong.onClick = (_event) -> + { + dialog.hideDialog(DialogButton.CANCEL); + + // Load song from template + state.loadSongAsTemplate(targetSongId); + } + + splashTemplateContainer.addComponent(linkTemplateSong); + } + + return dialog; + } + + public static function openUploadInstDialog(state:ChartEditorState, ?closable:Bool = true):Dialog + { + var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_UPLOAD_INST_LAYOUT, true, closable); + + var instrumentalBox:Box = dialog.findComponent('instrumentalBox', Box); + + instrumentalBox.onMouseOver = (_event) -> + { + instrumentalBox.swapClass('upload-bg', 'upload-bg-hover'); + Cursor.cursorMode = Pointer; + } + + instrumentalBox.onMouseOut = (_event) -> + { + instrumentalBox.swapClass('upload-bg-hover', 'upload-bg'); + Cursor.cursorMode = Default; + } + + var onDropFile:String->Void; + + instrumentalBox.onClick = (_event) -> + { + Dialogs.openBinaryFile("Open Instrumental", [ + {label: "Audio File (.ogg)", extension: "ogg"}], function(selectedFile) + { + if (selectedFile != null) + { + trace('Selected file: ' + selectedFile); + state.loadInstrumentalFromBytes(selectedFile.bytes); + dialog.hideDialog(DialogButton.APPLY); + removeDropHandler(onDropFile); + } + }); + } + + onDropFile = (path:String) -> + { + trace('Dropped file: ' + path); + state.loadInstrumentalFromPath(path); + dialog.hideDialog(DialogButton.APPLY); + removeDropHandler(onDropFile); + }; + + addDropHandler(onDropFile); + + return dialog; + } + + static function addDropHandler(handler:String->Void) + { + #if desktop + FlxG.stage.window.onDropFile.add(handler); + #else + trace('addDropHandler not implemented for this platform'); + #end + } + + static function removeDropHandler(handler:String->Void) + { + #if desktop + FlxG.stage.window.onDropFile.remove(handler); + #end + } + + public static function openSongMetadataDialog(state:ChartEditorState):Dialog + { + var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_SONG_METADATA_LAYOUT, true, false); + + var dialogSongName:TextField = dialog.findComponent('dialogSongName', TextField); + dialogSongName.onChange = (event:UIEvent) -> + { + var valid = event.target.text != null && event.target.text != ""; + + if (valid) + { + dialogSongName.removeClass('invalid-value'); + state.currentSongMetadata.songName = event.target.text; + } + else + { + state.currentSongMetadata.songName = null; + } + }; + state.currentSongMetadata.songName = null; + + var dialogSongArtist:TextField = dialog.findComponent('dialogSongArtist', TextField); + dialogSongArtist.onChange = (event:UIEvent) -> + { + var valid = event.target.text != null && event.target.text != ""; + + if (valid) + { + dialogSongArtist.removeClass('invalid-value'); + state.currentSongMetadata.artist = event.target.text; + } + else + { + state.currentSongMetadata.artist = null; + } + }; + state.currentSongMetadata.artist = null; + + var dialogStage:DropDown = dialog.findComponent('dialogStage', DropDown); + dialogStage.onChange = (event:UIEvent) -> + { + var valid = event.data != null && event.data.id != null; + + if (event.data.id == null) return; + state.currentSongMetadata.playData.stage = event.data.id; + }; + state.currentSongMetadata.playData.stage = null; + + var dialogNoteSkin:DropDown = dialog.findComponent('dialogNoteSkin', DropDown); + dialogNoteSkin.onChange = (event:UIEvent) -> + { + if (event.data.id == null) return; + state.currentSongMetadata.playData.noteSkin = event.data.id; + }; + state.currentSongMetadata.playData.noteSkin = null; + + var dialogBPM:NumberStepper = dialog.findComponent('dialogBPM', NumberStepper); + dialogBPM.onChange = (event:UIEvent) -> + { + if (event.value == null || event.value <= 0) return; + + var timeChanges = state.currentSongMetadata.timeChanges; + if (timeChanges == null || timeChanges.length == 0) + { + timeChanges = [new SongTimeChange(-1, 0, event.value, 4, 4, [4, 4, 4, 4])]; + } + else + { + timeChanges[0].bpm = event.value; + } + + Conductor.forceBPM(event.value); + + state.currentSongMetadata.timeChanges = timeChanges; + }; + + var dialogCharGrid:PropertyGrid = dialog.findComponent('dialogCharGrid', PropertyGrid); + var dialogCharAdd:Button = dialog.findComponent('dialogCharAdd', Button); + dialogCharAdd.onClick = (_event) -> + { + var charGroup:PropertyGroup; + charGroup = buildCharGroup(state, null, () -> + { + dialogCharGrid.removeComponent(charGroup); + }); + dialogCharGrid.addComponent(charGroup); + }; + + // Empty the character list. + state.currentSongMetadata.playData.playableChars = {}; + // Add at least one character group with no Remove button. + dialogCharGrid.addComponent(buildCharGroup(state, 'bf', null)); + + var dialogContinue:Button = dialog.findComponent('dialogContinue', Button); + dialogContinue.onClick = (_event) -> + { + dialog.hideDialog(DialogButton.APPLY); + }; + + return dialog; + } + + static function buildCharGroup(state:ChartEditorState, ?key:String = null, removeFunc:Void->Void):PropertyGroup + { + var groupKey = key; + + var getCharData = () -> + { + if (groupKey == null) groupKey = 'newChar${state.currentSongMetadata.playData.playableChars.keys().count()}'; + + var result = state.currentSongMetadata.playData.playableChars.get(groupKey); + if (result == null) + { + result = new SongPlayableChar('', 'dad'); + state.currentSongMetadata.playData.playableChars.set(groupKey, result); + } + return result; + } + + var moveCharGroup = (target:String) -> + { + var charData = getCharData(); + state.currentSongMetadata.playData.playableChars.remove(groupKey); + state.currentSongMetadata.playData.playableChars.set(target, charData); + groupKey = target; + } + + var removeGroup = () -> + { + state.currentSongMetadata.playData.playableChars.remove(groupKey); + removeFunc(); + } + + var charData = getCharData(); + + var charGroup:PropertyGroup = cast state.buildComponent(CHART_EDITOR_DIALOG_SONG_METADATA_CHARGROUP_LAYOUT); + + var charGroupPlayer:DropDown = charGroup.findComponent('charGroupPlayer', DropDown); + charGroupPlayer.onChange = (event:UIEvent) -> + { + charGroup.text = event.data.text; + moveCharGroup(event.data.id); + }; + + if (key == null) + { + // Find the next available player character. + trace(charGroupPlayer.dataSource.data); + } + + var charGroupOpponent:DropDown = charGroup.findComponent('charGroupOpponent', DropDown); + charGroupOpponent.onChange = (event:UIEvent) -> + { + charData.opponent = event.data.id; + }; + charGroupOpponent.value = getCharData().opponent; + + var charGroupGirlfriend:DropDown = charGroup.findComponent('charGroupGirlfriend', DropDown); + charGroupGirlfriend.onChange = (event:UIEvent) -> + { + charData.girlfriend = event.data.id; + }; + charGroupGirlfriend.value = getCharData().girlfriend; + + var charGroupRemove:Button = charGroup.findComponent('charGroupRemove', Button); + charGroupRemove.onClick = (_event:MouseEvent) -> + { + removeGroup(); + }; + + if (removeFunc == null) charGroupRemove.hidden = true; + + return charGroup; + } + + public static function openUploadVocalsDialog(state:ChartEditorState, ?closable:Bool = true):Dialog + { + var charIdsForVocals = []; + + for (charKey in state.currentSongMetadata.playData.playableChars.keys()) + { + var charData = state.currentSongMetadata.playData.playableChars.get(charKey); + charIdsForVocals.push(charKey); + if (charData.opponent != null) charIdsForVocals.push(charData.opponent); + } + + var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_UPLOAD_VOCALS_LAYOUT, true, closable); + + var dialogContainer = dialog.findComponent('vocalContainer'); + + var onDropFile:String->Void; + + for (charKey in charIdsForVocals) + { + trace('Adding vocal upload for character ${charKey}'); + var charMetadata:BaseCharacter = CharacterDataParser.fetchCharacter(charKey); + var charName:String = charMetadata.characterName; + + var vocalsEntry = state.buildComponent(CHART_EDITOR_DIALOG_UPLOAD_VOCALS_ENTRY_LAYOUT); + + var vocalsEntryLabel:Label = vocalsEntry.findComponent('vocalsEntryLabel', Label); + vocalsEntryLabel.text = 'Click to browse for a vocal track for $charName.'; + + vocalsEntry.onClick = (_event) -> + { + Dialogs.openBinaryFile('Open $charName Vocals', [ + {label: "Audio File (.ogg)", extension: "ogg"}], function(selectedFile) + { + if (selectedFile != null) + { + trace('Selected file: ' + selectedFile.name + "~" + selectedFile.fullPath); + vocalsEntryLabel.text = 'Vocals for $charName (click to browse)\n${selectedFile.name}'; + state.loadVocalsFromBytes(selectedFile.bytes); + removeDropHandler(onDropFile); + } + }); + } + + dialogContainer.addComponent(vocalsEntry); + } + + var dialogContinue:Button = dialog.findComponent('dialogContinue', Button); + dialogContinue.onClick = (_event) -> + { + dialog.hideDialog(DialogButton.APPLY); + }; + + // TODO: Redo the logic for file drop handler to be more robust. + // We need to distinguish which component the mouse is over when the file is dropped. + + onDropFile = (path:String) -> + { + trace('Dropped file: ' + path); + }; + addDropHandler(onDropFile); + + return dialog; + } + + /** + * Builds and opens a dialog displaying the user guide, providing guidance and help on how to use the chart editor. + */ + public static inline function openUserGuideDialog(state:ChartEditorState):Dialog + { + return openDialog(state, CHART_EDITOR_DIALOG_USER_GUIDE_LAYOUT, true, true); + } + + /** + * Builds and opens a dialog from a given layout path. + * @param modal Makes the background uninteractable while the dialog is open. + * @param closable Hides the close button on the dialog, preventing it from being closed unless the user interacts with the dialog. + */ + static function openDialog(state:ChartEditorState, key:String, modal:Bool = true, closable:Bool = true):Dialog + { + var dialog:Dialog = cast state.buildComponent(key); + dialog.destroyOnClose = true; + dialog.closable = closable; + dialog.showDialog(modal); + + state.isHaxeUIDialogOpen = true; + dialog.onDialogClosed = (_event) -> + { + state.isHaxeUIDialogOpen = false; + }; + + return dialog; + } } diff --git a/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx b/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx index 1c1580f7a..323d11abd 100644 --- a/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx +++ b/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx @@ -16,86 +16,85 @@ import funkin.play.song.SongData.SongEventData; */ class ChartEditorEventSprite extends FlxSprite { - public var parentState:ChartEditorState; + public var parentState:ChartEditorState; - /** - * The note data that this sprite represents. - * You can set this to null to kill the sprite and flag it for recycling. - */ - public var eventData(default, set):SongEventData; + /** + * The note data that this sprite represents. + * You can set this to null to kill the sprite and flag it for recycling. + */ + public var eventData(default, set):SongEventData; - /** - * The image used for all song events. Cached for performance. - */ - var eventGraphic:BitmapData; + /** + * The image used for all song events. Cached for performance. + */ + var eventGraphic:BitmapData; - public function new(parent:ChartEditorState) - { - super(); + public function new(parent:ChartEditorState) + { + super(); - this.parentState = parent; + this.parentState = parent; - buildGraphic(); - } + buildGraphic(); + } - function buildGraphic():Void - { - if (eventGraphic == null) - { - eventGraphic = Assets.getBitmapData(Paths.image('ui/chart-editor/event')); - } + function buildGraphic():Void + { + if (eventGraphic == null) + { + eventGraphic = Assets.getBitmapData(Paths.image('ui/chart-editor/event')); + } - loadGraphic(eventGraphic); - setGraphicSize(ChartEditorState.GRID_SIZE); - this.updateHitbox(); - } + loadGraphic(eventGraphic); + setGraphicSize(ChartEditorState.GRID_SIZE); + this.updateHitbox(); + } - function set_eventData(value:SongEventData):SongEventData - { - this.eventData = value; + function set_eventData(value:SongEventData):SongEventData + { + this.eventData = value; - if (this.eventData == null) - { - // Disown parent. - this.kill(); - return this.eventData; - } + if (this.eventData == null) + { + // Disown parent. + this.kill(); + return this.eventData; + } - this.visible = true; + this.visible = true; - // Update the position to match the note data. - updateEventPosition(); + // Update the position to match the note data. + updateEventPosition(); - return this.eventData; - } + return this.eventData; + } - public function updateEventPosition(?origin:FlxObject) - { - this.x = (ChartEditorState.STRUMLINE_SIZE * 2 + 1 - 1) * ChartEditorState.GRID_SIZE; - if (this.eventData.stepTime >= 0) - this.y = this.eventData.stepTime * ChartEditorState.GRID_SIZE; + public function updateEventPosition(?origin:FlxObject) + { + this.x = (ChartEditorState.STRUMLINE_SIZE * 2 + 1 - 1) * ChartEditorState.GRID_SIZE; + if (this.eventData.stepTime >= 0) this.y = this.eventData.stepTime * ChartEditorState.GRID_SIZE; - if (origin != null) - { - this.x += origin.x; - this.y += origin.y; - } - } + if (origin != null) + { + this.x += origin.x; + this.y += origin.y; + } + } - /** - * Return whether this note (or its parent) is currently visible. - */ - public function isEventVisible(viewAreaBottom:Float, viewAreaTop:Float):Bool - { - var outsideViewArea = (this.y + this.height < viewAreaTop || this.y > viewAreaBottom); + /** + * Return whether this note (or its parent) is currently visible. + */ + public function isEventVisible(viewAreaBottom:Float, viewAreaTop:Float):Bool + { + var outsideViewArea = (this.y + this.height < viewAreaTop || this.y > viewAreaBottom); - if (!outsideViewArea) - { - return true; - } + if (!outsideViewArea) + { + return true; + } - // TODO: Check if this note's parent or child is visible. + // TODO: Check if this note's parent or child is visible. - return false; - } + return false; + } } diff --git a/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx b/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx index bdf124766..85a1f86a2 100644 --- a/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx +++ b/source/funkin/ui/debug/charting/ChartEditorNoteSprite.hx @@ -14,275 +14,270 @@ import funkin.play.song.SongData.SongNoteData; */ class ChartEditorNoteSprite extends FlxSprite { - public var parentState:ChartEditorState; + public var parentState:ChartEditorState; - /** - * The note data that this sprite represents. - * You can set this to null to kill the sprite and flag it for recycling. - */ - public var noteData(default, set):SongNoteData; + /** + * The note data that this sprite represents. + * You can set this to null to kill the sprite and flag it for recycling. + */ + public var noteData(default, set):SongNoteData; - /** - * This note is the previous sprite in a sustain chain. - */ - public var parentNoteSprite(default, set):ChartEditorNoteSprite = null; + /** + * This note is the previous sprite in a sustain chain. + */ + public var parentNoteSprite(default, set):ChartEditorNoteSprite = null; - /** - * This note is the next sprite in a sustain chain. - */ - public var childNoteSprite(default, set):ChartEditorNoteSprite = null; + /** + * This note is the next sprite in a sustain chain. + */ + public var childNoteSprite(default, set):ChartEditorNoteSprite = null; - public function new(parent:ChartEditorState) - { - super(); + public function new(parent:ChartEditorState) + { + super(); - this.parentState = parent; + this.parentState = parent; - if (noteFrameCollection == null) - { - initFrameCollection(); - } + if (noteFrameCollection == null) + { + initFrameCollection(); + } - this.frames = noteFrameCollection; + this.frames = noteFrameCollection; - // Initialize all the animations, not just the one we're going to use immediately, - // so that later we can reuse the sprite without having to initialize more animations during scrolling. - this.animation.addByPrefix('tapLeftNormal', 'purple instance'); - this.animation.addByPrefix('tapDownNormal', 'blue instance'); - this.animation.addByPrefix('tapUpNormal', 'green instance'); - this.animation.addByPrefix('tapRightNormal', 'red instance'); + // Initialize all the animations, not just the one we're going to use immediately, + // so that later we can reuse the sprite without having to initialize more animations during scrolling. + this.animation.addByPrefix('tapLeftNormal', 'purple instance'); + this.animation.addByPrefix('tapDownNormal', 'blue instance'); + this.animation.addByPrefix('tapUpNormal', 'green instance'); + this.animation.addByPrefix('tapRightNormal', 'red instance'); - this.animation.addByPrefix('holdLeftNormal', 'LeftHoldPiece'); - this.animation.addByPrefix('holdDownNormal', 'DownHoldPiece'); - this.animation.addByPrefix('holdUpNormal', 'UpHoldPiece'); - this.animation.addByPrefix('holdRightNormal', 'RightHoldPiece'); + this.animation.addByPrefix('holdLeftNormal', 'LeftHoldPiece'); + this.animation.addByPrefix('holdDownNormal', 'DownHoldPiece'); + this.animation.addByPrefix('holdUpNormal', 'UpHoldPiece'); + this.animation.addByPrefix('holdRightNormal', 'RightHoldPiece'); - this.animation.addByPrefix('holdEndLeftNormal', 'LeftHoldEnd'); - this.animation.addByPrefix('holdEndDownNormal', 'DownHoldEnd'); - this.animation.addByPrefix('holdEndUpNormal', 'UpHoldEnd'); - this.animation.addByPrefix('holdEndRightNormal', 'RightHoldEnd'); + this.animation.addByPrefix('holdEndLeftNormal', 'LeftHoldEnd'); + this.animation.addByPrefix('holdEndDownNormal', 'DownHoldEnd'); + this.animation.addByPrefix('holdEndUpNormal', 'UpHoldEnd'); + this.animation.addByPrefix('holdEndRightNormal', 'RightHoldEnd'); - this.animation.addByPrefix('tapLeftPixel', 'pixel4'); - this.animation.addByPrefix('tapDownPixel', 'pixel5'); - this.animation.addByPrefix('tapUpPixel', 'pixel6'); - this.animation.addByPrefix('tapRightPixel', 'pixel7'); - } + this.animation.addByPrefix('tapLeftPixel', 'pixel4'); + this.animation.addByPrefix('tapDownPixel', 'pixel5'); + this.animation.addByPrefix('tapUpPixel', 'pixel6'); + this.animation.addByPrefix('tapRightPixel', 'pixel7'); + } - static var noteFrameCollection:FlxFramesCollection = null; + static var noteFrameCollection:FlxFramesCollection = null; - /** - * We load all the note frames once, then reuse them. - */ - static function initFrameCollection():Void - { - noteFrameCollection = new FlxFramesCollection(null, ATLAS, null); + /** + * We load all the note frames once, then reuse them. + */ + static function initFrameCollection():Void + { + noteFrameCollection = new FlxFramesCollection(null, ATLAS, null); - // TODO: Automatically iterate over the list of note skins. + // TODO: Automatically iterate over the list of note skins. - // Normal notes - var frameCollectionNormal = Paths.getSparrowAtlas('NOTE_assets'); + // Normal notes + var frameCollectionNormal = Paths.getSparrowAtlas('NOTE_assets'); - for (frame in frameCollectionNormal.frames) - { - noteFrameCollection.pushFrame(frame); - } - var frameCollectionNormal2 = Paths.getSparrowAtlas('NoteHoldNormal'); + for (frame in frameCollectionNormal.frames) + { + noteFrameCollection.pushFrame(frame); + } + var frameCollectionNormal2 = Paths.getSparrowAtlas('NoteHoldNormal'); - for (frame in frameCollectionNormal2.frames) - { - noteFrameCollection.pushFrame(frame); - } + for (frame in frameCollectionNormal2.frames) + { + noteFrameCollection.pushFrame(frame); + } - // Pixel notes - var graphicPixel = FlxG.bitmap.add(Paths.image('weeb/pixelUI/arrows-pixels', 'week6'), false, null); - if (graphicPixel == null) - trace('ERROR: Could not load graphic: ' + Paths.image('weeb/pixelUI/arrows-pixels', 'week6')); - var frameCollectionPixel = FlxTileFrames.fromGraphic(graphicPixel, new FlxPoint(17, 17)); - for (i in 0...frameCollectionPixel.frames.length) - { - var frame = frameCollectionPixel.frames[i]; + // Pixel notes + var graphicPixel = FlxG.bitmap.add(Paths.image('weeb/pixelUI/arrows-pixels', 'week6'), false, null); + if (graphicPixel == null) trace('ERROR: Could not load graphic: ' + Paths.image('weeb/pixelUI/arrows-pixels', 'week6')); + var frameCollectionPixel = FlxTileFrames.fromGraphic(graphicPixel, new FlxPoint(17, 17)); + for (i in 0...frameCollectionPixel.frames.length) + { + var frame = frameCollectionPixel.frames[i]; - frame.name = 'pixel' + i; - noteFrameCollection.pushFrame(frame); - } - } + frame.name = 'pixel' + i; + noteFrameCollection.pushFrame(frame); + } + } - function set_noteData(value:SongNoteData):SongNoteData - { - this.noteData = value; + function set_noteData(value:SongNoteData):SongNoteData + { + this.noteData = value; - if (this.noteData == null) - { - // Disown parent. - this.parentNoteSprite = null; - if (this.childNoteSprite != null) - { - // Kill all children and disown them. - this.childNoteSprite.noteData = null; - this.childNoteSprite = null; - } - this.kill(); - return this.noteData; - } + if (this.noteData == null) + { + // Disown parent. + this.parentNoteSprite = null; + if (this.childNoteSprite != null) + { + // Kill all children and disown them. + this.childNoteSprite.noteData = null; + this.childNoteSprite = null; + } + this.kill(); + return this.noteData; + } - this.visible = true; + this.visible = true; - // Update the animation to match the note data. - // Animation is updated first so size is correct before updating position. - playNoteAnimation(); + // Update the animation to match the note data. + // Animation is updated first so size is correct before updating position. + playNoteAnimation(); - // Update the position to match the note data. - updateNotePosition(); + // Update the position to match the note data. + updateNotePosition(); - return this.noteData; - } + return this.noteData; + } - public function updateNotePosition(?origin:FlxObject) - { - var cursorColumn:Int = this.noteData.data; + public function updateNotePosition(?origin:FlxObject) + { + var cursorColumn:Int = this.noteData.data; - if (cursorColumn < 0) - cursorColumn = 0; - if (cursorColumn >= (ChartEditorState.STRUMLINE_SIZE * 2 + 1)) - { - cursorColumn = (ChartEditorState.STRUMLINE_SIZE * 2 + 1); - } - else - { - // Invert player and opponent columns. - if (cursorColumn >= ChartEditorState.STRUMLINE_SIZE) - { - cursorColumn -= ChartEditorState.STRUMLINE_SIZE; - } - else - { - cursorColumn += ChartEditorState.STRUMLINE_SIZE; - } - } + if (cursorColumn < 0) cursorColumn = 0; + if (cursorColumn >= (ChartEditorState.STRUMLINE_SIZE * 2 + 1)) + { + cursorColumn = (ChartEditorState.STRUMLINE_SIZE * 2 + 1); + } + else + { + // Invert player and opponent columns. + if (cursorColumn >= ChartEditorState.STRUMLINE_SIZE) + { + cursorColumn -= ChartEditorState.STRUMLINE_SIZE; + } + else + { + cursorColumn += ChartEditorState.STRUMLINE_SIZE; + } + } - if (parentNoteSprite == null) - { - this.x = cursorColumn * ChartEditorState.GRID_SIZE; + if (parentNoteSprite == null) + { + this.x = cursorColumn * ChartEditorState.GRID_SIZE; - // Notes far in the song will start far down, but the group they belong to will have a high negative offset. - // TODO: stepTime doesn't account for fluctuating BPMs. - if (this.noteData.stepTime >= 0) - this.y = this.noteData.stepTime * ChartEditorState.GRID_SIZE; + // Notes far in the song will start far down, but the group they belong to will have a high negative offset. + // TODO: stepTime doesn't account for fluctuating BPMs. + if (this.noteData.stepTime >= 0) this.y = this.noteData.stepTime * ChartEditorState.GRID_SIZE; - if (origin != null) - { - this.x += origin.x; - this.y += origin.y; - } - } - else - { - // If this is a hold note, we need to adjust the position to be centered. - if (parentNoteSprite.parentNoteSprite == null) - { - this.x = parentNoteSprite.x; - this.x += (ChartEditorState.GRID_SIZE / 2); - this.x -= this.width / 2; - } - else - { - this.x = parentNoteSprite.x; - } + if (origin != null) + { + this.x += origin.x; + this.y += origin.y; + } + } + else + { + // If this is a hold note, we need to adjust the position to be centered. + if (parentNoteSprite.parentNoteSprite == null) + { + this.x = parentNoteSprite.x; + this.x += (ChartEditorState.GRID_SIZE / 2); + this.x -= this.width / 2; + } + else + { + this.x = parentNoteSprite.x; + } - this.y = parentNoteSprite.y; - if (parentNoteSprite.parentNoteSprite == null) - { - this.y += parentNoteSprite.height / 2; - } - else - { - this.y += parentNoteSprite.height - 1; - } - } - } + this.y = parentNoteSprite.y; + if (parentNoteSprite.parentNoteSprite == null) + { + this.y += parentNoteSprite.height / 2; + } + else + { + this.y += parentNoteSprite.height - 1; + } + } + } - function set_parentNoteSprite(value:ChartEditorNoteSprite):ChartEditorNoteSprite - { - this.parentNoteSprite = value; + function set_parentNoteSprite(value:ChartEditorNoteSprite):ChartEditorNoteSprite + { + this.parentNoteSprite = value; - if (this.parentNoteSprite != null) - { - this.noteData = this.parentNoteSprite.noteData; - } + if (this.parentNoteSprite != null) + { + this.noteData = this.parentNoteSprite.noteData; + } - return this.parentNoteSprite; - } + return this.parentNoteSprite; + } - function set_childNoteSprite(value:ChartEditorNoteSprite):ChartEditorNoteSprite - { - this.childNoteSprite = value; + function set_childNoteSprite(value:ChartEditorNoteSprite):ChartEditorNoteSprite + { + this.childNoteSprite = value; - if (this.parentNoteSprite != null) - { - this.noteData = this.parentNoteSprite.noteData; - } + if (this.parentNoteSprite != null) + { + this.noteData = this.parentNoteSprite.noteData; + } - return this.childNoteSprite; - } + return this.childNoteSprite; + } - public function playNoteAnimation() - { - // Decide whether to display a note or a sustain. - var baseAnimationName:String = 'tap'; - if (this.parentNoteSprite != null) - baseAnimationName = (this.childNoteSprite != null) ? 'hold' : 'holdEnd'; + public function playNoteAnimation() + { + // Decide whether to display a note or a sustain. + var baseAnimationName:String = 'tap'; + if (this.parentNoteSprite != null) baseAnimationName = (this.childNoteSprite != null) ? 'hold' : 'holdEnd'; - // Play the appropriate animation for the type, direction, and skin. - var animationName = '${baseAnimationName}${this.noteData.getDirectionName()}${this.parentState.currentSongNoteSkin}'; + // Play the appropriate animation for the type, direction, and skin. + var animationName = '${baseAnimationName}${this.noteData.getDirectionName()}${this.parentState.currentSongNoteSkin}'; - this.animation.play(animationName); + this.animation.play(animationName); - // Resize note. + // Resize note. - switch (baseAnimationName) - { - case 'tap': - this.setGraphicSize(0, ChartEditorState.GRID_SIZE); - case 'hold': - if (parentNoteSprite.parentNoteSprite == null) - { - this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), Std.int(ChartEditorState.GRID_SIZE / 2)); - } - else - { - this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), ChartEditorState.GRID_SIZE); - } - case 'holdEnd': - this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), Std.int(ChartEditorState.GRID_SIZE / 2)); - } - this.updateHitbox(); + switch (baseAnimationName) + { + case 'tap': + this.setGraphicSize(0, ChartEditorState.GRID_SIZE); + case 'hold': + if (parentNoteSprite.parentNoteSprite == null) + { + this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), Std.int(ChartEditorState.GRID_SIZE / 2)); + } + else + { + this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), ChartEditorState.GRID_SIZE); + } + case 'holdEnd': + this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), Std.int(ChartEditorState.GRID_SIZE / 2)); + } + this.updateHitbox(); - // TODO: Make this an attribute of the note skin. - this.antialiasing = (this.parentState.currentSongNoteSkin != 'Pixel'); - } + // TODO: Make this an attribute of the note skin. + this.antialiasing = (this.parentState.currentSongNoteSkin != 'Pixel'); + } - /** - * Return whether this note (or its parent) is currently visible. - */ - public function isNoteVisible(viewAreaBottom:Float, viewAreaTop:Float):Bool - { - var outsideViewArea = (this.y + this.height < viewAreaTop || this.y > viewAreaBottom); + /** + * Return whether this note (or its parent) is currently visible. + */ + public function isNoteVisible(viewAreaBottom:Float, viewAreaTop:Float):Bool + { + var outsideViewArea = (this.y + this.height < viewAreaTop || this.y > viewAreaBottom); - if (!outsideViewArea) - { - return true; - } + if (!outsideViewArea) + { + return true; + } - // TODO: Check if this note's parent or child is visible. + // TODO: Check if this note's parent or child is visible. - return false; - } + return false; + } - public function getBaseNoteSprite() - { - if (this.parentNoteSprite == null) - return this; - else - return this.parentNoteSprite; - } + public function getBaseNoteSprite() + { + if (this.parentNoteSprite == null) return this; + else + return this.parentNoteSprite; + } } diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index b86aa5e88..2140e17e1 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -235,8 +235,7 @@ class ChartEditorState extends HaxeUIState function get_songLengthInPixels():Int { - if (songLengthInPixels <= 0) - return 1000; + if (songLengthInPixels <= 0) return 1000; return songLengthInPixels; } @@ -279,8 +278,7 @@ class ChartEditorState extends HaxeUIState function set_currentTheme(value:ChartEditorTheme):ChartEditorTheme { - if (value == null || value == currentTheme) - return currentTheme; + if (value == null || value == currentTheme) return currentTheme; currentTheme = value; ChartEditorThemeHandler.updateTheme(this); @@ -472,8 +470,7 @@ class ChartEditorState extends HaxeUIState function set_saveDataDirty(value:Bool):Bool { - if (value == saveDataDirty) - return value; + if (value == saveDataDirty) return value; if (value) { @@ -1171,10 +1168,11 @@ class ChartEditorState extends HaxeUIState addUIClickListener('menubarItemCopy', (event:MouseEvent) -> { // Doesn't use a command because it's not undoable. - SongDataUtils.writeItemsToClipboard({ - notes: SongDataUtils.buildNoteClipboard(currentNoteSelection), - events: SongDataUtils.buildEventClipboard(currentEventSelection), - }); + SongDataUtils.writeItemsToClipboard( + { + notes: SongDataUtils.buildNoteClipboard(currentNoteSelection), + events: SongDataUtils.buildEventClipboard(currentEventSelection), + }); }); addUIClickListener('menubarItemCut', (event:MouseEvent) -> @@ -1222,17 +1220,20 @@ class ChartEditorState extends HaxeUIState performCommand(new DeselectAllItemsCommand(currentNoteSelection, currentEventSelection)); }); - addUIClickListener('menubarItemSelectRegion', (event:MouseEvent) -> { - // TODO: Implement this. - }); + addUIClickListener('menubarItemSelectRegion', (event:MouseEvent) -> + { + // TODO: Implement this. + }); - addUIClickListener('menubarItemSelectBeforeCursor', (event:MouseEvent) -> { - // TODO: Implement this. - }); + addUIClickListener('menubarItemSelectBeforeCursor', (event:MouseEvent) -> + { + // TODO: Implement this. + }); - addUIClickListener('menubarItemSelectAfterCursor', (event:MouseEvent) -> { - // TODO: Implement this. - }); + addUIClickListener('menubarItemSelectAfterCursor', (event:MouseEvent) -> + { + // TODO: Implement this. + }); addUIClickListener('menubarItemAbout', (event:MouseEvent) -> ChartEditorDialogHandler.openAboutDialog(this)); @@ -1246,15 +1247,13 @@ class ChartEditorState extends HaxeUIState addUIChangeListener('menuBarItemThemeLight', (event:UIEvent) -> { - if (event.target.value) - currentTheme = ChartEditorTheme.Light; + if (event.target.value) currentTheme = ChartEditorTheme.Light; }); setUICheckboxSelected('menuBarItemThemeLight', currentTheme == ChartEditorTheme.Light); addUIChangeListener('menuBarItemThemeDark', (event:UIEvent) -> { - if (event.target.value) - currentTheme = ChartEditorTheme.Dark; + if (event.target.value) currentTheme = ChartEditorTheme.Dark; }); setUICheckboxSelected('menuBarItemThemeDark', currentTheme == ChartEditorTheme.Dark); @@ -1280,8 +1279,7 @@ class ChartEditorState extends HaxeUIState addUIChangeListener('menubarItemVolumeInstrumental', (event:UIEvent) -> { var volume:Float = event.value / 100.0; - if (audioInstTrack != null) - audioInstTrack.volume = volume; + if (audioInstTrack != null) audioInstTrack.volume = volume; instVolumeLabel.text = 'Instrumental - ${Std.int(event.value)}%'; }); @@ -1289,8 +1287,7 @@ class ChartEditorState extends HaxeUIState addUIChangeListener('menubarItemVolumeVocals', (event:UIEvent) -> { var volume:Float = event.value / 100.0; - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.volume = volume; + if (audioVocalTrackGroup != null) audioVocalTrackGroup.volume = volume; vocalsVolumeLabel.text = 'Vocals - ${Std.int(event.value)}%'; }); @@ -1299,10 +1296,8 @@ class ChartEditorState extends HaxeUIState { var pitch = event.value * 2.0 / 100.0; #if FLX_PITCH - if (audioInstTrack != null) - audioInstTrack.pitch = pitch; - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.pitch = pitch; + if (audioInstTrack != null) audioInstTrack.pitch = pitch; + if (audioVocalTrackGroup != null) audioVocalTrackGroup.pitch = pitch; #end playbackSpeedLabel.text = 'Playback Speed - ${Std.int(event.value * 100) / 100}x'; }); @@ -1445,8 +1440,7 @@ class ChartEditorState extends HaxeUIState override function beatHit():Bool { // dispatchEvent gets called here. - if (!super.beatHit()) - return false; + if (!super.beatHit()) return false; if (shouldPlayMetronome && audioInstTrack.playing) { @@ -1462,8 +1456,7 @@ class ChartEditorState extends HaxeUIState override function stepHit():Bool { // dispatchEvent gets called here. - if (!super.stepHit()) - return false; + if (!super.stepHit()) return false; if (audioInstTrack.playing) { @@ -1483,8 +1476,7 @@ class ChartEditorState extends HaxeUIState function handleScrollKeybinds() { // Don't scroll when the cursor is over the UI. - if (isCursorOverHaxeUI) - return; + if (isCursorOverHaxeUI) return; // Amount to scroll the grid. var scrollAmount:Float = 0; @@ -1591,8 +1583,7 @@ class ChartEditorState extends HaxeUIState this.playheadPositionInPixels += playheadAmount; // Resync the conductor and audio tracks. - if (scrollAmount != 0 || playheadAmount != 0) - moveSongToScrollPosition(); + if (scrollAmount != 0 || playheadAmount != 0) moveSongToScrollPosition(); } function handleZoom() @@ -1699,8 +1690,7 @@ class ChartEditorState extends HaxeUIState var cursorMs:Float = cursorStep * Conductor.stepCrochet * (16 / noteSnapQuant); // The direction value for the column at the cursor. var cursorColumn:Int = Math.floor(cursorX / GRID_SIZE); - if (cursorColumn < 0) - cursorColumn = 0; + if (cursorColumn < 0) cursorColumn = 0; if (cursorColumn >= (STRUMLINE_SIZE * 2 + 1 - 1)) { // Don't invert the event column. @@ -2150,8 +2140,7 @@ class ChartEditorState extends HaxeUIState var displayedNoteData:Array = []; for (noteSprite in renderedNotes.members) { - if (noteSprite == null || !noteSprite.exists || !noteSprite.visible) - continue; + if (noteSprite == null || !noteSprite.exists || !noteSprite.visible) continue; if (!noteSprite.isNoteVisible(viewAreaBottom, viewAreaTop)) { @@ -2191,8 +2180,7 @@ class ChartEditorState extends HaxeUIState var displayedEventData:Array = []; for (eventSprite in renderedEvents.members) { - if (eventSprite == null || !eventSprite.exists || !eventSprite.visible) - continue; + if (eventSprite == null || !eventSprite.exists || !eventSprite.visible) continue; if (!eventSprite.isEventVisible(viewAreaBottom, viewAreaTop)) { @@ -2231,8 +2219,7 @@ class ChartEditorState extends HaxeUIState // Make sure the note appears when scrolling up. var modifiedViewAreaTop = viewAreaTop - GRID_SIZE; - if (noteTimePixels < modifiedViewAreaTop || noteTimePixels > viewAreaBottom) - continue; + if (noteTimePixels < modifiedViewAreaTop || noteTimePixels > viewAreaBottom) continue; // Else, this note is visible and we need to render it! @@ -2297,8 +2284,7 @@ class ChartEditorState extends HaxeUIState // Make sure the event appears when scrolling up. var modifiedViewAreaTop = viewAreaTop - GRID_SIZE; - if (eventTimePixels < modifiedViewAreaTop || eventTimePixels > viewAreaBottom) - continue; + if (eventTimePixels < modifiedViewAreaTop || eventTimePixels > viewAreaBottom) continue; // Else, this event is visible and we need to render it! @@ -2460,10 +2446,11 @@ class ChartEditorState extends HaxeUIState { // Copy selected notes. // We don't need a command for this since we can't undo it. - SongDataUtils.writeItemsToClipboard({ - notes: SongDataUtils.buildNoteClipboard(currentNoteSelection), - events: SongDataUtils.buildEventClipboard(currentEventSelection), - }); + SongDataUtils.writeItemsToClipboard( + { + notes: SongDataUtils.buildNoteClipboard(currentNoteSelection), + events: SongDataUtils.buildEventClipboard(currentEventSelection), + }); } // CTRL + X = Cut @@ -2531,8 +2518,7 @@ class ChartEditorState extends HaxeUIState function handleHelpKeybinds() { // F1 = Open Help - if (FlxG.keys.justPressed.F1) - ChartEditorDialogHandler.openUserGuideDialog(this); + if (FlxG.keys.justPressed.F1) ChartEditorDialogHandler.openUserGuideDialog(this); } function handleToolboxes() @@ -2550,12 +2536,10 @@ class ChartEditorState extends HaxeUIState // Manage the Select Difficulty tree view. var difficultyToolbox = ChartEditorToolboxHandler.getToolbox(this, CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT); - if (difficultyToolbox == null) - return; + if (difficultyToolbox == null) return; var treeView:TreeView = difficultyToolbox.findComponent('difficultyToolboxTree'); - if (treeView == null) - return; + if (treeView == null) return; // Clear the tree view so we can rebuild it. treeView.clearNodes(); @@ -2567,22 +2551,24 @@ class ChartEditorState extends HaxeUIState { var variationMetadata:SongMetadata = songMetadata.get(curVariation); - var treeVariation = treeSong.addNode({ - id: 'stv_variation_$curVariation', - text: 'V: ${curVariation.toTitleCase()}', - // icon: "haxeui-core/styles/default/haxeui_tiny.png" - }); + var treeVariation = treeSong.addNode( + { + id: 'stv_variation_$curVariation', + text: 'V: ${curVariation.toTitleCase()}', + // icon: "haxeui-core/styles/default/haxeui_tiny.png" + }); treeVariation.expanded = true; var difficultyList = variationMetadata.playData.difficulties; for (difficulty in difficultyList) { - var treeDifficulty = treeVariation.addNode({ - id: 'stv_difficulty_${curVariation}_$difficulty', - text: 'D: ${difficulty.toTitleCase()}', - // icon: "haxeui-core/styles/default/haxeui_tiny.png" - }); + var treeDifficulty = treeVariation.addNode( + { + id: 'stv_difficulty_${curVariation}_$difficulty', + text: 'D: ${difficulty.toTitleCase()}', + // icon: "haxeui-core/styles/default/haxeui_tiny.png" + }); } } @@ -2595,12 +2581,10 @@ class ChartEditorState extends HaxeUIState { // Manage the Select Difficulty tree view. var charPreviewToolbox = ChartEditorToolboxHandler.getToolbox(this, CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT); - if (charPreviewToolbox == null) - return; + if (charPreviewToolbox == null) return; var charPlayer:CharacterPlayer = charPreviewToolbox.findComponent('charPlayer'); - if (charPlayer == null) - return; + if (charPlayer == null) return; currentPlayerCharacterPlayer = charPlayer; } @@ -2609,12 +2593,10 @@ class ChartEditorState extends HaxeUIState { // Manage the Select Difficulty tree view. var charPreviewToolbox = ChartEditorToolboxHandler.getToolbox(this, CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT); - if (charPreviewToolbox == null) - return; + if (charPreviewToolbox == null) return; var charPlayer:CharacterPlayer = charPreviewToolbox.findComponent('charPlayer'); - if (charPlayer == null) - return; + if (charPlayer == null) return; currentOpponentCharacterPlayer = charPlayer; } @@ -2659,13 +2641,11 @@ class ChartEditorState extends HaxeUIState { var treeView:TreeView = findComponent('difficultyToolboxTree'); - if (treeView == null) - return null; + if (treeView == null) return null; var result = treeView.findNodeByPath('stv_song/stv_variation_$selectedVariation/stv_difficulty_${selectedVariation}_$selectedDifficulty', 'id'); - if (result == null) - return null; + if (result == null) return null; return result; } @@ -2823,8 +2803,7 @@ class ChartEditorState extends HaxeUIState Conductor.update(audioInstTrack.time); handleHitsounds(oldSongPosition, Conductor.songPosition); // Resync vocals. - if (Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100) - audioVocalTrackGroup.time = audioInstTrack.time; + if (Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100) audioVocalTrackGroup.time = audioInstTrack.time; var diffStepTime = Conductor.currentStepTime - oldStepTime; // Move the playhead. @@ -2839,8 +2818,8 @@ class ChartEditorState extends HaxeUIState Conductor.update(audioInstTrack.time); handleHitsounds(oldSongPosition, Conductor.songPosition); // Resync vocals. - if (audioVocalTrackGroup != null && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100) - audioVocalTrackGroup.time = audioInstTrack.time; + if (audioVocalTrackGroup != null + && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100) audioVocalTrackGroup.time = audioInstTrack.time; // We need time in fractional steps here to allow the song to actually play. // Also account for a potentially offset playhead. @@ -2864,18 +2843,15 @@ class ChartEditorState extends HaxeUIState */ function handleHitsounds(oldSongPosition:Float, newSongPosition:Float):Void { - if (!hitsoundsEnabled) - return; + if (!hitsoundsEnabled) return; // Assume notes are sorted by time. for (noteData in currentSongChartNoteData) { - if (noteData.time < oldSongPosition) - // Note is in the past. + if (noteData.time < oldSongPosition) // Note is in the past. continue; - if (noteData.time >= newSongPosition) - // Note is in the future. + if (noteData.time >= newSongPosition) // Note is in the future. return; // Note was just hit. @@ -2892,46 +2868,36 @@ class ChartEditorState extends HaxeUIState dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! - if (event.eventCanceled) - continue; + if (event.eventCanceled) continue; // Hitsounds. switch (noteData.getStrumlineIndex()) { case 0: // Player - if (hitsoundsEnabledPlayer) - playSound(Paths.sound('funnyNoise/funnyNoise-09')); + if (hitsoundsEnabledPlayer) playSound(Paths.sound('funnyNoise/funnyNoise-09')); case 1: // Opponent - if (hitsoundsEnabledOpponent) - playSound(Paths.sound('funnyNoise/funnyNoise-010')); + if (hitsoundsEnabledOpponent) playSound(Paths.sound('funnyNoise/funnyNoise-010')); } } } function startAudioPlayback() { - if (audioInstTrack != null) - audioInstTrack.play(); - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.play(); - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.play(); + if (audioInstTrack != null) audioInstTrack.play(); + if (audioVocalTrackGroup != null) audioVocalTrackGroup.play(); + if (audioVocalTrackGroup != null) audioVocalTrackGroup.play(); } function stopAudioPlayback() { - if (audioInstTrack != null) - audioInstTrack.pause(); - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.pause(); - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.pause(); + if (audioInstTrack != null) audioInstTrack.pause(); + if (audioVocalTrackGroup != null) audioVocalTrackGroup.pause(); + if (audioVocalTrackGroup != null) audioVocalTrackGroup.pause(); } function toggleAudioPlayback() { - if (audioInstTrack == null) - return; + if (audioInstTrack == null) return; if (audioInstTrack.playing) { @@ -2949,22 +2915,14 @@ class ChartEditorState extends HaxeUIState // TODO: Add the ability to switch modes. if (true) { - if (FlxG.keys.justPressed.ONE) - placeNoteAtPlayhead(0); - if (FlxG.keys.justPressed.TWO) - placeNoteAtPlayhead(1); - if (FlxG.keys.justPressed.THREE) - placeNoteAtPlayhead(2); - if (FlxG.keys.justPressed.FOUR) - placeNoteAtPlayhead(3); - if (FlxG.keys.justPressed.FIVE) - placeNoteAtPlayhead(4); - if (FlxG.keys.justPressed.SIX) - placeNoteAtPlayhead(5); - if (FlxG.keys.justPressed.SEVEN) - placeNoteAtPlayhead(6); - if (FlxG.keys.justPressed.EIGHT) - placeNoteAtPlayhead(7); + if (FlxG.keys.justPressed.ONE) placeNoteAtPlayhead(0); + if (FlxG.keys.justPressed.TWO) placeNoteAtPlayhead(1); + if (FlxG.keys.justPressed.THREE) placeNoteAtPlayhead(2); + if (FlxG.keys.justPressed.FOUR) placeNoteAtPlayhead(3); + if (FlxG.keys.justPressed.FIVE) placeNoteAtPlayhead(4); + if (FlxG.keys.justPressed.SIX) placeNoteAtPlayhead(5); + if (FlxG.keys.justPressed.SEVEN) placeNoteAtPlayhead(6); + if (FlxG.keys.justPressed.EIGHT) placeNoteAtPlayhead(7); } } @@ -2988,11 +2946,9 @@ class ChartEditorState extends HaxeUIState value = 0; } - if (value > songLengthInPixels) - value = songLengthInPixels; + if (value > songLengthInPixels) value = songLengthInPixels; - if (value == scrollPositionInPixels) - return value; + if (value == scrollPositionInPixels) return value; this.scrollPositionInPixels = value; @@ -3027,10 +2983,8 @@ class ChartEditorState extends HaxeUIState function set_playheadPositionInPixels(value:Float):Float { // Make sure playhead doesn't go outside the song. - if (value + scrollPositionInPixels < 0) - value = -scrollPositionInPixels; - if (value + scrollPositionInPixels > songLengthInPixels) - value = songLengthInPixels - scrollPositionInPixels; + if (value + scrollPositionInPixels < 0) value = -scrollPositionInPixels; + if (value + scrollPositionInPixels > songLengthInPixels) value = songLengthInPixels - scrollPositionInPixels; this.playheadPositionInPixels = value; @@ -3084,10 +3038,8 @@ class ChartEditorState extends HaxeUIState // Prevent the time from skipping back to 0 when the song ends. audioInstTrack.onComplete = function() { - if (audioInstTrack != null) - audioInstTrack.pause(); - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.pause(); + if (audioInstTrack != null) audioInstTrack.pause(); + if (audioVocalTrackGroup != null) audioVocalTrackGroup.pause(); }; songLengthInMs = audioInstTrack.length; @@ -3189,10 +3141,8 @@ class ChartEditorState extends HaxeUIState Conductor.update(scrollPositionInMs); // Update the songPosition in the audio tracks. - if (audioInstTrack != null) - audioInstTrack.time = scrollPositionInMs + playheadPositionInMs; - if (audioVocalTrackGroup != null) - audioVocalTrackGroup.time = scrollPositionInMs + playheadPositionInMs; + if (audioInstTrack != null) audioInstTrack.time = scrollPositionInMs + playheadPositionInMs; + if (audioVocalTrackGroup != null) audioVocalTrackGroup.time = scrollPositionInMs + playheadPositionInMs; // We need to update the note sprites because we changed the scroll position. noteDisplayDirty = true; @@ -3209,8 +3159,7 @@ class ChartEditorState extends HaxeUIState command.execute(this); undoHistory.push(command); commandHistoryDirty = true; - if (purgeRedoStack) - redoHistory = []; + if (purgeRedoStack) redoHistory = []; } /** diff --git a/source/funkin/ui/debug/charting/ChartEditorThemeHandler.hx b/source/funkin/ui/debug/charting/ChartEditorThemeHandler.hx index 317f4c632..7bdf366bf 100644 --- a/source/funkin/ui/debug/charting/ChartEditorThemeHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorThemeHandler.hx @@ -13,8 +13,8 @@ import openfl.geom.Rectangle; */ enum ChartEditorTheme { - Light; - Dark; + Light; + Dark; } /** @@ -22,223 +22,223 @@ enum ChartEditorTheme */ class ChartEditorThemeHandler { - // TODO: There's probably a better system of organization for these colors. - // An enum of typedefs or something? - // ================================ - static final BACKGROUND_COLOR_LIGHT:FlxColor = 0xFF673AB7; - static final BACKGROUND_COLOR_DARK:FlxColor = 0xFF673AB7; + // TODO: There's probably a better system of organization for these colors. + // An enum of typedefs or something? + // ================================ + static final BACKGROUND_COLOR_LIGHT:FlxColor = 0xFF673AB7; + static final BACKGROUND_COLOR_DARK:FlxColor = 0xFF673AB7; - // Color 1 of the grid pattern. Alternates with Color 2. - static final GRID_COLOR_1_LIGHT:FlxColor = 0xFFE7E6E6; - static final GRID_COLOR_1_DARK:FlxColor = 0xFF181919; + // Color 1 of the grid pattern. Alternates with Color 2. + static final GRID_COLOR_1_LIGHT:FlxColor = 0xFFE7E6E6; + static final GRID_COLOR_1_DARK:FlxColor = 0xFF181919; - // Color 2 of the grid pattern. Alternates with Color 1. - static final GRID_COLOR_2_LIGHT:FlxColor = 0xFFF8F8F8; - static final GRID_COLOR_2_DARK:FlxColor = 0xFF202020; + // Color 2 of the grid pattern. Alternates with Color 1. + static final GRID_COLOR_2_LIGHT:FlxColor = 0xFFF8F8F8; + static final GRID_COLOR_2_DARK:FlxColor = 0xFF202020; - // Color 3 of the grid pattern. Borders the other colors. - static final GRID_COLOR_3_LIGHT:FlxColor = 0xFFD9D5D5; - static final GRID_COLOR_3_DARK:FlxColor = 0xFF262A2A; + // Color 3 of the grid pattern. Borders the other colors. + static final GRID_COLOR_3_LIGHT:FlxColor = 0xFFD9D5D5; + static final GRID_COLOR_3_DARK:FlxColor = 0xFF262A2A; - // Vertical divider between characters. - static final GRID_STRUMLINE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111; - static final GRID_STRUMLINE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4; - // static final GRID_STRUMLINE_DIVIDER_WIDTH:Float = 2; - static final GRID_STRUMLINE_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH; + // Vertical divider between characters. + static final GRID_STRUMLINE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111; + static final GRID_STRUMLINE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4; + // static final GRID_STRUMLINE_DIVIDER_WIDTH:Float = 2; + static final GRID_STRUMLINE_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH; - // Horizontal divider between measures. - static final GRID_MEASURE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111; - static final GRID_MEASURE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4; - // static final GRID_MEASURE_DIVIDER_WIDTH:Float = 2; - static final GRID_MEASURE_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH; + // Horizontal divider between measures. + static final GRID_MEASURE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111; + static final GRID_MEASURE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4; + // static final GRID_MEASURE_DIVIDER_WIDTH:Float = 2; + static final GRID_MEASURE_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH; - // Border on the square highlighting selected notes. - static final SELECTION_SQUARE_BORDER_COLOR_LIGHT:FlxColor = 0xFF339933; - static final SELECTION_SQUARE_BORDER_COLOR_DARK:FlxColor = 0xFF339933; - static final SELECTION_SQUARE_BORDER_WIDTH:Int = 1; + // Border on the square highlighting selected notes. + static final SELECTION_SQUARE_BORDER_COLOR_LIGHT:FlxColor = 0xFF339933; + static final SELECTION_SQUARE_BORDER_COLOR_DARK:FlxColor = 0xFF339933; + static final SELECTION_SQUARE_BORDER_WIDTH:Int = 1; - // Fill on the square highlighting selected notes. - // Make sure this is transparent so you can see the notes underneath. - static final SELECTION_SQUARE_FILL_COLOR_LIGHT:FlxColor = 0x4033FF33; - static final SELECTION_SQUARE_FILL_COLOR_DARK:FlxColor = 0x4033FF33; + // Fill on the square highlighting selected notes. + // Make sure this is transparent so you can see the notes underneath. + static final SELECTION_SQUARE_FILL_COLOR_LIGHT:FlxColor = 0x4033FF33; + static final SELECTION_SQUARE_FILL_COLOR_DARK:FlxColor = 0x4033FF33; - static final PLAYHEAD_BLOCK_BORDER_WIDTH:Int = 2; - static final PLAYHEAD_BLOCK_BORDER_COLOR:FlxColor = 0xFF9D0011; - static final PLAYHEAD_BLOCK_FILL_COLOR:FlxColor = 0xFFBD0231; + static final PLAYHEAD_BLOCK_BORDER_WIDTH:Int = 2; + static final PLAYHEAD_BLOCK_BORDER_COLOR:FlxColor = 0xFF9D0011; + static final PLAYHEAD_BLOCK_FILL_COLOR:FlxColor = 0xFFBD0231; - public static function updateTheme(state:ChartEditorState):Void - { - updateBackground(state); - updateGridBitmap(state); - updateSelectionSquare(state); - } + public static function updateTheme(state:ChartEditorState):Void + { + updateBackground(state); + updateGridBitmap(state); + updateSelectionSquare(state); + } - static function updateBackground(state:ChartEditorState):Void - { - state.menuBG.color = switch (state.currentTheme) - { - case ChartEditorTheme.Light: BACKGROUND_COLOR_LIGHT; - case ChartEditorTheme.Dark: BACKGROUND_COLOR_DARK; - default: BACKGROUND_COLOR_LIGHT; - } - } + static function updateBackground(state:ChartEditorState):Void + { + state.menuBG.color = switch (state.currentTheme) + { + case ChartEditorTheme.Light: BACKGROUND_COLOR_LIGHT; + case ChartEditorTheme.Dark: BACKGROUND_COLOR_DARK; + default: BACKGROUND_COLOR_LIGHT; + } + } - /** - * Builds the checkerboard background image of the chart editor, and adds dividing lines to it. - * @param dark Whether to draw the grid in a dark color instead of a light one. - */ - static function updateGridBitmap(state:ChartEditorState):Void - { - var gridColor1:FlxColor = switch (state.currentTheme) - { - case Light: GRID_COLOR_1_LIGHT; - case Dark: GRID_COLOR_1_DARK; - default: GRID_COLOR_1_LIGHT; - }; + /** + * Builds the checkerboard background image of the chart editor, and adds dividing lines to it. + * @param dark Whether to draw the grid in a dark color instead of a light one. + */ + static function updateGridBitmap(state:ChartEditorState):Void + { + var gridColor1:FlxColor = switch (state.currentTheme) + { + case Light: GRID_COLOR_1_LIGHT; + case Dark: GRID_COLOR_1_DARK; + default: GRID_COLOR_1_LIGHT; + }; - var gridColor2:FlxColor = switch (state.currentTheme) - { - case Light: GRID_COLOR_2_LIGHT; - case Dark: GRID_COLOR_2_DARK; - default: GRID_COLOR_2_LIGHT; - }; + var gridColor2:FlxColor = switch (state.currentTheme) + { + case Light: GRID_COLOR_2_LIGHT; + case Dark: GRID_COLOR_2_DARK; + default: GRID_COLOR_2_LIGHT; + }; - // Draw the base grid. + // Draw the base grid. - // 2 * (Strumline Size) + 1 grid squares wide, by (4 * quarter notes per measure) grid squares tall. - // This gets reused to fill the screen. - var gridWidth:Int = Std.int(ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE * 2 + 1)); - var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * (Conductor.stepsPerMeasure)); - state.gridBitmap = FlxGridOverlay.createGrid(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, gridWidth, gridHeight, true, gridColor1, - gridColor2); + // 2 * (Strumline Size) + 1 grid squares wide, by (4 * quarter notes per measure) grid squares tall. + // This gets reused to fill the screen. + var gridWidth:Int = Std.int(ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE * 2 + 1)); + var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * (Conductor.stepsPerMeasure)); + state.gridBitmap = FlxGridOverlay.createGrid(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, gridWidth, gridHeight, true, gridColor1, gridColor2); - // Selection borders - var selectionBorderColor:FlxColor = switch (state.currentTheme) - { - case Light: GRID_COLOR_3_LIGHT; - case Dark: GRID_COLOR_3_DARK; - default: GRID_COLOR_3_LIGHT; - }; + // Selection borders + var selectionBorderColor:FlxColor = switch (state.currentTheme) + { + case Light: GRID_COLOR_3_LIGHT; + case Dark: GRID_COLOR_3_DARK; + default: GRID_COLOR_3_LIGHT; + }; - // Selection border at top. - state.gridBitmap.fillRect(new Rectangle(0, -(ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), state.gridBitmap.width, - ChartEditorState.GRID_SELECTION_BORDER_WIDTH), - selectionBorderColor); + // Selection border at top. + state.gridBitmap.fillRect(new Rectangle(0, -(ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), state.gridBitmap.width, + ChartEditorState.GRID_SELECTION_BORDER_WIDTH), + selectionBorderColor); - // Selection borders in the middle. - for (i in 1...(Conductor.stepsPerMeasure)) - { - state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), - state.gridBitmap.width, ChartEditorState.GRID_SELECTION_BORDER_WIDTH), - selectionBorderColor); - } + // Selection borders in the middle. + for (i in 1...(Conductor.stepsPerMeasure)) + { + state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), + state.gridBitmap.width, ChartEditorState.GRID_SELECTION_BORDER_WIDTH), + selectionBorderColor); + } - // Selection border at bottom. - state.gridBitmap.fillRect(new Rectangle(0, state.gridBitmap.height - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), state.gridBitmap.width, - ChartEditorState.GRID_SELECTION_BORDER_WIDTH), - selectionBorderColor); + // Selection border at bottom. + state.gridBitmap.fillRect(new Rectangle(0, state.gridBitmap.height - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), state.gridBitmap.width, + ChartEditorState.GRID_SELECTION_BORDER_WIDTH), + selectionBorderColor); - // Selection border at left. - state.gridBitmap.fillRect(new Rectangle(-(ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, ChartEditorState.GRID_SELECTION_BORDER_WIDTH, - state.gridBitmap.height), - selectionBorderColor); + // Selection border at left. + state.gridBitmap.fillRect(new Rectangle(-(ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, ChartEditorState.GRID_SELECTION_BORDER_WIDTH, + state.gridBitmap.height), + selectionBorderColor); - // Selection borders across the middle. - for (i in 1...(ChartEditorState.STRUMLINE_SIZE * 2 + 1)) - { - state.gridBitmap.fillRect(new Rectangle((ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, - ChartEditorState.GRID_SELECTION_BORDER_WIDTH, state.gridBitmap.height), - selectionBorderColor); - } + // Selection borders across the middle. + for (i in 1...(ChartEditorState.STRUMLINE_SIZE * 2 + 1)) + { + state.gridBitmap.fillRect(new Rectangle((ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, + ChartEditorState.GRID_SELECTION_BORDER_WIDTH, state.gridBitmap.height), + selectionBorderColor); + } - // Selection border at right. - state.gridBitmap.fillRect(new Rectangle(state.gridBitmap.width - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, - ChartEditorState.GRID_SELECTION_BORDER_WIDTH, state.gridBitmap.height), - selectionBorderColor); + // Selection border at right. + state.gridBitmap.fillRect(new Rectangle(state.gridBitmap.width - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, + ChartEditorState.GRID_SELECTION_BORDER_WIDTH, state.gridBitmap.height), + selectionBorderColor); - // Draw dividers between the measures. + // Draw dividers between the measures. - var gridMeasureDividerColor:FlxColor = switch (state.currentTheme) - { - case Light: GRID_MEASURE_DIVIDER_COLOR_LIGHT; - case Dark: GRID_MEASURE_DIVIDER_COLOR_DARK; - default: GRID_MEASURE_DIVIDER_COLOR_LIGHT; - }; + var gridMeasureDividerColor:FlxColor = switch (state.currentTheme) + { + case Light: GRID_MEASURE_DIVIDER_COLOR_LIGHT; + case Dark: GRID_MEASURE_DIVIDER_COLOR_DARK; + default: GRID_MEASURE_DIVIDER_COLOR_LIGHT; + }; - // Divider at top - state.gridBitmap.fillRect(new Rectangle(0, 0, state.gridBitmap.width, GRID_MEASURE_DIVIDER_WIDTH / 2), gridMeasureDividerColor); - // Divider at bottom - var dividerLineBY = state.gridBitmap.height - (GRID_MEASURE_DIVIDER_WIDTH / 2); - state.gridBitmap.fillRect(new Rectangle(0, dividerLineBY, state.gridBitmap.width, GRID_MEASURE_DIVIDER_WIDTH / 2), gridMeasureDividerColor); + // Divider at top + state.gridBitmap.fillRect(new Rectangle(0, 0, state.gridBitmap.width, GRID_MEASURE_DIVIDER_WIDTH / 2), gridMeasureDividerColor); + // Divider at bottom + var dividerLineBY = state.gridBitmap.height - (GRID_MEASURE_DIVIDER_WIDTH / 2); + state.gridBitmap.fillRect(new Rectangle(0, dividerLineBY, state.gridBitmap.width, GRID_MEASURE_DIVIDER_WIDTH / 2), gridMeasureDividerColor); - // Draw dividers between the strumlines. + // Draw dividers between the strumlines. - var gridStrumlineDividerColor:FlxColor = switch (state.currentTheme) - { - case Light: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT; - case Dark: GRID_STRUMLINE_DIVIDER_COLOR_DARK; - default: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT; - }; + var gridStrumlineDividerColor:FlxColor = switch (state.currentTheme) + { + case Light: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT; + case Dark: GRID_STRUMLINE_DIVIDER_COLOR_DARK; + default: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT; + }; - // Divider at 1 * (Strumline Size) - var dividerLineAX = ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE) - (GRID_STRUMLINE_DIVIDER_WIDTH / 2); - state.gridBitmap.fillRect(new Rectangle(dividerLineAX, 0, GRID_STRUMLINE_DIVIDER_WIDTH, state.gridBitmap.height), gridStrumlineDividerColor); - // Divider at 2 * (Strumline Size) - var dividerLineBX = ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE * 2) - (GRID_STRUMLINE_DIVIDER_WIDTH / 2); - state.gridBitmap.fillRect(new Rectangle(dividerLineBX, 0, GRID_STRUMLINE_DIVIDER_WIDTH, state.gridBitmap.height), gridStrumlineDividerColor); + // Divider at 1 * (Strumline Size) + var dividerLineAX = ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE) - (GRID_STRUMLINE_DIVIDER_WIDTH / 2); + state.gridBitmap.fillRect(new Rectangle(dividerLineAX, 0, GRID_STRUMLINE_DIVIDER_WIDTH, state.gridBitmap.height), gridStrumlineDividerColor); + // Divider at 2 * (Strumline Size) + var dividerLineBX = ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE * 2) - (GRID_STRUMLINE_DIVIDER_WIDTH / 2); + state.gridBitmap.fillRect(new Rectangle(dividerLineBX, 0, GRID_STRUMLINE_DIVIDER_WIDTH, state.gridBitmap.height), gridStrumlineDividerColor); - if (state.gridTiledSprite != null) { - state.gridTiledSprite.loadGraphic(state.gridBitmap); - } - // Else, gridTiledSprite will be built later. - } + if (state.gridTiledSprite != null) + { + state.gridTiledSprite.loadGraphic(state.gridBitmap); + } + // Else, gridTiledSprite will be built later. + } - static function updateSelectionSquare(state:ChartEditorState):Void - { - var selectionSquareBorderColor:FlxColor = switch (state.currentTheme) - { - case Light: SELECTION_SQUARE_BORDER_COLOR_LIGHT; - case Dark: SELECTION_SQUARE_BORDER_COLOR_DARK; - default: SELECTION_SQUARE_BORDER_COLOR_LIGHT; - }; + static function updateSelectionSquare(state:ChartEditorState):Void + { + var selectionSquareBorderColor:FlxColor = switch (state.currentTheme) + { + case Light: SELECTION_SQUARE_BORDER_COLOR_LIGHT; + case Dark: SELECTION_SQUARE_BORDER_COLOR_DARK; + default: SELECTION_SQUARE_BORDER_COLOR_LIGHT; + }; - var selectionSquareFillColor:FlxColor = switch (state.currentTheme) - { - case Light: SELECTION_SQUARE_FILL_COLOR_LIGHT; - case Dark: SELECTION_SQUARE_FILL_COLOR_DARK; - default: SELECTION_SQUARE_FILL_COLOR_LIGHT; - }; + var selectionSquareFillColor:FlxColor = switch (state.currentTheme) + { + case Light: SELECTION_SQUARE_FILL_COLOR_LIGHT; + case Dark: SELECTION_SQUARE_FILL_COLOR_DARK; + default: SELECTION_SQUARE_FILL_COLOR_LIGHT; + }; - state.selectionSquareBitmap = new BitmapData(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, true); + state.selectionSquareBitmap = new BitmapData(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, true); - state.selectionSquareBitmap.fillRect(new Rectangle(0, 0, ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE), selectionSquareBorderColor); - state.selectionSquareBitmap.fillRect(new Rectangle(SELECTION_SQUARE_BORDER_WIDTH, SELECTION_SQUARE_BORDER_WIDTH, - ChartEditorState.GRID_SIZE - (SELECTION_SQUARE_BORDER_WIDTH * 2), ChartEditorState.GRID_SIZE - (SELECTION_SQUARE_BORDER_WIDTH * 2)), - selectionSquareFillColor); + state.selectionSquareBitmap.fillRect(new Rectangle(0, 0, ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE), selectionSquareBorderColor); + state.selectionSquareBitmap.fillRect(new Rectangle(SELECTION_SQUARE_BORDER_WIDTH, SELECTION_SQUARE_BORDER_WIDTH, + ChartEditorState.GRID_SIZE - (SELECTION_SQUARE_BORDER_WIDTH * 2), ChartEditorState.GRID_SIZE - (SELECTION_SQUARE_BORDER_WIDTH * 2)), + selectionSquareFillColor); - state.selectionBoxSprite = new FlxSliceSprite(state.selectionSquareBitmap, - new FlxRect(SELECTION_SQUARE_BORDER_WIDTH - + 4, SELECTION_SQUARE_BORDER_WIDTH - + 4, - ChartEditorState.GRID_SIZE - - (2 * SELECTION_SQUARE_BORDER_WIDTH + 8), ChartEditorState.GRID_SIZE - - (2 * SELECTION_SQUARE_BORDER_WIDTH + 8)), - 32, 32); - } + state.selectionBoxSprite = new FlxSliceSprite(state.selectionSquareBitmap, + new FlxRect(SELECTION_SQUARE_BORDER_WIDTH + + 4, SELECTION_SQUARE_BORDER_WIDTH + + 4, ChartEditorState.GRID_SIZE + - (2 * SELECTION_SQUARE_BORDER_WIDTH + 8), + ChartEditorState.GRID_SIZE + - (2 * SELECTION_SQUARE_BORDER_WIDTH + 8)), + 32, 32); + } - public static function buildPlayheadBlock():FlxSprite - { - var playheadBlock:FlxSprite = new FlxSprite(); + public static function buildPlayheadBlock():FlxSprite + { + var playheadBlock:FlxSprite = new FlxSprite(); - var playheadBlockBitmap:BitmapData = new BitmapData(ChartEditorState.PLAYHEAD_SCROLL_AREA_WIDTH, ChartEditorState.PLAYHEAD_HEIGHT * 2, true); + var playheadBlockBitmap:BitmapData = new BitmapData(ChartEditorState.PLAYHEAD_SCROLL_AREA_WIDTH, ChartEditorState.PLAYHEAD_HEIGHT * 2, true); - playheadBlockBitmap.fillRect(new Rectangle(0, 0, ChartEditorState.PLAYHEAD_SCROLL_AREA_WIDTH, ChartEditorState.PLAYHEAD_HEIGHT * 2), - PLAYHEAD_BLOCK_BORDER_COLOR); - playheadBlockBitmap.fillRect(new Rectangle(PLAYHEAD_BLOCK_BORDER_WIDTH, PLAYHEAD_BLOCK_BORDER_WIDTH, - ChartEditorState.PLAYHEAD_SCROLL_AREA_WIDTH - (2 * PLAYHEAD_BLOCK_BORDER_WIDTH), - ChartEditorState.PLAYHEAD_HEIGHT * 2 - (2 * PLAYHEAD_BLOCK_BORDER_WIDTH)), - PLAYHEAD_BLOCK_FILL_COLOR); + playheadBlockBitmap.fillRect(new Rectangle(0, 0, ChartEditorState.PLAYHEAD_SCROLL_AREA_WIDTH, ChartEditorState.PLAYHEAD_HEIGHT * 2), + PLAYHEAD_BLOCK_BORDER_COLOR); + playheadBlockBitmap.fillRect(new Rectangle(PLAYHEAD_BLOCK_BORDER_WIDTH, PLAYHEAD_BLOCK_BORDER_WIDTH, + ChartEditorState.PLAYHEAD_SCROLL_AREA_WIDTH - (2 * PLAYHEAD_BLOCK_BORDER_WIDTH), + ChartEditorState.PLAYHEAD_HEIGHT * 2 - (2 * PLAYHEAD_BLOCK_BORDER_WIDTH)), + PLAYHEAD_BLOCK_FILL_COLOR); - return playheadBlock.loadGraphic(playheadBlockBitmap); - } + return playheadBlock.loadGraphic(playheadBlockBitmap); + } } diff --git a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx index 88bb9eca4..8e21b3aeb 100644 --- a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx @@ -35,8 +35,7 @@ class ChartEditorToolboxHandler { public static function setToolboxState(state:ChartEditorState, id:String, shown:Bool):Void { - if (shown) - showToolbox(state, id); + if (shown) showToolbox(state, id); else hideToolbox(state, id); } @@ -45,8 +44,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = state.activeToolboxes.get(id); - if (toolbox == null) - toolbox = initToolbox(state, id); + if (toolbox == null) toolbox = initToolbox(state, id); if (toolbox != null) { @@ -62,8 +60,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = state.activeToolboxes.get(id); - if (toolbox == null) - toolbox = initToolbox(state, id); + if (toolbox == null) toolbox = initToolbox(state, id); if (toolbox != null) { @@ -107,8 +104,7 @@ class ChartEditorToolboxHandler } // This happens if the layout you try to load has a syntax error. - if (toolbox == null) - return null; + if (toolbox == null) return null; // Make sure we can reuse the toolbox later. toolbox.destroyOnClose = false; @@ -122,8 +118,7 @@ class ChartEditorToolboxHandler var toolbox:Dialog = state.activeToolboxes.get(id); // Initialize the toolbox without showing it. - if (toolbox == null) - toolbox = initToolbox(state, id); + if (toolbox == null) toolbox = initToolbox(state, id); return toolbox; } @@ -132,8 +127,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 50; @@ -146,8 +140,7 @@ class ChartEditorToolboxHandler var toolsGroup:Group = toolbox.findComponent("toolboxToolsGroup", Group); - if (toolsGroup == null) - return null; + if (toolsGroup == null) return null; toolsGroup.onChange = (event:UIEvent) -> { @@ -169,8 +162,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 75; @@ -217,8 +209,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 100; @@ -333,8 +324,7 @@ class ChartEditorToolboxHandler { trace('ChartEditorToolboxHandler.buildEventDataFormFromSchema() - ${event.target.id} = ${event.target.value}'); - if (event.target.value == null) - state.selectedEventData.remove(event.target.id); + if (event.target.value == null) state.selectedEventData.remove(event.target.id); else state.selectedEventData.set(event.target.id, event.target.value); } @@ -345,8 +335,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 125; @@ -406,8 +395,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 150; @@ -464,16 +452,14 @@ class ChartEditorToolboxHandler var inputNoteSkin:DropDown = toolbox.findComponent('inputNoteSkin', DropDown); inputNoteSkin.onChange = (event:UIEvent) -> { - if (event.data.id == null) - return; + if (event.data.id == null) return; state.currentSongMetadata.playData.noteSkin = event.data.id; }; var inputBPM:NumberStepper = toolbox.findComponent('inputBPM', NumberStepper); inputBPM.onChange = (event:UIEvent) -> { - if (event.value == null || event.value <= 0) - return; + if (event.value == null || event.value <= 0) return; var timeChanges = state.currentSongMetadata.timeChanges; if (timeChanges == null || timeChanges.length == 0) @@ -513,8 +499,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 175; @@ -532,8 +517,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 200; @@ -558,8 +542,7 @@ class ChartEditorToolboxHandler { var toolbox:Dialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT); - if (toolbox == null) - return null; + if (toolbox == null) return null; // Starting position. toolbox.x = 200; diff --git a/source/funkin/ui/haxeui/HaxeUIState.hx b/source/funkin/ui/haxeui/HaxeUIState.hx index f7da230bb..e23768131 100644 --- a/source/funkin/ui/haxeui/HaxeUIState.hx +++ b/source/funkin/ui/haxeui/HaxeUIState.hx @@ -13,182 +13,177 @@ import lime.app.Application; class HaxeUIState extends MusicBeatState { - public var component:Component; + public var component:Component; - var _componentKey:String; + var _componentKey:String; - public function new(key:String) - { - super(); - _componentKey = key; - } + public function new(key:String) + { + super(); + _componentKey = key; + } - override function create() - { - super.create(); + override function create() + { + super.create(); - if (component == null) - component = buildComponent(_componentKey); - if (component != null) - add(component); - } + if (component == null) component = buildComponent(_componentKey); + if (component != null) add(component); + } - public function buildComponent(assetPath:String) - { - try - { - return RuntimeComponentBuilder.fromAsset(assetPath); - } - catch (e) - { - Application.current.window.alert('Error building component "$assetPath": $e', 'HaxeUI Parsing Error'); - // trace('[ERROR] Failed to build component from asset: ' + assetPath); - // trace(e); + public function buildComponent(assetPath:String) + { + try + { + return RuntimeComponentBuilder.fromAsset(assetPath); + } + catch (e) + { + Application.current.window.alert('Error building component "$assetPath": $e', 'HaxeUI Parsing Error'); + // trace('[ERROR] Failed to build component from asset: ' + assetPath); + // trace(e); - return null; - } - } + return null; + } + } - /** - * The currently active context menu. - */ - public var contextMenu:Component; + /** + * The currently active context menu. + */ + public var contextMenu:Component; - /** - * This function is called when right clicking on a component, to display a context menu. - */ - function showContextMenu(assetPath:String, xPos:Float, yPos:Float):Component - { - if (contextMenu != null) - contextMenu.destroy(); + /** + * This function is called when right clicking on a component, to display a context menu. + */ + function showContextMenu(assetPath:String, xPos:Float, yPos:Float):Component + { + if (contextMenu != null) contextMenu.destroy(); - contextMenu = buildComponent(assetPath); + contextMenu = buildComponent(assetPath); - if (contextMenu != null) - { - // Move the context menu to the mouse position. - contextMenu.left = xPos; - contextMenu.top = yPos; - Screen.instance.addComponent(contextMenu); - } + if (contextMenu != null) + { + // Move the context menu to the mouse position. + contextMenu.left = xPos; + contextMenu.top = yPos; + Screen.instance.addComponent(contextMenu); + } - return contextMenu; - } + return contextMenu; + } - /** - * Register a context menu to display when right clicking. - * @param component Only display the menu when clicking this component. If null, display the menu when right clicking anywhere. - * @param assetPath The asset path to the context menu XML. - */ - public function registerContextMenu(target:Null, assetPath:String):Void - { - if (target == null) - { - Screen.instance.registerEvent(MouseEvent.RIGHT_CLICK, function(e:MouseEvent) - { - showContextMenu(assetPath, e.screenX, e.screenY); - }); - } - else - { - target.registerEvent(MouseEvent.RIGHT_CLICK, function(e:MouseEvent) - { - showContextMenu(assetPath, e.screenX, e.screenY); - }); - } - } + /** + * Register a context menu to display when right clicking. + * @param component Only display the menu when clicking this component. If null, display the menu when right clicking anywhere. + * @param assetPath The asset path to the context menu XML. + */ + public function registerContextMenu(target:Null, assetPath:String):Void + { + if (target == null) + { + Screen.instance.registerEvent(MouseEvent.RIGHT_CLICK, function(e:MouseEvent) + { + showContextMenu(assetPath, e.screenX, e.screenY); + }); + } + else + { + target.registerEvent(MouseEvent.RIGHT_CLICK, function(e:MouseEvent) + { + showContextMenu(assetPath, e.screenX, e.screenY); + }); + } + } - /** - * Add an onClick listener to a HaxeUI menu bar item. - */ - function addUIClickListener(key:String, callback:MouseEvent->Void) - { - var target:Component = findComponent(key); - if (target == null) - { - // Gracefully handle the case where the item can't be located. - trace('WARN: Could not locate menu item: $key'); - } - else - { - target.onClick = callback; - } - } + /** + * Add an onClick listener to a HaxeUI menu bar item. + */ + function addUIClickListener(key:String, callback:MouseEvent->Void) + { + var target:Component = findComponent(key); + if (target == null) + { + // Gracefully handle the case where the item can't be located. + trace('WARN: Could not locate menu item: $key'); + } + else + { + target.onClick = callback; + } + } - /** - * Add an onChange listener to a HaxeUI input component such as a slider or text field. - */ - function addUIChangeListener(key:String, callback:UIEvent->Void) - { - var target:Component = findComponent(key); - if (target == null) - { - // Gracefully handle the case where the item can't be located. - trace('WARN: Could not locate menu item: $key'); - } - else - { - target.onChange = callback; - } - } + /** + * Add an onChange listener to a HaxeUI input component such as a slider or text field. + */ + function addUIChangeListener(key:String, callback:UIEvent->Void) + { + var target:Component = findComponent(key); + if (target == null) + { + // Gracefully handle the case where the item can't be located. + trace('WARN: Could not locate menu item: $key'); + } + else + { + target.onChange = callback; + } + } - /** - * Set the value of a HaxeUI component. - * Usually modifies the text of a label or value of a text field. - */ - function setUIValue(key:String, value:T):T - { - var target:Component = findComponent(key); - if (target == null) - { - // Gracefully handle the case where the item can't be located. - trace('WARN: Could not locate menu item: $key'); - return value; - } - else - { - return target.value = value; - } - } + /** + * Set the value of a HaxeUI component. + * Usually modifies the text of a label or value of a text field. + */ + function setUIValue(key:String, value:T):T + { + var target:Component = findComponent(key); + if (target == null) + { + // Gracefully handle the case where the item can't be located. + trace('WARN: Could not locate menu item: $key'); + return value; + } + else + { + return target.value = value; + } + } - /** - * Set the value of a HaxeUI checkbox, - * since that's on 'selected' instead of 'value'. - */ - public function setUICheckboxSelected(key:String, value:Bool):Bool - { - var targetA:CheckBox = findComponent(key, CheckBox); + /** + * Set the value of a HaxeUI checkbox, + * since that's on 'selected' instead of 'value'. + */ + public function setUICheckboxSelected(key:String, value:Bool):Bool + { + var targetA:CheckBox = findComponent(key, CheckBox); - if (targetA != null) - { - return targetA.selected = value; - } + if (targetA != null) + { + return targetA.selected = value; + } - var targetB:MenuCheckBox = findComponent(key, MenuCheckBox); - if (targetB != null) - { - return targetB.selected = value; - } + var targetB:MenuCheckBox = findComponent(key, MenuCheckBox); + if (targetB != null) + { + return targetB.selected = value; + } - // Gracefully handle the case where the item can't be located. - trace('WARN: Could not locate check box: $key'); - return value; - } + // Gracefully handle the case where the item can't be located. + trace('WARN: Could not locate check box: $key'); + return value; + } - public function findComponent(criteria:String = null, type:Class = null, recursive:Null = null, searchType:String = "id"):Null - { - if (component == null) - return null; + public function findComponent(criteria:String = null, type:Class = null, recursive:Null = null, searchType:String = "id"):Null + { + if (component == null) return null; - return component.findComponent(criteria, type, recursive, searchType); - } + return component.findComponent(criteria, type, recursive, searchType); + } - override function destroy() - { - if (component != null) - remove(component); - component = null; + override function destroy() + { + if (component != null) remove(component); + component = null; - super.destroy(); - } + super.destroy(); + } } diff --git a/source/funkin/ui/haxeui/HaxeUISubState.hx b/source/funkin/ui/haxeui/HaxeUISubState.hx index b512c8451..15e7f60f8 100644 --- a/source/funkin/ui/haxeui/HaxeUISubState.hx +++ b/source/funkin/ui/haxeui/HaxeUISubState.hx @@ -5,89 +5,87 @@ import haxe.ui.core.Component; class HaxeUISubState extends MusicBeatSubstate { - // The component representing the main UI. - public var component:Component; + // The component representing the main UI. + public var component:Component; - var _componentKey:String; + var _componentKey:String; - public function new(key:String) - { - super(); - _componentKey = key; - } + public function new(key:String) + { + super(); + _componentKey = key; + } - override function create() - { - super.create(); + override function create() + { + super.create(); - refreshComponent(); - } + refreshComponent(); + } - /** - * Builds a component from a given XML file. - * Call this in your code to load additional components at runtime. - */ - public function buildComponent(assetPath:String) - { - trace('Building component $assetPath'); - return RuntimeComponentBuilder.fromAsset(assetPath); - } + /** + * Builds a component from a given XML file. + * Call this in your code to load additional components at runtime. + */ + public function buildComponent(assetPath:String) + { + trace('Building component $assetPath'); + return RuntimeComponentBuilder.fromAsset(assetPath); + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - // Force quit. - if (FlxG.keys.justPressed.F4) - FlxG.switchState(new MainMenuState()); + // Force quit. + if (FlxG.keys.justPressed.F4) FlxG.switchState(new MainMenuState()); - // Refresh the component. - if (FlxG.keys.justPressed.F5) - { - refreshComponent(); - } - } + // Refresh the component. + if (FlxG.keys.justPressed.F5) + { + refreshComponent(); + } + } - function refreshComponent() - { - /* - if (component != null) - { - remove(component); - component = null; - } + function refreshComponent() + { + /* + if (component != null) + { + remove(component); + component = null; + } - if (component != null) - { - trace('Success!'); - add(component); - } - else - { - trace('Failed to build component $_componentKey'); - } - */ + if (component != null) + { + trace('Success!'); + add(component); + } + else + { + trace('Failed to build component $_componentKey'); + } + */ - if (component == null) - { - component = buildComponent(_componentKey); - add(component); - trace(component); - } - else - { - var component2 = buildComponent(_componentKey); - component2.x += 100; - add(component2); - trace(component2); - remove(component); - } - } + if (component == null) + { + component = buildComponent(_componentKey); + add(component); + trace(component); + } + else + { + var component2 = buildComponent(_componentKey); + component2.x += 100; + add(component2); + trace(component2); + remove(component); + } + } - override function destroy() - { - if (component != null) - remove(component); - component = null; - } + override function destroy() + { + if (component != null) remove(component); + component = null; + } } diff --git a/source/funkin/ui/haxeui/components/CharacterPlayer.hx b/source/funkin/ui/haxeui/components/CharacterPlayer.hx index 37018b760..c45aac35e 100644 --- a/source/funkin/ui/haxeui/components/CharacterPlayer.hx +++ b/source/funkin/ui/haxeui/components/CharacterPlayer.hx @@ -21,256 +21,251 @@ import openfl.Assets; private typedef AnimationInfo = { - var name:String; - var prefix:String; - var frameRate:Null; // default 30 - var looped:Null; // default true - var flipX:Null; // default false - var flipY:Null; // default false + var name:String; + var prefix:String; + var frameRate:Null; // default 30 + var looped:Null; // default true + var flipX:Null; // default false + var flipY:Null; // default false } @:composite(Layout) class CharacterPlayer extends Box { - private var character:BaseCharacter; + var character:BaseCharacter; - public function new(?defaultToBf:Bool = true) - { - super(); - this._overrideSkipTransformChildren = false; + public function new(?defaultToBf:Bool = true) + { + super(); + this._overrideSkipTransformChildren = false; - if (defaultToBf) - { - loadCharacter('bf'); - } - } + if (defaultToBf) + { + loadCharacter('bf'); + } + } - private var _charId:String; + var _charId:String; - public var charId(get, set):String; + public var charId(get, set):String; - private function get_charId():String - { - return _charId; - } + function get_charId():String + { + return _charId; + } - private function set_charId(value:String):String - { - _charId = value; - loadCharacter(_charId); - return value; - } + function set_charId(value:String):String + { + _charId = value; + loadCharacter(_charId); + return value; + } - private var _redispatchLoaded:Bool = false; // possible haxeui bug: if listener is added after event is dispatched, event is "lost"... needs thinking about, is it smart to "collect and redispatch"? Not sure - private var _redispatchStart:Bool = false; // possible haxeui bug: if listener is added after event is dispatched, event is "lost"... needs thinking about, is it smart to "collect and redispatch"? Not sure + var _redispatchLoaded:Bool = false; // possible haxeui bug: if listener is added after event is dispatched, event is "lost"... needs thinking about, is it smart to "collect and redispatch"? Not sure + var _redispatchStart:Bool = false; // possible haxeui bug: if listener is added after event is dispatched, event is "lost"... needs thinking about, is it smart to "collect and redispatch"? Not sure - public override function onReady() - { - super.onReady(); + public override function onReady() + { + super.onReady(); - invalidateComponentLayout(); + invalidateComponentLayout(); - if (_redispatchLoaded) - { - _redispatchLoaded = false; - dispatch(new AnimationEvent(AnimationEvent.LOADED)); - } + if (_redispatchLoaded) + { + _redispatchLoaded = false; + dispatch(new AnimationEvent(AnimationEvent.LOADED)); + } - if (_redispatchStart) - { - _redispatchStart = false; - dispatch(new AnimationEvent(AnimationEvent.START)); - } + if (_redispatchStart) + { + _redispatchStart = false; + dispatch(new AnimationEvent(AnimationEvent.START)); + } - parentComponent._overrideSkipTransformChildren = false; - } + parentComponent._overrideSkipTransformChildren = false; + } - public function loadCharacter(id:String) - { - if (id == null) - { - return; - } + public function loadCharacter(id:String) + { + if (id == null) + { + return; + } - if (character != null) - { - remove(character); - character.destroy(); - character = null; - } + if (character != null) + { + remove(character); + character.destroy(); + character = null; + } - var newCharacter:BaseCharacter = CharacterDataParser.fetchCharacter(id); + var newCharacter:BaseCharacter = CharacterDataParser.fetchCharacter(id); - if (newCharacter == null) - { - return; - } + if (newCharacter == null) + { + return; + } - character = newCharacter; - if (_characterType != null) - { - character.characterType = _characterType; - } - if (flip) - { - character.flipX = !character.flipX; - } - - character.scale.x *= _scale; - character.scale.y *= _scale; - - character.animation.callback = function(name:String = "", frameNumber:Int = -1, frameIndex:Int = -1) - { - @:privateAccess - character.onAnimationFrame(name, frameNumber, frameIndex); - dispatch(new AnimationEvent(AnimationEvent.FRAME)); - }; - character.animation.finishCallback = function(name:String = "") - { - @:privateAccess - character.onAnimationFinished(name); - dispatch(new AnimationEvent(AnimationEvent.END)); - }; - add(character); + character = newCharacter; + if (_characterType != null) + { + character.characterType = _characterType; + } + if (flip) + { + character.flipX = !character.flipX; + } - invalidateComponentLayout(); + character.scale.x *= _scale; + character.scale.y *= _scale; - if (hasEvent(AnimationEvent.LOADED)) - { - dispatch(new AnimationEvent(AnimationEvent.LOADED)); - } - else - { - _redispatchLoaded = true; - } - } + character.animation.callback = function(name:String = "", frameNumber:Int = -1, frameIndex:Int = -1) + { + @:privateAccess + character.onAnimationFrame(name, frameNumber, frameIndex); + dispatch(new AnimationEvent(AnimationEvent.FRAME)); + }; + character.animation.finishCallback = function(name:String = "") + { + @:privateAccess + character.onAnimationFinished(name); + dispatch(new AnimationEvent(AnimationEvent.END)); + }; + add(character); - private override function repositionChildren() - { - super.repositionChildren(); + invalidateComponentLayout(); - @:privateAccess - var animOffsets = character.animOffsets; + if (hasEvent(AnimationEvent.LOADED)) + { + dispatch(new AnimationEvent(AnimationEvent.LOADED)); + } + else + { + _redispatchLoaded = true; + } + } - character.x = this.screenX + ((this.width / 2) - (character.frameWidth / 2)); - character.x -= animOffsets[0]; - character.y = this.screenY + ((this.height / 2) - (character.frameHeight / 2)); - character.y -= animOffsets[1]; - } + override function repositionChildren() + { + super.repositionChildren(); - private var _characterType:CharacterType; - public function setCharacterType(value:CharacterType) - { - _characterType = value; - if (character != null) - { - character.characterType = value; - } - } + @:privateAccess + var animOffsets = character.animOffsets; - public var flip(default, set):Bool; + character.x = this.screenX + ((this.width / 2) - (character.frameWidth / 2)); + character.x -= animOffsets[0]; + character.y = this.screenY + ((this.height / 2) - (character.frameHeight / 2)); + character.y -= animOffsets[1]; + } - private function set_flip(value:Bool):Bool - { - if (value == flip) - return value; + var _characterType:CharacterType; - if (character != null) - { - character.flipX = !character.flipX; - } + public function setCharacterType(value:CharacterType) + { + _characterType = value; + if (character != null) + { + character.characterType = value; + } + } - return flip = value; - } + public var flip(default, set):Bool; - var _scale:Float = 1.0; - public function setScale(value) - { - _scale = value; - if (character != null) - { - character.scale.x *= _scale; - character.scale.y *= _scale; - } - } + function set_flip(value:Bool):Bool + { + if (value == flip) return value; - public function onUpdate(event:UpdateScriptEvent) - { - if (character != null) - character.onUpdate(event); - } + if (character != null) + { + character.flipX = !character.flipX; + } - public function onBeatHit(event:SongTimeScriptEvent):Void - { - if (character != null) - character.onBeatHit(event); + return flip = value; + } - this.repositionChildren(); - } + var _scale:Float = 1.0; - public function onStepHit(event:SongTimeScriptEvent):Void - { - if (character != null) - character.onStepHit(event); - } + public function setScale(value) + { + _scale = value; + if (character != null) + { + character.scale.x *= _scale; + character.scale.y *= _scale; + } + } - public function onNoteHit(event:NoteScriptEvent):Void - { - if (character != null) - character.onNoteHit(event); + public function onUpdate(event:UpdateScriptEvent) + { + if (character != null) character.onUpdate(event); + } - this.repositionChildren(); - } + public function onBeatHit(event:SongTimeScriptEvent):Void + { + if (character != null) character.onBeatHit(event); - public function onNoteMiss(event:NoteScriptEvent):Void - { - if (character != null) - character.onNoteMiss(event); + this.repositionChildren(); + } - this.repositionChildren(); - } + public function onStepHit(event:SongTimeScriptEvent):Void + { + if (character != null) character.onStepHit(event); + } - public function onNoteGhostMiss(event:GhostMissNoteScriptEvent):Void - { - if (character != null) - character.onNoteGhostMiss(event); + public function onNoteHit(event:NoteScriptEvent):Void + { + if (character != null) character.onNoteHit(event); - this.repositionChildren(); - } + this.repositionChildren(); + } + + public function onNoteMiss(event:NoteScriptEvent):Void + { + if (character != null) character.onNoteMiss(event); + + this.repositionChildren(); + } + + public function onNoteGhostMiss(event:GhostMissNoteScriptEvent):Void + { + if (character != null) character.onNoteGhostMiss(event); + + this.repositionChildren(); + } } @:access(funkin.ui.haxeui.components.CharacterPlayer) private class Layout extends DefaultLayout { - public override function repositionChildren() - { - var player = cast(_component, CharacterPlayer); - var sprite:BaseCharacter = player.character; - if (sprite == null) - { - return super.repositionChildren(); - } + public override function repositionChildren() + { + var player = cast(_component, CharacterPlayer); + var sprite:BaseCharacter = player.character; + if (sprite == null) + { + return super.repositionChildren(); + } - @:privateAccess - var animOffsets = sprite.animOffsets; + @:privateAccess + var animOffsets = sprite.animOffsets; - sprite.x = _component.screenLeft + ((_component.width / 2) - (sprite.frameWidth / 2)); - sprite.x += animOffsets[0]; - sprite.y = _component.screenTop + ((_component.height / 2) - (sprite.frameHeight / 2)); - sprite.y += animOffsets[1]; - } + sprite.x = _component.screenLeft + ((_component.width / 2) - (sprite.frameWidth / 2)); + sprite.x += animOffsets[0]; + sprite.y = _component.screenTop + ((_component.height / 2) - (sprite.frameHeight / 2)); + sprite.y += animOffsets[1]; + } - public override function calcAutoSize(exclusions:Array = null):Size - { - var player = cast(_component, CharacterPlayer); - var sprite = player.character; - if (sprite == null) - { - return super.calcAutoSize(exclusions); - } - var size = new Size(); - size.width = sprite.frameWidth + paddingLeft + paddingRight; - size.height = sprite.frameHeight + paddingTop + paddingBottom; - return size; - } + public override function calcAutoSize(exclusions:Array = null):Size + { + var player = cast(_component, CharacterPlayer); + var sprite = player.character; + if (sprite == null) + { + return super.calcAutoSize(exclusions); + } + var size = new Size(); + size.width = sprite.frameWidth + paddingLeft + paddingRight; + size.height = sprite.frameHeight + paddingTop + paddingBottom; + return size; + } } diff --git a/source/funkin/ui/haxeui/components/Notifbar.hx b/source/funkin/ui/haxeui/components/Notifbar.hx index b643d360b..bd08b4965 100644 --- a/source/funkin/ui/haxeui/components/Notifbar.hx +++ b/source/funkin/ui/haxeui/components/Notifbar.hx @@ -12,102 +12,100 @@ import haxe.ui.core.Component; class Notifbar extends SideBar { - final NOTIFICATION_DISMISS_TIME = 5.0; // seconds - var dismissTimer:FlxTimer = null; + final NOTIFICATION_DISMISS_TIME = 5.0; // seconds + var dismissTimer:FlxTimer = null; - var outerContainer:Box = null; - var container:VBox = null; - var message:Label = null; - var action:Button = null; - var dismiss:Button = null; + var outerContainer:Box = null; + var container:VBox = null; + var message:Label = null; + var action:Button = null; + var dismiss:Button = null; - public function new() - { - super(); + public function new() + { + super(); - buildSidebar(); - buildChildren(); - } + buildSidebar(); + buildChildren(); + } - public function showNotification(message:String, ?actionText:String = null, ?actionCallback:Void->Void = null, ?dismissTime:Float = null) - { - if (dismissTimer != null) - dismissNotification(); + public function showNotification(message:String, ?actionText:String = null, ?actionCallback:Void->Void = null, ?dismissTime:Float = null) + { + if (dismissTimer != null) dismissNotification(); - if (dismissTime == null) - dismissTime = NOTIFICATION_DISMISS_TIME; + if (dismissTime == null) dismissTime = NOTIFICATION_DISMISS_TIME; - // Message text. - this.message.text = message; + // Message text. + this.message.text = message; - // Action - if (actionText != null) - { - this.action.text = actionText; - this.action.visible = true; - this.action.disabled = false; - this.action.onClick = (_) -> - { - actionCallback(); - }; - } - else - { - this.action.visible = false; - this.action.disabled = false; - this.action.onClick = null; - } + // Action + if (actionText != null) + { + this.action.text = actionText; + this.action.visible = true; + this.action.disabled = false; + this.action.onClick = (_) -> + { + actionCallback(); + }; + } + else + { + this.action.visible = false; + this.action.disabled = false; + this.action.onClick = null; + } - this.show(); + this.show(); - // Auto dismiss. - dismissTimer = new FlxTimer().start(dismissTime, (_:FlxTimer) -> dismissNotification()); - } + // Auto dismiss. + dismissTimer = new FlxTimer().start(dismissTime, (_:FlxTimer) -> dismissNotification()); + } - public function dismissNotification() - { - if (dismissTimer != null) - { - dismissTimer.cancel(); - dismissTimer = null; - } + public function dismissNotification() + { + if (dismissTimer != null) + { + dismissTimer.cancel(); + dismissTimer = null; + } - this.hide(); - } + this.hide(); + } - function buildSidebar():Void - { - this.width = 256; - this.height = 80; + function buildSidebar():Void + { + this.width = 256; + this.height = 80; - // border-top: 1px solid #000; border-left: 1px solid #000; - this.styleString = "border: 1px solid #000; background-color: #3d3f41; padding: 8px; border-top-left-radius: 8px;"; + // border-top: 1px solid #000; border-left: 1px solid #000; + this.styleString = "border: 1px solid #000; background-color: #3d3f41; padding: 8px; border-top-left-radius: 8px;"; - // float to the right - this.x = FlxG.width - this.width; + // float to the right + this.x = FlxG.width - this.width; - this.position = "bottom"; - this.method = "float"; - } + this.position = "bottom"; + this.method = "float"; + } - function buildChildren():Void - { - outerContainer = cast(buildComponent("assets/data/notifbar.xml"), Box); - addComponent(outerContainer); + function buildChildren():Void + { + outerContainer = cast(buildComponent("assets/data/notifbar.xml"), Box); + addComponent(outerContainer); - container = outerContainer.findComponent('notifbarContainer', VBox); - message = outerContainer.findComponent('notifbarMessage', Label); - action = outerContainer.findComponent('notifbarAction', Button); - dismiss = outerContainer.findComponent('notifbarDismiss', Button); + container = outerContainer.findComponent('notifbarContainer', VBox); + message = outerContainer.findComponent('notifbarMessage', Label); + action = outerContainer.findComponent('notifbarAction', Button); + dismiss = outerContainer.findComponent('notifbarDismiss', Button); - dismiss.onClick = (_) -> - { - dismissNotification(); - }; - } + dismiss.onClick = (_) -> + { + dismissNotification(); + }; + } - function buildComponent(path:String):Component - { - return RuntimeComponentBuilder.fromAsset(path); - } + function buildComponent(path:String):Component + { + return RuntimeComponentBuilder.fromAsset(path); + } } diff --git a/source/funkin/ui/stageBuildShit/CharStage.hx b/source/funkin/ui/stageBuildShit/CharStage.hx index 740c8de3b..cd13a7251 100644 --- a/source/funkin/ui/stageBuildShit/CharStage.hx +++ b/source/funkin/ui/stageBuildShit/CharStage.hx @@ -2,8 +2,8 @@ package funkin.ui.stageBuildShit; class CharStage extends SprStage { - public function new(x:Float, y:Float, dragShitFunc:SprStage->Void) - { - super(x, y, dragShitFunc); - } + public function new(x:Float, y:Float, dragShitFunc:SprStage->Void) + { + super(x, y, dragShitFunc); + } } diff --git a/source/funkin/ui/stageBuildShit/SprStage.hx b/source/funkin/ui/stageBuildShit/SprStage.hx index 23387aedd..681e6f10f 100644 --- a/source/funkin/ui/stageBuildShit/SprStage.hx +++ b/source/funkin/ui/stageBuildShit/SprStage.hx @@ -6,47 +6,46 @@ import flixel.math.FlxPoint; class SprStage extends FlxSprite { - public var imgName:String = ''; + public var imgName:String = ''; - public var layer:Int = 0; - public var mousePressing:Bool = false; + public var layer:Int = 0; + public var mousePressing:Bool = false; - public var mouseOffset:FlxPoint = FlxPoint.get(0, 0); - public var oldPos:FlxPoint = FlxPoint.get(0, 0); + public var mouseOffset:FlxPoint = FlxPoint.get(0, 0); + public var oldPos:FlxPoint = FlxPoint.get(0, 0); - public function new(?x:Float = 0, ?y:Float = 0, dragShitFunc:SprStage->Void) - { - super(x, y); + public function new(?x:Float = 0, ?y:Float = 0, dragShitFunc:SprStage->Void) + { + super(x, y); - FlxMouseEvent.add(this, dragShitFunc, null, function(spr:SprStage) - { - if (isSelected() || StageBuilderState.curTool == SELECT) - alpha = 0.5; - }, function(spr:SprStage) - { - alpha = 1; - }, false, true, true); - } + FlxMouseEvent.add(this, dragShitFunc, null, function(spr:SprStage) + { + if (isSelected() || StageBuilderState.curTool == SELECT) alpha = 0.5; + }, function(spr:SprStage) + { + alpha = 1; + }, false, true, true); + } - public function isSelected():Bool - { - return StageBuilderState.curSelectedSpr == this; - } + public function isSelected():Bool + { + return StageBuilderState.curSelectedSpr == this; + } - override function update(elapsed:Float) - { - super.update(elapsed); + override function update(elapsed:Float) + { + super.update(elapsed); - if (mousePressing && isSelected()) - { - this.x = FlxG.mouse.x - mouseOffset.x; - this.y = FlxG.mouse.y - mouseOffset.y; - } + if (mousePressing && isSelected()) + { + this.x = FlxG.mouse.x - mouseOffset.x; + this.y = FlxG.mouse.y - mouseOffset.y; + } - if (FlxG.mouse.justReleased) - { - mousePressing = false; - StageBuilderState.changeTool(GRAB); - } - } + if (FlxG.mouse.justReleased) + { + mousePressing = false; + StageBuilderState.changeTool(GRAB); + } + } } diff --git a/source/funkin/ui/stageBuildShit/StageBuilderState.hx b/source/funkin/ui/stageBuildShit/StageBuilderState.hx index 3d9a555a0..ad40a8657 100644 --- a/source/funkin/ui/stageBuildShit/StageBuilderState.hx +++ b/source/funkin/ui/stageBuildShit/StageBuilderState.hx @@ -15,434 +15,421 @@ import flixel.util.FlxTimer; class StageBuilderState extends MusicBeatState { - private var hudGrp:FlxGroup; - var textInfo:FlxText; + var hudGrp:FlxGroup; + var textInfo:FlxText; - private var sprGrp:FlxTypedGroup; + var sprGrp:FlxTypedGroup; - // var snd:Sound; - // var sndChannel:SoundChannel; - var hudCam:FlxCamera; + // var snd:Sound; + // var sndChannel:SoundChannel; + var hudCam:FlxCamera; - override function create() - { - hudCam = new FlxCamera(); - hudCam.bgColor.alpha = 0; + override function create() + { + hudCam = new FlxCamera(); + hudCam.bgColor.alpha = 0; - FlxG.cameras.add(hudCam, false); + FlxG.cameras.add(hudCam, false); - super.create(); + super.create(); - FlxG.mouse.visible = true; + FlxG.mouse.visible = true; - // var alsoSnd:FlxSound = new FlxSound(); + // var alsoSnd:FlxSound = new FlxSound(); - // snd = new Sound(); + // snd = new Sound(); - // var swagBytes:ByteArray = new ByteArray(8192); + // var swagBytes:ByteArray = new ByteArray(8192); - // for (shit in 0...8192) - // { - // swagBytes.writeFloat(Math.sin((shit) / Math.PI) * 0.25); - // swagBytes.writeFloat(Math.sin((shit) / Math.PI) * 0.25); - // trace('wweseosme???'); - // } + // for (shit in 0...8192) + // { + // swagBytes.writeFloat(Math.sin((shit) / Math.PI) * 0.25); + // swagBytes.writeFloat(Math.sin((shit) / Math.PI) * 0.25); + // trace('wweseosme???'); + // } - // snd.__buffer = AudioBuffer.fromBytes(swagBytes); - // snd.dispatchEvent(new Event(Event.COMPLETE)); + // snd.__buffer = AudioBuffer.fromBytes(swagBytes); + // snd.dispatchEvent(new Event(Event.COMPLETE)); - // swagBytes.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); - // swagBytes.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); + // swagBytes.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); + // swagBytes.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); - // function sineShit(event:SampleDataEvent):Void - // { - // for (shit in 0...8192) - // { - // event.data.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); - // event.data.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); - // trace('wweseosme???'); - // } - // } + // function sineShit(event:SampleDataEvent):Void + // { + // for (shit in 0...8192) + // { + // event.data.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); + // event.data.writeFloat(Math.sin((shit + event.position) / Math.PI) * 0.25); + // trace('wweseosme???'); + // } + // } - // snd.addEventListener(SampleDataEvent.SAMPLE_DATA, sineShit); - // snd.__buffer. - // snd = Assets.getSound(Paths.music('freakyMenu')); - // for (thing in snd.load) - // thing = Std.int(thing / 2); - // snd.play(); - // trace(snd.__buffer.data.toBytes().getData().bytes); + // snd.addEventListener(SampleDataEvent.SAMPLE_DATA, sineShit); + // snd.__buffer. + // snd = Assets.getSound(Paths.music('freakyMenu')); + // for (thing in snd.load) + // thing = Std.int(thing / 2); + // snd.play(); + // trace(snd.__buffer.data.toBytes().getData().bytes); - var bg:FlxSprite = FlxGridOverlay.create(10, 10); - add(bg); + var bg:FlxSprite = FlxGridOverlay.create(10, 10); + add(bg); - sprGrp = new FlxTypedGroup(); - add(sprGrp); + sprGrp = new FlxTypedGroup(); + add(sprGrp); - hudGrp = new FlxGroup(); - hudGrp.cameras = [hudCam]; - add(hudGrp); + hudGrp = new FlxGroup(); + hudGrp.cameras = [hudCam]; + add(hudGrp); - textInfo = new FlxText(10, 80, 0, "", 24); - textInfo.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); - textInfo.scrollFactor.set(); - hudGrp.add(textInfo); + textInfo = new FlxText(10, 80, 0, "", 24); + textInfo.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + textInfo.scrollFactor.set(); + hudGrp.add(textInfo); - var imgBtn:FlxButton = new FlxButton(20, 20, "Load Image", loadImage); - hudGrp.add(imgBtn); + var imgBtn:FlxButton = new FlxButton(20, 20, "Load Image", loadImage); + hudGrp.add(imgBtn); - var saveSceneBtn:FlxButton = new FlxButton(20, 50, "Save Scene", saveScene); - hudGrp.add(saveSceneBtn); + var saveSceneBtn:FlxButton = new FlxButton(20, 50, "Save Scene", saveScene); + hudGrp.add(saveSceneBtn); - #if desktop - FlxG.stage.window.onDropFile.add(function(path:String) - { - trace("DROPPED FILE FROM: " + Std.string(path)); + #if desktop + FlxG.stage.window.onDropFile.add(function(path:String) + { + trace("DROPPED FILE FROM: " + Std.string(path)); - var fileName:String = path.split('\\').pop(); - var fileNameNoExt:String = fileName.split('.')[0]; + var fileName:String = path.split('\\').pop(); + var fileNameNoExt:String = fileName.split('.')[0]; - var newPath = './' + Paths.image('stageBuild/' + fileNameNoExt); - // sys.io.File.copy(path, newPath); - // trace(sys.io.File.getBytes(Std.string(path)).toString()); + var newPath = './' + Paths.image('stageBuild/' + fileNameNoExt); + // sys.io.File.copy(path, newPath); + // trace(sys.io.File.getBytes(Std.string(path)).toString()); - // FlxG.bitmap.add('assets/preload/images/stageBuild/eltonJohn.png'); + // FlxG.bitmap.add('assets/preload/images/stageBuild/eltonJohn.png'); - sys.io.File.copy(path, './' + Paths.image('stageBuild/stageTempImg')); + sys.io.File.copy(path, './' + Paths.image('stageBuild/stageTempImg')); - var fo = sys.io.File.write(newPath); + var fo = sys.io.File.write(newPath); - fo.write(sys.io.File.getBytes(path)); + fo.write(sys.io.File.getBytes(path)); - new FlxTimer().start(0.2, function(tmr) - { - var awesomeImg:SprStage = new SprStage(FlxG.mouse.x, FlxG.mouse.y, sprDragShitFunc); - awesomeImg.loadGraphic(Paths.image('stageBuild/stageTempImg'), false, 0, 0, true); + new FlxTimer().start(0.2, function(tmr) + { + var awesomeImg:SprStage = new SprStage(FlxG.mouse.x, FlxG.mouse.y, sprDragShitFunc); + awesomeImg.loadGraphic(Paths.image('stageBuild/stageTempImg'), false, 0, 0, true); - awesomeImg.layer = sprGrp.members.length; - awesomeImg.imgName = fileName; - - sprGrp.add(awesomeImg); - - curFocus = MOVEMENTS; - }); - - // Load the image shit by - // 1. reading the image file names - // 2. copy to stage temp like normal? + awesomeImg.layer = sprGrp.members.length; + awesomeImg.imgName = fileName; - // var awesomeImg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('stageBuild/swag')); - // sprGrp.add(awesomeImg); - // var swag = Paths.image('characters/temp'); - - // if (bf != null) - // remove(bf); - // FlxG.bitmap.removeByKey(Paths.image('characters/temp')); - - // bf.loadGraphic(Paths.image('characters/temp')); - // add(bf); - }); - #end - } - - public static var curSelectedSpr:SprStage; - - function loadImage():Void - { - // var img:FlxSprite = new FlxSprite().loadGraphic(Paths.image('newgrounds_logo')); - // img.scrollFactor.set(0.5, 2); - // sprGrp.add(img); - } - - function saveScene():Void - { - // trace(); - } - - public static var curTool:TOOLS = SELECT; - - var tempTool:TOOLS = SELECT; - - override function update(elapsed:Float) - { - if (FlxG.keys.justPressed.H) - hudGrp.visible = !hudGrp.visible; - - if (FlxG.keys.justPressed.ESCAPE) - { - if (curFocus == ATTRIBUTES) - curFocus = MOVEMENTS; - else - curFocus = ATTRIBUTES; - } - - switch (curFocus) - { - case MOVEMENTS: - movementControls(); - case ATTRIBUTES: - attributeControls(); - default: - } - - if (FlxG.keys.justPressed.DELETE) - { - if (curSelectedSpr != null) - sprGrp.remove(curSelectedSpr, true); - } - - CoolUtil.mouseCamDrag(); - - if (FlxG.keys.pressed.CONTROL) - CoolUtil.mouseWheelZoom(); - - if (isShaking) - { - FlxG.stage.window.x = Std.int(shakePos.x + (FlxG.random.float(-1, 1) * shakeIntensity)); - FlxG.stage.window.y = Std.int(shakePos.y + (FlxG.random.float(-1, 1) * shakeIntensity)); - - shakeIntensity -= 30 * elapsed; - - if (shakeIntensity <= 0) - { - isShaking = false; - shakeIntensity = 60; - FlxG.stage.window.x = Std.int(shakePos.x); - FlxG.stage.window.y = Std.int(shakePos.y); - } - } - - if (curTool == GRABBING && FlxG.mouse.justReleased) - { - moveSprPos([ - curSelectedSpr.x - curSelectedSpr.oldPos.x, - curSelectedSpr.y - curSelectedSpr.oldPos.y - ]); - } - - if (FlxG.keys.justPressed.Z && actionQueue.length > 0) - { - // trace('UNDO - QUEUE LENGTH: ' + actionQueue.length); - isUndoRedo = true; - - var daFunc = actionQueue.pop(); - var daValue = posQueue.pop(); - - daFunc(daValue); - } - - super.update(elapsed); - } - - function attributeControls():Void - { - textInfo.alpha = 1; - - if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.RIGHT) - { - if (FlxG.keys.justPressed.LEFT) - { - curSelectedSpr.scrollFactor.x -= 0.1; - curSelectedSpr.scrollFactor.y -= 0.1; - } - - if (FlxG.keys.justPressed.RIGHT) - { - curSelectedSpr.scrollFactor.x += 0.1; - curSelectedSpr.scrollFactor.y += 0.1; - } - - updateTextInfo(); - } - } - - function movementControls():Void - { - textInfo.alpha = 0.5; - - if (FlxG.keys.justPressed.CONTROL) - { - tempTool = curTool; - - changeTool(SELECT); - } - if (FlxG.keys.justReleased.CONTROL) - { - changeTool(tempTool); - } - - if (FlxG.keys.justPressed.V) - { - changeTool(SELECT); - } - - if (FlxG.keys.justPressed.R) - { - shakingScreen(); - - FlxG.stage.window.title = "YOU WILL DIE"; - - // FlxG.stage.window.x -= Std.int(10); - // FlxG.stage.window.y -= Std.int(10); - // FlxG.stage.window.width += Std.int(40); - // FlxG.stage.window.height += Std.int(20); - } - - if (FlxG.keys.justPressed.RIGHT) - moveSprPos([1, 0, true]); - if (FlxG.keys.justPressed.LEFT) - moveSprPos([-1, 0, true]); - if (FlxG.keys.justPressed.UP) - moveSprPos([0, -1, true]); - if (FlxG.keys.justPressed.DOWN) - moveSprPos([0, 1, true]); - - if (FlxG.keys.justPressed.LBRACKET) - { - if (curSelectedSpr != null) - moveLayer(1); - } - - if (FlxG.keys.justPressed.RBRACKET) - { - if (curSelectedSpr != null) - moveLayer(-1); - } - } - - var curFocus:FOCUS = MOVEMENTS; - - static public function changeTool(newTool:TOOLS) - { - curTool = newTool; - - switch (curTool) - { - // redo this later so it doesn't create brand new FlxSprites into memory or someshit??? this was lazy 3AM way - case SELECT: - FlxG.mouse.load(new FlxSprite().loadGraphic(Paths.image('stageBuild/cursorSelect')).pixels); - case GRABBING: - FlxG.mouse.load(new FlxSprite().loadGraphic(Paths.image('stageBuild/cursorGrabbing')).pixels); - case GRAB: - FlxG.mouse.load(new FlxSprite().loadGraphic(Paths.image('stageBuild/cursorGrab')).pixels); - default: - trace('swag'); - } - } - - function changeCurSelected(spr:SprStage) - { - undoRedoCheck(changeCurSelected, curSelectedSpr); - curSelectedSpr = spr; - - updateTextInfo(); - } - - function updateTextInfo() - { - textInfo.text = curSelectedSpr.imgName; - textInfo.text += ' - parallax: ' + curSelectedSpr.scrollFactor; - } - - // base check to see if its in a state of undo or redo - function undoRedoCheck(daFunc:Dynamic->Void, daValue:Dynamic) - { - if (!isUndoRedo) - { - actionQueue.push(daFunc); - posQueue.push(daValue); - } - else - isUndoRedo = false; - } - - function sprDragShitFunc(spr:SprStage) - { - if (curTool == SELECT) - changeCurSelected(spr); - - spr.mousePressing = true; - - if (spr.isSelected()) - changeTool(GRABBING); - spr.mouseOffset.set(FlxG.mouse.x - spr.x, FlxG.mouse.y - spr.y); - spr.oldPos.set(spr.x, spr.y); - } - - // make function for changing cur selection - function moveSprPos(dumbArray:Array) - { - var xDiff:Float = dumbArray[0]; - var yDiff:Float = dumbArray[1]; - var forceMove:Bool = dumbArray[2]; - - // trace(xDiff); - // trace(yDiff); - - // usually set to false for the MOUSE DRAG, merely to track movements from the mouse - if (forceMove) - { - curSelectedSpr.x += xDiff; - curSelectedSpr.y += yDiff; - } - - undoRedoCheck(moveSprPos, [-xDiff, -yDiff, true]); - } - - var isUndoRedo:Bool = false; - var actionQueue:ArrayVoid> = []; - var posQueue:Array = []; - - function moveLayer(layerMovement:Int = 0):Void - { - if (curSelectedSpr.layer == 0 && layerMovement > 0) - return; - - curSelectedSpr.layer -= layerMovement; - sprGrp.members[curSelectedSpr.layer].layer += layerMovement; - // NOTE: fix to account if only one layer is in? - - sortSprGrp(); - undoRedoCheck(moveLayer, layerMovement * -1); - } - - var isShaking:Bool = false; - var shakeIntensity:Float = 60; - var shakePos:FlxPoint = new FlxPoint(); - - function shakingScreen() - { - if (!isShaking) - { - isShaking = true; - shakePos.set(FlxG.stage.window.x, FlxG.stage.window.y); - } - } - - function sortSprGrp() - { - sprGrp.sort(daLayerSorting, FlxSort.ASCENDING); - - FlxMouseEvent.reorder(); - } - - function daLayerSorting(order:Int = FlxSort.ASCENDING, layer1:SprStage, layer2:SprStage):Int - { - return FlxSort.byValues(FlxSort.ASCENDING, layer1.layer, layer2.layer); - } + sprGrp.add(awesomeImg); + + curFocus = MOVEMENTS; + }); + + // Load the image shit by + // 1. reading the image file names + // 2. copy to stage temp like normal? + + // var awesomeImg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('stageBuild/swag')); + // sprGrp.add(awesomeImg); + // var swag = Paths.image('characters/temp'); + + // if (bf != null) + // remove(bf); + // FlxG.bitmap.removeByKey(Paths.image('characters/temp')); + + // bf.loadGraphic(Paths.image('characters/temp')); + // add(bf); + }); + #end + } + + public static var curSelectedSpr:SprStage; + + function loadImage():Void + { + // var img:FlxSprite = new FlxSprite().loadGraphic(Paths.image('newgrounds_logo')); + // img.scrollFactor.set(0.5, 2); + // sprGrp.add(img); + } + + function saveScene():Void + { + // trace(); + } + + public static var curTool:TOOLS = SELECT; + + var tempTool:TOOLS = SELECT; + + override function update(elapsed:Float) + { + if (FlxG.keys.justPressed.H) hudGrp.visible = !hudGrp.visible; + + if (FlxG.keys.justPressed.ESCAPE) + { + if (curFocus == ATTRIBUTES) curFocus = MOVEMENTS; + else + curFocus = ATTRIBUTES; + } + + switch (curFocus) + { + case MOVEMENTS: + movementControls(); + case ATTRIBUTES: + attributeControls(); + default: + } + + if (FlxG.keys.justPressed.DELETE) + { + if (curSelectedSpr != null) sprGrp.remove(curSelectedSpr, true); + } + + CoolUtil.mouseCamDrag(); + + if (FlxG.keys.pressed.CONTROL) CoolUtil.mouseWheelZoom(); + + if (isShaking) + { + FlxG.stage.window.x = Std.int(shakePos.x + (FlxG.random.float(-1, 1) * shakeIntensity)); + FlxG.stage.window.y = Std.int(shakePos.y + (FlxG.random.float(-1, 1) * shakeIntensity)); + + shakeIntensity -= 30 * elapsed; + + if (shakeIntensity <= 0) + { + isShaking = false; + shakeIntensity = 60; + FlxG.stage.window.x = Std.int(shakePos.x); + FlxG.stage.window.y = Std.int(shakePos.y); + } + } + + if (curTool == GRABBING && FlxG.mouse.justReleased) + { + moveSprPos([ + curSelectedSpr.x - curSelectedSpr.oldPos.x, + curSelectedSpr.y - curSelectedSpr.oldPos.y + ]); + } + + if (FlxG.keys.justPressed.Z && actionQueue.length > 0) + { + // trace('UNDO - QUEUE LENGTH: ' + actionQueue.length); + isUndoRedo = true; + + var daFunc = actionQueue.pop(); + var daValue = posQueue.pop(); + + daFunc(daValue); + } + + super.update(elapsed); + } + + function attributeControls():Void + { + textInfo.alpha = 1; + + if (FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.RIGHT) + { + if (FlxG.keys.justPressed.LEFT) + { + curSelectedSpr.scrollFactor.x -= 0.1; + curSelectedSpr.scrollFactor.y -= 0.1; + } + + if (FlxG.keys.justPressed.RIGHT) + { + curSelectedSpr.scrollFactor.x += 0.1; + curSelectedSpr.scrollFactor.y += 0.1; + } + + updateTextInfo(); + } + } + + function movementControls():Void + { + textInfo.alpha = 0.5; + + if (FlxG.keys.justPressed.CONTROL) + { + tempTool = curTool; + + changeTool(SELECT); + } + if (FlxG.keys.justReleased.CONTROL) + { + changeTool(tempTool); + } + + if (FlxG.keys.justPressed.V) + { + changeTool(SELECT); + } + + if (FlxG.keys.justPressed.R) + { + shakingScreen(); + + FlxG.stage.window.title = "YOU WILL DIE"; + + // FlxG.stage.window.x -= Std.int(10); + // FlxG.stage.window.y -= Std.int(10); + // FlxG.stage.window.width += Std.int(40); + // FlxG.stage.window.height += Std.int(20); + } + + if (FlxG.keys.justPressed.RIGHT) moveSprPos([1, 0, true]); + if (FlxG.keys.justPressed.LEFT) moveSprPos([-1, 0, true]); + if (FlxG.keys.justPressed.UP) moveSprPos([0, -1, true]); + if (FlxG.keys.justPressed.DOWN) moveSprPos([0, 1, true]); + + if (FlxG.keys.justPressed.LBRACKET) + { + if (curSelectedSpr != null) moveLayer(1); + } + + if (FlxG.keys.justPressed.RBRACKET) + { + if (curSelectedSpr != null) moveLayer(-1); + } + } + + var curFocus:FOCUS = MOVEMENTS; + + static public function changeTool(newTool:TOOLS) + { + curTool = newTool; + + switch (curTool) + { + // redo this later so it doesn't create brand new FlxSprites into memory or someshit??? this was lazy 3AM way + case SELECT: + FlxG.mouse.load(new FlxSprite().loadGraphic(Paths.image('stageBuild/cursorSelect')).pixels); + case GRABBING: + FlxG.mouse.load(new FlxSprite().loadGraphic(Paths.image('stageBuild/cursorGrabbing')).pixels); + case GRAB: + FlxG.mouse.load(new FlxSprite().loadGraphic(Paths.image('stageBuild/cursorGrab')).pixels); + default: + trace('swag'); + } + } + + function changeCurSelected(spr:SprStage) + { + undoRedoCheck(changeCurSelected, curSelectedSpr); + curSelectedSpr = spr; + + updateTextInfo(); + } + + function updateTextInfo() + { + textInfo.text = curSelectedSpr.imgName; + textInfo.text += ' - parallax: ' + curSelectedSpr.scrollFactor; + } + + // base check to see if its in a state of undo or redo + function undoRedoCheck(daFunc:Dynamic->Void, daValue:Dynamic) + { + if (!isUndoRedo) + { + actionQueue.push(daFunc); + posQueue.push(daValue); + } + else + isUndoRedo = false; + } + + function sprDragShitFunc(spr:SprStage) + { + if (curTool == SELECT) changeCurSelected(spr); + + spr.mousePressing = true; + + if (spr.isSelected()) changeTool(GRABBING); + spr.mouseOffset.set(FlxG.mouse.x - spr.x, FlxG.mouse.y - spr.y); + spr.oldPos.set(spr.x, spr.y); + } + + // make function for changing cur selection + function moveSprPos(dumbArray:Array) + { + var xDiff:Float = dumbArray[0]; + var yDiff:Float = dumbArray[1]; + var forceMove:Bool = dumbArray[2]; + + // trace(xDiff); + // trace(yDiff); + + // usually set to false for the MOUSE DRAG, merely to track movements from the mouse + if (forceMove) + { + curSelectedSpr.x += xDiff; + curSelectedSpr.y += yDiff; + } + + undoRedoCheck(moveSprPos, [-xDiff, -yDiff, true]); + } + + var isUndoRedo:Bool = false; + var actionQueue:ArrayVoid> = []; + var posQueue:Array = []; + + function moveLayer(layerMovement:Int = 0):Void + { + if (curSelectedSpr.layer == 0 && layerMovement > 0) return; + + curSelectedSpr.layer -= layerMovement; + sprGrp.members[curSelectedSpr.layer].layer += layerMovement; + // NOTE: fix to account if only one layer is in? + + sortSprGrp(); + undoRedoCheck(moveLayer, layerMovement * -1); + } + + var isShaking:Bool = false; + var shakeIntensity:Float = 60; + var shakePos:FlxPoint = new FlxPoint(); + + function shakingScreen() + { + if (!isShaking) + { + isShaking = true; + shakePos.set(FlxG.stage.window.x, FlxG.stage.window.y); + } + } + + function sortSprGrp() + { + sprGrp.sort(daLayerSorting, FlxSort.ASCENDING); + + FlxMouseEvent.reorder(); + } + + function daLayerSorting(order:Int = FlxSort.ASCENDING, layer1:SprStage, layer2:SprStage):Int + { + return FlxSort.byValues(FlxSort.ASCENDING, layer1.layer, layer2.layer); + } } enum FOCUS { - ATTRIBUTES; - MOVEMENTS; - TOOLBAR; + ATTRIBUTES; + MOVEMENTS; + TOOLBAR; } enum TOOLS { - SELECT; - MOVE; - GRAB; - GRABBING; - BOYFRIEND; + SELECT; + MOVE; + GRAB; + GRABBING; + BOYFRIEND; } diff --git a/source/funkin/ui/stageBuildShit/StageOffsetSubstate.hx b/source/funkin/ui/stageBuildShit/StageOffsetSubstate.hx index b527aa92e..4e255a963 100644 --- a/source/funkin/ui/stageBuildShit/StageOffsetSubstate.hx +++ b/source/funkin/ui/stageBuildShit/StageOffsetSubstate.hx @@ -80,8 +80,7 @@ class StageOffsetSubstate extends MusicBeatSubstate CoolUtil.mouseCamDrag(); - if (FlxG.keys.pressed.CONTROL) - CoolUtil.mouseWheelZoom(); + if (FlxG.keys.pressed.CONTROL) CoolUtil.mouseWheelZoom(); if (FlxG.mouse.wheel != 0) { @@ -96,8 +95,7 @@ class StageOffsetSubstate extends MusicBeatSubstate thing.alpha = 1; } - if (uiStuff != null) - remove(uiStuff); + if (uiStuff != null) remove(uiStuff); uiStuff = null; @@ -109,7 +107,7 @@ class StageOffsetSubstate extends MusicBeatSubstate var _file:FileReference; - private function saveStageFileRef(_):Void + function saveStageFileRef(_):Void { var jsonStr = prepStageStuff(); @@ -145,7 +143,7 @@ class StageOffsetSubstate extends MusicBeatSubstate _file = null; } - private function saveCharacterCompile(_):Void + function saveCharacterCompile(_):Void { var outputJson:String = prepStageStuff(); @@ -158,7 +156,7 @@ class StageOffsetSubstate extends MusicBeatSubstate #end } - private function prepStageStuff():String + function prepStageStuff():String { var stageLol:StageData = StageDataParser.parseStageData(PlayState.instance.currentStageId); diff --git a/source/funkin/ui/stageBuildShit/StagetoolBar.hx b/source/funkin/ui/stageBuildShit/StagetoolBar.hx index 521881c9c..1a443f42a 100644 --- a/source/funkin/ui/stageBuildShit/StagetoolBar.hx +++ b/source/funkin/ui/stageBuildShit/StagetoolBar.hx @@ -4,19 +4,19 @@ import flixel.group.FlxGroup; class StagetoolBar extends FlxGroup { - var icons:Array = [SELECT, MOVE, GRAB, BOYFRIEND]; - var iconSprs:Array = ['cursorSelect', 'cursorGrab', 'cursorMove', 'toolbarBF']; + var icons:Array = [SELECT, MOVE, GRAB, BOYFRIEND]; + var iconSprs:Array = ['cursorSelect', 'cursorGrab', 'cursorMove', 'toolbarBF']; - public function new() - { - super(); + public function new() + { + super(); - for (icon in icons) - { - // switch (icon) - // { - // case SELECT: - // } - } - } + for (icon in icons) + { + // switch (icon) + // { + // case SELECT: + // } + } + } } diff --git a/source/funkin/util/BezierUtil.hx b/source/funkin/util/BezierUtil.hx index a1bd45762..56d20cf48 100644 --- a/source/funkin/util/BezierUtil.hx +++ b/source/funkin/util/BezierUtil.hx @@ -2,76 +2,86 @@ package funkin.util; import flixel.math.FlxPoint; -class BezierUtil { - /** - * Linearly interpolate between two values. - * Depending on p, 0 = a, 1 = b, 0.5 = halfway between a and b. - */ - static inline function mix2(p:Float, a:Float, b:Float):Float { - return a * (1 - p) + (b * p); - } +class BezierUtil +{ + /** + * Linearly interpolate between two values. + * Depending on p, 0 = a, 1 = b, 0.5 = halfway between a and b. + */ + static inline function mix2(p:Float, a:Float, b:Float):Float + { + return a * (1 - p) + (b * p); + } - /** - * Linearly interpolate between three values. - * Depending on p, 0 = a, 0.5 = b, 1 = c, 0.25 = halfway between a and c, etc. - */ - static inline function mix3(p:Float, a:Float, b:Float, c:Float):Float { - return mix2(p, mix2(p, a, b), mix2(p, b, c)); - } + /** + * Linearly interpolate between three values. + * Depending on p, 0 = a, 0.5 = b, 1 = c, 0.25 = halfway between a and c, etc. + */ + static inline function mix3(p:Float, a:Float, b:Float, c:Float):Float + { + return mix2(p, mix2(p, a, b), mix2(p, b, c)); + } - static inline function mix4(p:Float, a:Float, b:Float, c:Float, d:Float):Float { - return mix2(p, mix3(p, a, b, c), mix3(p, b, c, d)); - } + static inline function mix4(p:Float, a:Float, b:Float, c:Float, d:Float):Float + { + return mix2(p, mix3(p, a, b, c), mix3(p, b, c, d)); + } - static inline function mix5(p:Float, a:Float, b:Float, c:Float, d:Float, e:Float):Float { - return mix2(p, mix4(p, a, b, c, d), mix4(p, b, c, d, e)); - } + static inline function mix5(p:Float, a:Float, b:Float, c:Float, d:Float, e:Float):Float + { + return mix2(p, mix4(p, a, b, c, d), mix4(p, b, c, d, e)); + } - static inline function mix6(p:Float, a:Float, b:Float, c:Float, d:Float, e:Float, f:Float):Float { - return mix2(p, mix5(p, a, b, c, d, e), mix5(p, b, c, d, e, f)); - } + static inline function mix6(p:Float, a:Float, b:Float, c:Float, d:Float, e:Float, f:Float):Float + { + return mix2(p, mix5(p, a, b, c, d, e), mix5(p, b, c, d, e, f)); + } - /** - * A bezier curve with two points. - * This is really just linear interpolation but whatever. - */ - public static function bezier2(p:Float, a:FlxPoint, b:FlxPoint):FlxPoint { - return new FlxPoint(mix2(p, a.x, b.x), mix2(p, a.y, b.y)); - } + /** + * A bezier curve with two points. + * This is really just linear interpolation but whatever. + */ + public static function bezier2(p:Float, a:FlxPoint, b:FlxPoint):FlxPoint + { + return new FlxPoint(mix2(p, a.x, b.x), mix2(p, a.y, b.y)); + } - /** - * A bezier curve with three points. - * @param p The percentage of the way through the curve. - * @param a The start point. - * @param b The control point. - * @param c The end point. - */ - public static function bezier3(p:Float, a:FlxPoint, b:FlxPoint, c:FlxPoint):FlxPoint { - return new FlxPoint(mix3(p, a.x, b.x, c.x), mix3(p, a.y, b.y, c.y)); - } + /** + * A bezier curve with three points. + * @param p The percentage of the way through the curve. + * @param a The start point. + * @param b The control point. + * @param c The end point. + */ + public static function bezier3(p:Float, a:FlxPoint, b:FlxPoint, c:FlxPoint):FlxPoint + { + return new FlxPoint(mix3(p, a.x, b.x, c.x), mix3(p, a.y, b.y, c.y)); + } - /** - * A bezier curve with four points. - * @param p The percentage of the way through the curve. - * @param a The start point. - * @param b The first control point. - * @param c The second control point. - * @param d The end point. - */ - public static function bezier4(p:Float, a:FlxPoint, b:FlxPoint, c:FlxPoint, d:FlxPoint):FlxPoint { - return new FlxPoint(mix4(p, a.x, b.x, c.x, d.x), mix4(p, a.y, b.y, c.y, d.y)); - } + /** + * A bezier curve with four points. + * @param p The percentage of the way through the curve. + * @param a The start point. + * @param b The first control point. + * @param c The second control point. + * @param d The end point. + */ + public static function bezier4(p:Float, a:FlxPoint, b:FlxPoint, c:FlxPoint, d:FlxPoint):FlxPoint + { + return new FlxPoint(mix4(p, a.x, b.x, c.x, d.x), mix4(p, a.y, b.y, c.y, d.y)); + } - /** - * A bezier curve with four points. - * @param p The percentage of the way through the curve. - * @param a The start point. - * @param b The first control point. - * @param c The second control point. - * @param c The third control point. - * @param d The end point. - */ - public static function bezier5(p:Float, a:FlxPoint, b:FlxPoint, c:FlxPoint, d:FlxPoint, e:FlxPoint):FlxPoint { - return new FlxPoint(mix5(p, a.x, b.x, c.x, d.x, e.x), mix5(p, a.y, b.y, c.y, d.y, e.y)); - } -} \ No newline at end of file + /** + * A bezier curve with four points. + * @param p The percentage of the way through the curve. + * @param a The start point. + * @param b The first control point. + * @param c The second control point. + * @param c The third control point. + * @param d The end point. + */ + public static function bezier5(p:Float, a:FlxPoint, b:FlxPoint, c:FlxPoint, d:FlxPoint, e:FlxPoint):FlxPoint + { + return new FlxPoint(mix5(p, a.x, b.x, c.x, d.x, e.x), mix5(p, a.y, b.y, c.y, d.y, e.y)); + } +} diff --git a/source/funkin/util/ClipboardUtil.hx b/source/funkin/util/ClipboardUtil.hx index bd81a2d4d..292cb111f 100644 --- a/source/funkin/util/ClipboardUtil.hx +++ b/source/funkin/util/ClipboardUtil.hx @@ -7,45 +7,45 @@ package funkin.util; */ class ClipboardUtil { - /** - * Add an event listener callback which executes next time the system clipboard is updated. - * - * @param callback The callback to execute when the clipboard is updated. - * @param once If true, the callback will only execute once and then be deleted. - * @param priority Set the priority at which the callback will be executed. Higher values execute first. - */ - public static function addListener(callback:Void->Void, ?once:Bool = false, ?priority:Int = 0):Void - { - lime.system.Clipboard.onUpdate.add(callback, once, priority); - } + /** + * Add an event listener callback which executes next time the system clipboard is updated. + * + * @param callback The callback to execute when the clipboard is updated. + * @param once If true, the callback will only execute once and then be deleted. + * @param priority Set the priority at which the callback will be executed. Higher values execute first. + */ + public static function addListener(callback:Void->Void, ?once:Bool = false, ?priority:Int = 0):Void + { + lime.system.Clipboard.onUpdate.add(callback, once, priority); + } - /** - * Remove an event listener callback from the system clipboard. - * - * @param callback The callback to remove. - */ - public static function removeListener(callback:Void->Void):Void - { - lime.system.Clipboard.onUpdate.remove(callback); - } + /** + * Remove an event listener callback from the system clipboard. + * + * @param callback The callback to remove. + */ + public static function removeListener(callback:Void->Void):Void + { + lime.system.Clipboard.onUpdate.remove(callback); + } - /** - * Get the current contents of the system clipboard. - * - * @return The current contents of the system clipboard. - */ - public static function getClipboard():String - { - return lime.system.Clipboard.text; - } + /** + * Get the current contents of the system clipboard. + * + * @return The current contents of the system clipboard. + */ + public static function getClipboard():String + { + return lime.system.Clipboard.text; + } - /** - * Set the contents of the system clipboard. - * - * @param text The text to set the system clipboard to. - */ - public static function setClipboard(text:String):String - { - return lime.system.Clipboard.text = text; - } + /** + * Set the contents of the system clipboard. + * + * @param text The text to set the system clipboard to. + */ + public static function setClipboard(text:String):String + { + return lime.system.Clipboard.text = text; + } } diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 622cb5fd2..4379fe48e 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -5,109 +5,109 @@ import lime.app.Application; class Constants { - /** - * ENGINE AND VERSION DATA - */ - // ============================== + /** + * ENGINE AND VERSION DATA + */ + // ============================== - /** - * The title of the game, for debug printing purposes. - * Change this if you're making an engine. - */ - public static final TITLE = "Friday Night Funkin'"; + /** + * The title of the game, for debug printing purposes. + * Change this if you're making an engine. + */ + public static final TITLE = "Friday Night Funkin'"; - /** - * The current version number of the game. - * Modify this in the `project.xml` file. - */ - public static var VERSION(get, null):String; + /** + * The current version number of the game. + * Modify this in the `project.xml` file. + */ + public static var VERSION(get, null):String; - /** - * A suffix to add to the game version. - * Add a suffix to prototype builds and remove it for releases. - */ - public static final VERSION_SUFFIX = ' PROTOTYPE'; + /** + * A suffix to add to the game version. + * Add a suffix to prototype builds and remove it for releases. + */ + public static final VERSION_SUFFIX = ' PROTOTYPE'; - #if debug - static function get_VERSION():String - { - return 'v${Application.current.meta.get('version')} (${GIT_BRANCH} : ${GIT_HASH})' + VERSION_SUFFIX; - } - #else - static function get_VERSION():String - { - return 'v${Application.current.meta.get('version')}' + VERSION_SUFFIX; - } - #end + #if debug + static function get_VERSION():String + { + return 'v${Application.current.meta.get('version')} (${GIT_BRANCH} : ${GIT_HASH})' + VERSION_SUFFIX; + } + #else + static function get_VERSION():String + { + return 'v${Application.current.meta.get('version')}' + VERSION_SUFFIX; + } + #end - /** - * URL DATA - */ - // ============================== + /** + * URL DATA + */ + // ============================== - /** - * Link to download the game on Itch.io. - */ - public static final URL_ITCH:String = "https://ninja-muffin24.itch.io/funkin/purchase"; + /** + * Link to download the game on Itch.io. + */ + public static final URL_ITCH:String = "https://ninja-muffin24.itch.io/funkin/purchase"; - /** - * Link to the game's page on Kickstarter. - */ - public static final URL_KICKSTARTER:String = "https://www.kickstarter.com/projects/funkin/friday-night-funkin-the-full-ass-game/"; + /** + * Link to the game's page on Kickstarter. + */ + public static final URL_KICKSTARTER:String = "https://www.kickstarter.com/projects/funkin/friday-night-funkin-the-full-ass-game/"; - /** - * GIT REPO DATA - */ - // ============================== + /** + * GIT REPO DATA + */ + // ============================== - #if debug - /** - * The current Git branch. - */ - public static final GIT_BRANCH = funkin.util.macro.GitCommit.getGitBranch(); + #if debug + /** + * The current Git branch. + */ + public static final GIT_BRANCH = funkin.util.macro.GitCommit.getGitBranch(); - /** - * The current Git commit hash. - */ - public static final GIT_HASH = funkin.util.macro.GitCommit.getGitCommitHash(); - #end + /** + * The current Git commit hash. + */ + public static final GIT_HASH = funkin.util.macro.GitCommit.getGitCommitHash(); + #end - /** - * COLORS - */ - // ============================== + /** + * COLORS + */ + // ============================== - /** - * The color used by the enemy health bar. - */ - public static final COLOR_HEALTH_BAR_RED:FlxColor = 0xFFFF0000; + /** + * The color used by the enemy health bar. + */ + public static final COLOR_HEALTH_BAR_RED:FlxColor = 0xFFFF0000; - /** - * The color used by the player health bar. - */ - public static final COLOR_HEALTH_BAR_GREEN:FlxColor = 0xFF66FF33; + /** + * The color used by the player health bar. + */ + public static final COLOR_HEALTH_BAR_GREEN:FlxColor = 0xFF66FF33; - /** - * OTHER - */ - // ============================== + /** + * OTHER + */ + // ============================== - /** - * The scale factor to use when increasing the size of pixel art graphics. - */ - public static final PIXEL_ART_SCALE = 6; + /** + * The scale factor to use when increasing the size of pixel art graphics. + */ + public static final PIXEL_ART_SCALE = 6; - /** - * The BPM of the title screen and menu music. - * TODO: Move to metadata file. - */ - public static final FREAKY_MENU_BPM = 102; + /** + * The BPM of the title screen and menu music. + * TODO: Move to metadata file. + */ + public static final FREAKY_MENU_BPM = 102; - /** - * The volume at which to play the countdown before the song starts. - */ - public static final COUNTDOWN_VOLUME = 0.6; + /** + * The volume at which to play the countdown before the song starts. + */ + public static final COUNTDOWN_VOLUME = 0.6; - public static final DEFAULT_VARIATION = 'default'; - public static final DEFAULT_DIFFICULTY = 'normal'; + public static final DEFAULT_VARIATION = 'default'; + public static final DEFAULT_DIFFICULTY = 'normal'; } diff --git a/source/funkin/util/DateUtil.hx b/source/funkin/util/DateUtil.hx index 32db7804d..715371f80 100644 --- a/source/funkin/util/DateUtil.hx +++ b/source/funkin/util/DateUtil.hx @@ -2,10 +2,10 @@ package funkin.util; class DateUtil { - public static function generateTimestamp():String - { - var date = Date.now(); - return - '${date.getFullYear()}-${Std.string(date.getMonth() + 1).lpad('0', 2)}-${Std.string(date.getDate()).lpad('0', 2)}-${Std.string(date.getHours()).lpad('0', 2)}-${Std.string(date.getMinutes()).lpad('0', 2)}-${Std.string(date.getSeconds()).lpad('0', 2)}'; - } + public static function generateTimestamp():String + { + var date = Date.now(); + return + '${date.getFullYear()}-${Std.string(date.getMonth() + 1).lpad('0', 2)}-${Std.string(date.getDate()).lpad('0', 2)}-${Std.string(date.getHours()).lpad('0', 2)}-${Std.string(date.getMinutes()).lpad('0', 2)}-${Std.string(date.getSeconds()).lpad('0', 2)}'; + } } diff --git a/source/funkin/util/FileUtil.hx b/source/funkin/util/FileUtil.hx index e3dafc2cb..03b7bc8a9 100644 --- a/source/funkin/util/FileUtil.hx +++ b/source/funkin/util/FileUtil.hx @@ -13,512 +13,495 @@ import lime.utils.Resource; */ class FileUtil { - /** - * Browses for a single file, then calls `onSelect(path)` when a path chosen. - * Note that on HTML5 this will immediately fail, you should call `openFile(onOpen:Resource->Void)` instead. - * - * @param typeFilter Filters what kinds of files can be selected. - * @return Whether the file dialog was opened successfully. - */ - public static function browseForFile(?typeFilter:Array, ?onSelect:String->Void, ?onCancel:Void->Void, ?defaultPath:String, - ?dialogTitle:String):Bool - { - #if desktop - var filter = convertTypeFilter(typeFilter); + /** + * Browses for a single file, then calls `onSelect(path)` when a path chosen. + * Note that on HTML5 this will immediately fail, you should call `openFile(onOpen:Resource->Void)` instead. + * + * @param typeFilter Filters what kinds of files can be selected. + * @return Whether the file dialog was opened successfully. + */ + public static function browseForFile(?typeFilter:Array, ?onSelect:String->Void, ?onCancel:Void->Void, ?defaultPath:String, + ?dialogTitle:String):Bool + { + #if desktop + var filter = convertTypeFilter(typeFilter); - var fileDialog = new FileDialog(); - if (onSelect != null) - fileDialog.onSelect.add(onSelect); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onSelect != null) fileDialog.onSelect.add(onSelect); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.browse(OPEN, filter, defaultPath, dialogTitle); - return true; - #elseif html5 - onCancel(); - return false; - #else - onCancel(); - return false; - #end - } + fileDialog.browse(OPEN, filter, defaultPath, dialogTitle); + return true; + #elseif html5 + onCancel(); + return false; + #else + onCancel(); + return false; + #end + } - /** - * Browses for a directory, then calls `onSelect(path)` when a path chosen. - * Note that on HTML5 this will immediately fail. - * - * @param typeFilter TODO What does this do? - * @return Whether the file dialog was opened successfully. - */ - public static function browseForDirectory(?typeFilter:Array, ?onSelect:String->Void, ?onCancel:Void->Void, ?defaultPath:String, - ?dialogTitle:String):Bool - { - #if desktop - var filter = convertTypeFilter(typeFilter); + /** + * Browses for a directory, then calls `onSelect(path)` when a path chosen. + * Note that on HTML5 this will immediately fail. + * + * @param typeFilter TODO What does this do? + * @return Whether the file dialog was opened successfully. + */ + public static function browseForDirectory(?typeFilter:Array, ?onSelect:String->Void, ?onCancel:Void->Void, ?defaultPath:String, + ?dialogTitle:String):Bool + { + #if desktop + var filter = convertTypeFilter(typeFilter); - var fileDialog = new FileDialog(); - if (onSelect != null) - fileDialog.onSelect.add(onSelect); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onSelect != null) fileDialog.onSelect.add(onSelect); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.browse(OPEN_DIRECTORY, filter, defaultPath, dialogTitle); - return true; - #elseif html5 - onCancel(); - return false; - #else - onCancel(); - return false; - #end - } + fileDialog.browse(OPEN_DIRECTORY, filter, defaultPath, dialogTitle); + return true; + #elseif html5 + onCancel(); + return false; + #else + onCancel(); + return false; + #end + } - /** - * Browses for multiple file, then calls `onSelect(paths)` when a path chosen. - * Note that on HTML5 this will immediately fail. - * - * @return Whether the file dialog was opened successfully. - */ - public static function browseForMultipleFiles(?typeFilter:Array, ?onSelect:Array->Void, ?onCancel:Void->Void, ?defaultPath:String, - ?dialogTitle:String):Bool - { - #if desktop - var filter = convertTypeFilter(typeFilter); + /** + * Browses for multiple file, then calls `onSelect(paths)` when a path chosen. + * Note that on HTML5 this will immediately fail. + * + * @return Whether the file dialog was opened successfully. + */ + public static function browseForMultipleFiles(?typeFilter:Array, ?onSelect:Array->Void, ?onCancel:Void->Void, ?defaultPath:String, + ?dialogTitle:String):Bool + { + #if desktop + var filter = convertTypeFilter(typeFilter); - var fileDialog = new FileDialog(); - if (onSelect != null) - fileDialog.onSelectMultiple.add(onSelect); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onSelect != null) fileDialog.onSelectMultiple.add(onSelect); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.browse(OPEN_MULTIPLE, filter, defaultPath, dialogTitle); - return true; - #elseif html5 - onCancel(); - return false; - #else - onCancel(); - return false; - #end - } + fileDialog.browse(OPEN_MULTIPLE, filter, defaultPath, dialogTitle); + return true; + #elseif html5 + onCancel(); + return false; + #else + onCancel(); + return false; + #end + } - /** - * Browses for a file location to save to, then calls `onSelect(path)` when a path chosen. - * Note that on HTML5 you can't do much with this, you should call `saveFile(resource:haxe.io.Bytes)` instead. - * - * @param typeFilter TODO What does this do? - * @return Whether the file dialog was opened successfully. - */ - public static function browseForSaveFile(?typeFilter:Array, ?onSelect:String->Void, ?onCancel:Void->Void, ?defaultPath:String, - ?dialogTitle:String):Bool - { - #if desktop - var filter = convertTypeFilter(typeFilter); + /** + * Browses for a file location to save to, then calls `onSelect(path)` when a path chosen. + * Note that on HTML5 you can't do much with this, you should call `saveFile(resource:haxe.io.Bytes)` instead. + * + * @param typeFilter TODO What does this do? + * @return Whether the file dialog was opened successfully. + */ + public static function browseForSaveFile(?typeFilter:Array, ?onSelect:String->Void, ?onCancel:Void->Void, ?defaultPath:String, + ?dialogTitle:String):Bool + { + #if desktop + var filter = convertTypeFilter(typeFilter); - var fileDialog = new FileDialog(); - if (onSelect != null) - fileDialog.onSelect.add(onSelect); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onSelect != null) fileDialog.onSelect.add(onSelect); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.browse(SAVE, filter, defaultPath, dialogTitle); - return true; - #elseif html5 - onCancel(); - return false; - #else - onCancel(); - return false; - #end - } + fileDialog.browse(SAVE, filter, defaultPath, dialogTitle); + return true; + #elseif html5 + onCancel(); + return false; + #else + onCancel(); + return false; + #end + } - /** - * Browses for a single file location, then reads it and passes it to `onOpen(resource:haxe.io.Bytes)`. - * Works great on desktop and HTML5. - * - * @param typeFilter TODO What does this do? - * @return Whether the file dialog was opened successfully. - */ - public static function openFile(?typeFilter:Array, ?onOpen:Bytes->Void, ?onCancel:Void->Void, ?defaultPath:String, ?dialogTitle:String):Bool - { - #if desktop - var filter = convertTypeFilter(typeFilter); + /** + * Browses for a single file location, then reads it and passes it to `onOpen(resource:haxe.io.Bytes)`. + * Works great on desktop and HTML5. + * + * @param typeFilter TODO What does this do? + * @return Whether the file dialog was opened successfully. + */ + public static function openFile(?typeFilter:Array, ?onOpen:Bytes->Void, ?onCancel:Void->Void, ?defaultPath:String, ?dialogTitle:String):Bool + { + #if desktop + var filter = convertTypeFilter(typeFilter); - var fileDialog = new FileDialog(); - if (onOpen != null) - fileDialog.onOpen.add(onOpen); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onOpen != null) fileDialog.onOpen.add(onOpen); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.open(filter, defaultPath, dialogTitle); - return true; - #elseif html5 - var filter = convertTypeFilter(typeFilter); + fileDialog.open(filter, defaultPath, dialogTitle); + return true; + #elseif html5 + var filter = convertTypeFilter(typeFilter); - var onFileLoaded = function(event) - { - var loadedFileRef:FileReference = event.target; - trace('Loaded file: ' + loadedFileRef.name); - onOpen(loadedFileRef.data); - } + var onFileLoaded = function(event) + { + var loadedFileRef:FileReference = event.target; + trace('Loaded file: ' + loadedFileRef.name); + onOpen(loadedFileRef.data); + } - var onFileSelected = function(event) - { - var selectedFileRef:FileReference = event.target; - trace('Selected file: ' + selectedFileRef.name); - selectedFileRef.addEventListener(Event.COMPLETE, onFileLoaded); - selectedFileRef.load(); - } + var onFileSelected = function(event) + { + var selectedFileRef:FileReference = event.target; + trace('Selected file: ' + selectedFileRef.name); + selectedFileRef.addEventListener(Event.COMPLETE, onFileLoaded); + selectedFileRef.load(); + } - var fileRef = new FileReference(); - file.addEventListener(Event.SELECT, onFileSelected); - file.open(filter, defaultPath, dialogTitle); - #else - onCancel(); - return false; - #end - } + var fileRef = new FileReference(); + file.addEventListener(Event.SELECT, onFileSelected); + file.open(filter, defaultPath, dialogTitle); + #else + onCancel(); + return false; + #end + } - /** - * Browses for a single file location, then writes the provided `haxe.io.Bytes` data and calls `onSave(path)` when done. - * Works great on desktop and HTML5. - * - * @param typeFilter TODO What does this do? - * @return Whether the file dialog was opened successfully. - */ - public static function saveFile(data:Bytes, ?onSave:String->Void, ?onCancel:Void->Void, ?defaultFileName:String, ?dialogTitle:String):Bool - { - #if desktop - var filter = defaultFileName != null ? Path.extension(defaultFileName) : null; + /** + * Browses for a single file location, then writes the provided `haxe.io.Bytes` data and calls `onSave(path)` when done. + * Works great on desktop and HTML5. + * + * @param typeFilter TODO What does this do? + * @return Whether the file dialog was opened successfully. + */ + public static function saveFile(data:Bytes, ?onSave:String->Void, ?onCancel:Void->Void, ?defaultFileName:String, ?dialogTitle:String):Bool + { + #if desktop + var filter = defaultFileName != null ? Path.extension(defaultFileName) : null; - var fileDialog = new FileDialog(); - if (onSave != null) - fileDialog.onSelect.add(onSave); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onSave != null) fileDialog.onSelect.add(onSave); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.save(data, filter, defaultFileName, dialogTitle); - return true; - #elseif html5 - var filter = defaultFileName != null ? Path.extension(defaultFileName) : null; + fileDialog.save(data, filter, defaultFileName, dialogTitle); + return true; + #elseif html5 + var filter = defaultFileName != null ? Path.extension(defaultFileName) : null; - var fileDialog = new FileDialog(); - if (onSave != null) - fileDialog.onSave.add(onSave); - if (onCancel != null) - fileDialog.onCancel.add(onCancel); + var fileDialog = new FileDialog(); + if (onSave != null) fileDialog.onSave.add(onSave); + if (onCancel != null) fileDialog.onCancel.add(onCancel); - fileDialog.save(data, filter, defaultFileName, dialogTitle); - #else - onCancel(); - return false; - #end - } + fileDialog.save(data, filter, defaultFileName, dialogTitle); + #else + onCancel(); + return false; + #end + } - /** - * Prompts the user to save multiple files. - * On desktop, this will prompt the user for a directory, then write all of the files to there. - * On HTML5, this will zip the files up and prompt the user to save that. - * - * @param typeFilter TODO What does this do? - * @return Whether the file dialog was opened successfully. - */ - public static function saveMultipleFiles(resources:Array, ?onSaveAll:Array->Void, ?onCancel:Void->Void, ?defaultPath:String, - ?force:Bool = false):Bool - { - #if desktop - // Prompt the user for a directory, then write all of the files to there. - var onSelectDir = function(targetPath:String) - { - var paths:Array = []; - for (resource in resources) - { - var filePath = haxe.io.Path.join([targetPath, resource.fileName]); - try - { - if (resource.data == null) - { - trace('WARNING: File $filePath has no data or content. Skipping.'); - continue; - } - else - { - writeBytesToPath(filePath, resource.data, force ? Force : Skip); - } - } - catch (e:Dynamic) - { - trace('Failed to write file (probably already exists): $filePath' + filePath); - continue; - } - paths.push(filePath); - } - onSaveAll(paths); - } + /** + * Prompts the user to save multiple files. + * On desktop, this will prompt the user for a directory, then write all of the files to there. + * On HTML5, this will zip the files up and prompt the user to save that. + * + * @param typeFilter TODO What does this do? + * @return Whether the file dialog was opened successfully. + */ + public static function saveMultipleFiles(resources:Array, ?onSaveAll:Array->Void, ?onCancel:Void->Void, ?defaultPath:String, + ?force:Bool = false):Bool + { + #if desktop + // Prompt the user for a directory, then write all of the files to there. + var onSelectDir = function(targetPath:String) + { + var paths:Array = []; + for (resource in resources) + { + var filePath = haxe.io.Path.join([targetPath, resource.fileName]); + try + { + if (resource.data == null) + { + trace('WARNING: File $filePath has no data or content. Skipping.'); + continue; + } + else + { + writeBytesToPath(filePath, resource.data, force ? Force : Skip); + } + } + catch (e:Dynamic) + { + trace('Failed to write file (probably already exists): $filePath' + filePath); + continue; + } + paths.push(filePath); + } + onSaveAll(paths); + } - browseForDirectory(null, onSelectDir, onCancel, defaultPath, "Choose directory to save all files to..."); + browseForDirectory(null, onSelectDir, onCancel, defaultPath, "Choose directory to save all files to..."); - return true; - #elseif html5 - saveFilesAsZIP(resources, onSaveAll, onCancel, defaultPath, force); + return true; + #elseif html5 + saveFilesAsZIP(resources, onSaveAll, onCancel, defaultPath, force); - return true; - #else - onCancel(); - return false; - #end - } + return true; + #else + onCancel(); + return false; + #end + } - /** - * Takes an array of file entries and prompts the user to save them as a ZIP file. - */ - public static function saveFilesAsZIP(resources:Array, ?onSave:Array->Void, ?onCancel:Void->Void, ?defaultPath:String, - ?force:Bool = false):Bool - { - // Create a ZIP file. - var zipBytes = createZIPFromEntries(resources); + /** + * Takes an array of file entries and prompts the user to save them as a ZIP file. + */ + public static function saveFilesAsZIP(resources:Array, ?onSave:Array->Void, ?onCancel:Void->Void, ?defaultPath:String, + ?force:Bool = false):Bool + { + // Create a ZIP file. + var zipBytes = createZIPFromEntries(resources); - var onSave = function(path:String) - { - onSave([path]); - }; + var onSave = function(path:String) + { + onSave([path]); + }; - // Prompt the user to save the ZIP file. - saveFile(zipBytes, onSave, onCancel, defaultPath, "Save files as ZIP..."); + // Prompt the user to save the ZIP file. + saveFile(zipBytes, onSave, onCancel, defaultPath, "Save files as ZIP..."); - return true; - } + return true; + } - /** - * Takes an array of file entries and forcibly writes a ZIP to the given path. - * Only works on desktop, because HTML5 doesn't allow you to write files to arbitrary paths. - * Use `saveFilesAsZIP` instead. - * @param force Whether to force overwrite an existing file. - */ - public static function saveFilesAsZIPToPath(resources:Array, path:String, ?force:Bool = false):Bool - { - #if desktop - // Create a ZIP file. - var zipBytes = createZIPFromEntries(resources); + /** + * Takes an array of file entries and forcibly writes a ZIP to the given path. + * Only works on desktop, because HTML5 doesn't allow you to write files to arbitrary paths. + * Use `saveFilesAsZIP` instead. + * @param force Whether to force overwrite an existing file. + */ + public static function saveFilesAsZIPToPath(resources:Array, path:String, ?force:Bool = false):Bool + { + #if desktop + // Create a ZIP file. + var zipBytes = createZIPFromEntries(resources); - // Write the ZIP. - writeBytesToPath(path, zipBytes, force ? Force : Skip); + // Write the ZIP. + writeBytesToPath(path, zipBytes, force ? Force : Skip); - return true; - #else - return false; - #end - } + return true; + #else + return false; + #end + } - /** - * Write string file contents directly to a given path. - * Only works on desktop. - * - * @param mode Whether to Force, Skip, or Ask to overwrite an existing file. - */ - public static function writeStringToPath(path:String, data:String, mode:FileWriteMode = Skip) - { - #if sys - createDirIfNotExists(Path.directory(path)); + /** + * Write string file contents directly to a given path. + * Only works on desktop. + * + * @param mode Whether to Force, Skip, or Ask to overwrite an existing file. + */ + public static function writeStringToPath(path:String, data:String, mode:FileWriteMode = Skip) + { + #if sys + createDirIfNotExists(Path.directory(path)); - switch (mode) - { - case Force: - sys.io.File.saveContent(path, data); - case Skip: - if (!sys.FileSystem.exists(path)) - { - sys.io.File.saveContent(path, data); - } - else - { - throw 'File already exists: $path'; - } - case Ask: - if (sys.FileSystem.exists(path)) - { - // TODO: We don't have the technology to use native popups yet. - } - else - { - sys.io.File.saveContent(path, data); - } - } - #else - throw 'Direct file writing by path not supported on this platform.'; - #end - } + switch (mode) + { + case Force: + sys.io.File.saveContent(path, data); + case Skip: + if (!sys.FileSystem.exists(path)) + { + sys.io.File.saveContent(path, data); + } + else + { + throw 'File already exists: $path'; + } + case Ask: + if (sys.FileSystem.exists(path)) + { + // TODO: We don't have the technology to use native popups yet. + } + else + { + sys.io.File.saveContent(path, data); + } + } + #else + throw 'Direct file writing by path not supported on this platform.'; + #end + } - /** - * Write byte file contents directly to a given path. - * Only works on desktop. - * - * @param mode Whether to Force, Skip, or Ask to overwrite an existing file. - */ - public static function writeBytesToPath(path:String, data:Bytes, mode:FileWriteMode = Skip) - { - #if sys - createDirIfNotExists(Path.directory(path)); + /** + * Write byte file contents directly to a given path. + * Only works on desktop. + * + * @param mode Whether to Force, Skip, or Ask to overwrite an existing file. + */ + public static function writeBytesToPath(path:String, data:Bytes, mode:FileWriteMode = Skip) + { + #if sys + createDirIfNotExists(Path.directory(path)); - switch (mode) - { - case Force: - sys.io.File.saveBytes(path, data); - case Skip: - if (!sys.FileSystem.exists(path)) - { - sys.io.File.saveBytes(path, data); - } - else - { - throw 'File already exists: $path'; - } - case Ask: - if (sys.FileSystem.exists(path)) - { - // TODO: We don't have the technology to use native popups yet. - } - else - { - sys.io.File.saveBytes(path, data); - } - } - #else - throw 'Direct file writing by path not supported on this platform.'; - #end - } + switch (mode) + { + case Force: + sys.io.File.saveBytes(path, data); + case Skip: + if (!sys.FileSystem.exists(path)) + { + sys.io.File.saveBytes(path, data); + } + else + { + throw 'File already exists: $path'; + } + case Ask: + if (sys.FileSystem.exists(path)) + { + // TODO: We don't have the technology to use native popups yet. + } + else + { + sys.io.File.saveBytes(path, data); + } + } + #else + throw 'Direct file writing by path not supported on this platform.'; + #end + } - /** - * Write string file contents directly to the end of a file at the given path. - * Only works on desktop. - */ - public static function appendStringToPath(path:String, data:String) - { - sys.io.File.append(path, false).writeString(data); - } + /** + * Write string file contents directly to the end of a file at the given path. + * Only works on desktop. + */ + public static function appendStringToPath(path:String, data:String) + { + sys.io.File.append(path, false).writeString(data); + } - /** - * Create a directory if it doesn't already exist. - * Only works on desktop. - */ - public static function createDirIfNotExists(dir:String) - { - #if sys - if (!sys.FileSystem.exists(dir)) - { - sys.FileSystem.createDirectory(dir); - } - #end - } + /** + * Create a directory if it doesn't already exist. + * Only works on desktop. + */ + public static function createDirIfNotExists(dir:String) + { + #if sys + if (!sys.FileSystem.exists(dir)) + { + sys.FileSystem.createDirectory(dir); + } + #end + } - static var tempDir:String = null; - static final TEMP_ENV_VARS:Array = ['TEMP', 'TMPDIR', 'TEMPDIR', 'TMP']; + static var tempDir:String = null; + static final TEMP_ENV_VARS:Array = ['TEMP', 'TMPDIR', 'TEMPDIR', 'TMP']; - /** - * Get the path to a temporary directory we can use for writing files. - * Only works on desktop. - */ - public static function getTempDir():String - { - if (tempDir != null) - return tempDir; + /** + * Get the path to a temporary directory we can use for writing files. + * Only works on desktop. + */ + public static function getTempDir():String + { + if (tempDir != null) return tempDir; - #if sys - #if windows - var path:String = null; + #if sys + #if windows + var path:String = null; - for (envName in TEMP_ENV_VARS) - { - path = Sys.getEnv(envName); + for (envName in TEMP_ENV_VARS) + { + path = Sys.getEnv(envName); - if (path == "") - path = null; - if (path != null) - break; - } + if (path == "") path = null; + if (path != null) break; + } - return tempDir = Path.join([path, 'funkin/']); - #else - return tempDir = '/tmp/funkin/'; - #end - #else - return null; - #end - } + return tempDir = Path.join([path, 'funkin/']); + #else + return tempDir = '/tmp/funkin/'; + #end + #else + return null; + #end + } - /** - * Create a Bytes object containing a ZIP file, containing the provided entries. - * - * @param entries The entries to add to the ZIP file. - * @return The ZIP file as a Bytes object. - */ - public static function createZIPFromEntries(entries:Array):Bytes - { - var o = new haxe.io.BytesOutput(); + /** + * Create a Bytes object containing a ZIP file, containing the provided entries. + * + * @param entries The entries to add to the ZIP file. + * @return The ZIP file as a Bytes object. + */ + public static function createZIPFromEntries(entries:Array):Bytes + { + var o = new haxe.io.BytesOutput(); - var zipWriter = new haxe.zip.Writer(o); - zipWriter.write(entries.list()); + var zipWriter = new haxe.zip.Writer(o); + zipWriter.write(entries.list()); - return o.getBytes(); - } + return o.getBytes(); + } - /** - * Create a ZIP file entry from a file name and its string contents. - * - * @param name The name of the file. You can use slashes to create subdirectories. - * @param content The string contents of the file. - * @return The resulting entry. - */ - public static function makeZIPEntry(name:String, content:String):Entry - { - var data = haxe.io.Bytes.ofString(content, UTF8); + /** + * Create a ZIP file entry from a file name and its string contents. + * + * @param name The name of the file. You can use slashes to create subdirectories. + * @param content The string contents of the file. + * @return The resulting entry. + */ + public static function makeZIPEntry(name:String, content:String):Entry + { + var data = haxe.io.Bytes.ofString(content, UTF8); - return { - fileName: name, - fileSize: data.length, + return { + fileName: name, + fileSize: data.length, - data: data, - dataSize: data.length, + data: data, + dataSize: data.length, - compressed: false, + compressed: false, - fileTime: Date.now(), - crc32: null, - extraFields: null, - }; - } + fileTime: Date.now(), + crc32: null, + extraFields: null, + }; + } - static function convertTypeFilter(typeFilter:Array):String - { - var filter = null; - if (typeFilter != null) - { - var filters = []; - for (type in typeFilter) - { - filters.push(StringTools.replace(StringTools.replace(type.extension, "*.", ""), ";", ",")); - } - filter = filters.join(";"); - } + static function convertTypeFilter(typeFilter:Array):String + { + var filter = null; + if (typeFilter != null) + { + var filters = []; + for (type in typeFilter) + { + filters.push(StringTools.replace(StringTools.replace(type.extension, "*.", ""), ";", ",")); + } + filter = filters.join(";"); + } - return filter; - } + return filter; + } } enum FileWriteMode { - /** - * Forcibly overwrite the file if it already exists. - */ - Force; + /** + * Forcibly overwrite the file if it already exists. + */ + Force; - /** - * Ask the user if they want to overwrite the file if it already exists. - */ - Ask; + /** + * Ask the user if they want to overwrite the file if it already exists. + */ + Ask; - /** - * Skip the file if it already exists. - */ - Skip; + /** + * Skip the file if it already exists. + */ + Skip; } diff --git a/source/funkin/util/SaveDataUtil.hx b/source/funkin/util/SaveDataUtil.hx index 457fd2f0d..202536aad 100644 --- a/source/funkin/util/SaveDataUtil.hx +++ b/source/funkin/util/SaveDataUtil.hx @@ -1,2 +1 @@ package funkin.util; - diff --git a/source/funkin/util/SerializerUtil.hx b/source/funkin/util/SerializerUtil.hx index 12597aebc..b478f9e98 100644 --- a/source/funkin/util/SerializerUtil.hx +++ b/source/funkin/util/SerializerUtil.hx @@ -5,54 +5,51 @@ import thx.semver.Version; class SerializerUtil { - static final INDENT_CHAR = "\t"; + static final INDENT_CHAR = "\t"; - /** - * Convert a Haxe object to a JSON string. - **/ - public static function toJSON(input:Dynamic, ?pretty:Bool = true):String - { - return Json.stringify(input, replacer, pretty ? INDENT_CHAR : null); - } + /** + * Convert a Haxe object to a JSON string. + **/ + public static function toJSON(input:Dynamic, ?pretty:Bool = true):String + { + return Json.stringify(input, replacer, pretty ? INDENT_CHAR : null); + } - /** - * Convert a JSON string to a Haxe object of the chosen type. - */ - public static function fromJSONTyped(input:String, type:Class):T - { - return cast Json.parse(input); - } + /** + * Convert a JSON string to a Haxe object of the chosen type. + */ + public static function fromJSONTyped(input:String, type:Class):T + { + return cast Json.parse(input); + } - /** - * Convert a JSON string to a Haxe object. - */ - public static function fromJSON(input:String):Dynamic - { - return Json.parse(input); - } + /** + * Convert a JSON string to a Haxe object. + */ + public static function fromJSON(input:String):Dynamic + { + return Json.parse(input); + } - /** - * Customize how certain types are serialized when converting to JSON. - */ - static function replacer(key:String, value:Dynamic):Dynamic - { - // Hacky because you can't use `isOfType` on a struct. - if (key == "version") - { - if (Std.isOfType(value, String)) - return value; + /** + * Customize how certain types are serialized when converting to JSON. + */ + static function replacer(key:String, value:Dynamic):Dynamic + { + // Hacky because you can't use `isOfType` on a struct. + if (key == "version") + { + if (Std.isOfType(value, String)) return value; - // Stringify Version objects. - var valueVersion:thx.semver.Version = cast value; - var result = '${valueVersion.major}.${valueVersion.minor}.${valueVersion.patch}'; - if (valueVersion.hasPre) - result += '-${valueVersion.pre}'; - if (valueVersion.hasBuild) - result += '+${valueVersion.build}'; - return result; - } + // Stringify Version objects. + var valueVersion:thx.semver.Version = cast value; + var result = '${valueVersion.major}.${valueVersion.minor}.${valueVersion.patch}'; + if (valueVersion.hasPre) result += '-${valueVersion.pre}'; + if (valueVersion.hasBuild) result += '+${valueVersion.build}'; + return result; + } - // Else, return the value as-is. - return value; - } + // Else, return the value as-is. + return value; + } } diff --git a/source/funkin/util/SortUtil.hx b/source/funkin/util/SortUtil.hx index 6e92d6b68..e10f6dd55 100644 --- a/source/funkin/util/SortUtil.hx +++ b/source/funkin/util/SortUtil.hx @@ -7,24 +7,23 @@ import flixel.util.FlxSort; class SortUtil { - /** - * You can use this function in FlxTypedGroup.sort() to sort FlxObjects by their z-index values. - * The value defaults to 0, but by assigning it you can easily rearrange objects as desired. - */ - public static inline function byZIndex(Order:Int, Obj1:FlxBasic, Obj2:FlxBasic):Int - { - if (Obj1 == null || Obj2 == null) - return 0; - return FlxSort.byValues(Order, Obj1.zIndex, Obj2.zIndex); - } + /** + * You can use this function in FlxTypedGroup.sort() to sort FlxObjects by their z-index values. + * The value defaults to 0, but by assigning it you can easily rearrange objects as desired. + */ + public static inline function byZIndex(Order:Int, Obj1:FlxBasic, Obj2:FlxBasic):Int + { + if (Obj1 == null || Obj2 == null) return 0; + return FlxSort.byValues(Order, Obj1.zIndex, Obj2.zIndex); + } - /** - * Given two Notes, returns 1 or -1 based on whether `a` or `b` has an earlier strumtime. - * - * @param order Either `FlxSort.ASCENDING` or `FlxSort.DESCENDING` - */ - public static inline function byStrumtime(order:Int, a:Note, b:Note) - { - return FlxSort.byValues(order, a.data.strumTime, b.data.strumTime); - } + /** + * Given two Notes, returns 1 or -1 based on whether `a` or `b` has an earlier strumtime. + * + * @param order Either `FlxSort.ASCENDING` or `FlxSort.DESCENDING` + */ + public static inline function byStrumtime(order:Int, a:Note, b:Note) + { + return FlxSort.byValues(order, a.data.strumTime, b.data.strumTime); + } } diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index 57e1f80ed..08cde69a6 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -10,22 +10,22 @@ import thx.semver.VersionRule; */ class VersionUtil { - /** - * Checks that a given verison number satisisfies a given version rule. - * Version rule can be complex, e.g. "1.0.x" or ">=1.0.0,<1.1.0", or anything NPM supports. - */ - public static function validateVersion(version:String, versionRule:String):Bool - { - try - { - var v:Version = version; // Perform a cast. - var vr:VersionRule = versionRule; // Perform a cast. - return v.satisfies(vr); - } - catch (e) - { - trace('[VERSIONUTIL] Invalid semantic version: ${version}'); - return false; - } - } + /** + * Checks that a given verison number satisisfies a given version rule. + * Version rule can be complex, e.g. "1.0.x" or ">=1.0.0,<1.1.0", or anything NPM supports. + */ + public static function validateVersion(version:String, versionRule:String):Bool + { + try + { + var v:Version = version; // Perform a cast. + var vr:VersionRule = versionRule; // Perform a cast. + return v.satisfies(vr); + } + catch (e) + { + trace('[VERSIONUTIL] Invalid semantic version: ${version}'); + return false; + } + } } diff --git a/source/funkin/util/assets/DataAssets.hx b/source/funkin/util/assets/DataAssets.hx index afa041d5b..ee75dd207 100644 --- a/source/funkin/util/assets/DataAssets.hx +++ b/source/funkin/util/assets/DataAssets.hx @@ -2,30 +2,29 @@ package funkin.util.assets; class DataAssets { - static function buildDataPath(path:String):String - { - return 'assets/data/${path}'; - } + static function buildDataPath(path:String):String + { + return 'assets/data/${path}'; + } - public static function listDataFilesInPath(path:String, ?suffix:String = '.json'):Array - { - var textAssets = openfl.utils.Assets.list(); - var queryPath = buildDataPath(path); + public static function listDataFilesInPath(path:String, ?suffix:String = '.json'):Array + { + var textAssets = openfl.utils.Assets.list(); + var queryPath = buildDataPath(path); - var results:Array = []; - for (textPath in textAssets) - { - if (textPath.startsWith(queryPath) && textPath.endsWith(suffix)) - { - var pathNoSuffix = textPath.substring(0, textPath.length - suffix.length); - var pathNoPrefix = pathNoSuffix.substring(queryPath.length); + var results:Array = []; + for (textPath in textAssets) + { + if (textPath.startsWith(queryPath) && textPath.endsWith(suffix)) + { + var pathNoSuffix = textPath.substring(0, textPath.length - suffix.length); + var pathNoPrefix = pathNoSuffix.substring(queryPath.length); - // No duplicates! Why does this happen? - if (!results.contains(pathNoPrefix)) - results.push(pathNoPrefix); - } - } + // No duplicates! Why does this happen? + if (!results.contains(pathNoPrefix)) results.push(pathNoPrefix); + } + } - return results; - } + return results; + } } diff --git a/source/funkin/util/assets/FlxAnimationUtil.hx b/source/funkin/util/assets/FlxAnimationUtil.hx index 52b25999c..bab1e090b 100644 --- a/source/funkin/util/assets/FlxAnimationUtil.hx +++ b/source/funkin/util/assets/FlxAnimationUtil.hx @@ -6,54 +6,54 @@ import funkin.play.AnimationData; class FlxAnimationUtil { - /** - * Properly adds an animation to a sprite based on JSON data. - */ - public static function addAtlasAnimation(target:FlxSprite, anim:AnimationData) - { - var frameRate = anim.frameRate == null ? 24 : anim.frameRate; - var looped = anim.looped == null ? false : anim.looped; - var flipX = anim.flipX == null ? false : anim.flipX; - var flipY = anim.flipY == null ? false : anim.flipY; + /** + * Properly adds an animation to a sprite based on JSON data. + */ + public static function addAtlasAnimation(target:FlxSprite, anim:AnimationData) + { + var frameRate = anim.frameRate == null ? 24 : anim.frameRate; + var looped = anim.looped == null ? false : anim.looped; + var flipX = anim.flipX == null ? false : anim.flipX; + var flipY = anim.flipY == null ? false : anim.flipY; - if (anim.frameIndices != null && anim.frameIndices.length > 0) - { - // trace('addByIndices(${anim.name}, ${anim.prefix}, ${anim.frameIndices}, ${frameRate}, ${looped}, ${flipX}, ${flipY})'); - target.animation.addByIndices(anim.name, anim.prefix, anim.frameIndices, "", frameRate, looped, flipX, flipY); - // trace('RESULT:${target.animation.getAnimationList()}'); - } - else - { - // trace('addByPrefix(${anim.name}, ${anim.prefix}, ${frameRate}, ${looped}, ${flipX}, ${flipY})'); - target.animation.addByPrefix(anim.name, anim.prefix, frameRate, looped, flipX, flipY); - // trace('RESULT:${target.animation.getAnimationList()}'); - } - } + if (anim.frameIndices != null && anim.frameIndices.length > 0) + { + // trace('addByIndices(${anim.name}, ${anim.prefix}, ${anim.frameIndices}, ${frameRate}, ${looped}, ${flipX}, ${flipY})'); + target.animation.addByIndices(anim.name, anim.prefix, anim.frameIndices, "", frameRate, looped, flipX, flipY); + // trace('RESULT:${target.animation.getAnimationList()}'); + } + else + { + // trace('addByPrefix(${anim.name}, ${anim.prefix}, ${frameRate}, ${looped}, ${flipX}, ${flipY})'); + target.animation.addByPrefix(anim.name, anim.prefix, frameRate, looped, flipX, flipY); + // trace('RESULT:${target.animation.getAnimationList()}'); + } + } - /** - * Properly adds multiple animations to a sprite based on JSON data. - */ - public static function addAtlasAnimations(target:FlxSprite, animations:Array) - { - for (anim in animations) - { - addAtlasAnimation(target, anim); - } - } + /** + * Properly adds multiple animations to a sprite based on JSON data. + */ + public static function addAtlasAnimations(target:FlxSprite, animations:Array) + { + for (anim in animations) + { + addAtlasAnimation(target, anim); + } + } - public static function combineFramesCollections(a:FlxFramesCollection, b:FlxFramesCollection):FlxFramesCollection - { - var result:FlxFramesCollection = new FlxFramesCollection(null, ATLAS, null); + public static function combineFramesCollections(a:FlxFramesCollection, b:FlxFramesCollection):FlxFramesCollection + { + var result:FlxFramesCollection = new FlxFramesCollection(null, ATLAS, null); - for (frame in a.frames) - { - result.pushFrame(frame); - } - for (frame in b.frames) - { - result.pushFrame(frame); - } + for (frame in a.frames) + { + result.pushFrame(frame); + } + for (frame in b.frames) + { + result.pushFrame(frame); + } - return result; - } + return result; + } } diff --git a/source/funkin/util/macro/ClassMacro.hx b/source/funkin/util/macro/ClassMacro.hx index 4589eaac8..591a5f0e1 100644 --- a/source/funkin/util/macro/ClassMacro.hx +++ b/source/funkin/util/macro/ClassMacro.hx @@ -55,8 +55,7 @@ class ClassMacro var targetClass:ClassType = MacroUtil.getClassTypeFromExpr(targetClassExpr); var targetClassPath:String = null; - if (targetClass != null) - targetClassPath = targetClass.pack.join('.') + '.' + targetClass.name; + if (targetClass != null) targetClassPath = targetClass.pack.join('.') + '.' + targetClass.name; var request:String = 'extend~${targetClassPath}'; @@ -125,12 +124,10 @@ class ClassMacro { var compiledClassList:ClassType = MacroUtil.getClassType("funkin.util.macro.CompiledClassList"); - if (compiledClassList == null) - throw "Could not find CompiledClassList class."; + if (compiledClassList == null) throw "Could not find CompiledClassList class."; // Reset outdated metadata. - if (compiledClassList.meta.has('classLists')) - compiledClassList.meta.remove('classLists'); + if (compiledClassList.meta.has('classLists')) compiledClassList.meta.remove('classLists'); var classLists:Array = []; // Generate classLists. diff --git a/source/funkin/util/macro/CompiledClassList.hx b/source/funkin/util/macro/CompiledClassList.hx index d7a50668e..68415b1be 100644 --- a/source/funkin/util/macro/CompiledClassList.hx +++ b/source/funkin/util/macro/CompiledClassList.hx @@ -50,8 +50,7 @@ class CompiledClassList public static function get(request:String):List> { - if (classLists == null) - init(); + if (classLists == null) init(); if (!classLists.exists(request)) { diff --git a/source/funkin/util/macro/FlxMacro.hx b/source/funkin/util/macro/FlxMacro.hx index 8e75dc1ec..313b2561a 100644 --- a/source/funkin/util/macro/FlxMacro.hx +++ b/source/funkin/util/macro/FlxMacro.hx @@ -3,33 +3,33 @@ package funkin.util.macro; #if macro class FlxMacro { - /** - * A macro to be called targeting the `FlxBasic` class. - * @return An array of fields that the class contains. - */ - public static macro function buildFlxBasic():Array - { - var pos:haxe.macro.Expr.Position = haxe.macro.Context.currentPos(); - // The FlxBasic class. We can add new properties to this class. - var cls:haxe.macro.Type.ClassType = haxe.macro.Context.getLocalClass().get(); - // The fields of the FlxClass. - var fields:Array = haxe.macro.Context.getBuildFields(); + /** + * A macro to be called targeting the `FlxBasic` class. + * @return An array of fields that the class contains. + */ + public static macro function buildFlxBasic():Array + { + var pos:haxe.macro.Expr.Position = haxe.macro.Context.currentPos(); + // The FlxBasic class. We can add new properties to this class. + var cls:haxe.macro.Type.ClassType = haxe.macro.Context.getLocalClass().get(); + // The fields of the FlxClass. + var fields:Array = haxe.macro.Context.getBuildFields(); - // haxe.macro.Context.info('[INFO] ${cls.name}: Adding zIndex attribute...', pos); + // haxe.macro.Context.info('[INFO] ${cls.name}: Adding zIndex attribute...', pos); - // Here, we add the zIndex attribute to all FlxBasic objects. - // This has no functional code tied to it, but it can be used as a target value - // for the FlxTypedGroup.sort method, to rearrange the objects in the scene. - fields = fields.concat([ - { - name: "zIndex", // Field name. - access: [haxe.macro.Expr.Access.APublic], // Access level - kind: haxe.macro.Expr.FieldType.FVar(macro:Int, macro $v{0}), // Variable type and default value - pos: pos, // The field's position in code. - } - ]); + // Here, we add the zIndex attribute to all FlxBasic objects. + // This has no functional code tied to it, but it can be used as a target value + // for the FlxTypedGroup.sort method, to rearrange the objects in the scene. + fields = fields.concat([ + { + name: "zIndex", // Field name. + access: [haxe.macro.Expr.Access.APublic], // Access level + kind: haxe.macro.Expr.FieldType.FVar(macro:Int, macro $v{0}), // Variable type and default value + pos: pos, // The field's position in code. + } + ]); - return fields; - } + return fields; + } } #end diff --git a/source/funkin/util/macro/MacroUtil.hx b/source/funkin/util/macro/MacroUtil.hx index 1edf07e8f..e0f06c866 100644 --- a/source/funkin/util/macro/MacroUtil.hx +++ b/source/funkin/util/macro/MacroUtil.hx @@ -16,8 +16,7 @@ class MacroUtil public static macro function getDefine(key:String, defaultValue:String = null):haxe.macro.Expr { var value = haxe.macro.Context.definedValue(key); - if (value == null) - value = defaultValue; + if (value == null) value = defaultValue; return macro $v{value}; } @@ -135,8 +134,7 @@ class MacroUtil */ public static function isSubclassOf(classType:ClassType, superClass:ClassType):Bool { - if (areClassesEqual(classType, superClass)) - return true; + if (areClassesEqual(classType, superClass)) return true; if (classType.superClass != null) { diff --git a/source/funkin/util/tools/IteratorTools.hx b/source/funkin/util/tools/IteratorTools.hx index 0b25a7df5..261f101e4 100644 --- a/source/funkin/util/tools/IteratorTools.hx +++ b/source/funkin/util/tools/IteratorTools.hx @@ -9,8 +9,8 @@ package funkin.util.tools; */ class IteratorTools { - public static function array(iterator:Iterator):Array - { - return [for (i in iterator) i]; - } + public static function array(iterator:Iterator):Array + { + return [for (i in iterator) i]; + } } diff --git a/source/funkin/util/tools/StringTools.hx b/source/funkin/util/tools/StringTools.hx index 0c6937e94..7ecddd0d9 100644 --- a/source/funkin/util/tools/StringTools.hx +++ b/source/funkin/util/tools/StringTools.hx @@ -5,55 +5,57 @@ package funkin.util.tools; */ class StringTools { - /** - * Converts a string to title case. For example, "hello world" becomes "Hello World". + /** + * Converts a string to title case. For example, "hello world" becomes "Hello World". * - * @param value The string to convert. - * @return The converted string. - */ - public static function toTitleCase(value:String):String - { - var words:Array = value.split(" "); - var result:String = ""; - for (i in 0...words.length) - { - var word:String = words[i]; - result += word.charAt(0).toUpperCase() + word.substr(1).toLowerCase(); - if (i < words.length - 1) - { - result += " "; - } - } - return result; - } - - /** - * Converts a string to lower kebab case. For example, "Hello World" becomes "hello-world". - * - * @param value The string to convert. - * @return The converted string. - */ - public static function toLowerKebabCase(value:String):String { - return value.toLowerCase().replace(' ', "-"); - } - - /** - * Converts a string to upper kebab case, aka screaming kebab case. For example, "Hello World" becomes "HELLO-WORLD". - * - * @param value The string to convert. - * @return The converted string. - */ - public static function toUpperKebabCase(value:String):String { - return value.toUpperCase().replace(' ', "-"); - } - - /** - * Parses the string data as JSON and returns the resulting object. - * - * @return The parsed object. - */ - public static function parseJSON(value:String):Dynamic + * @param value The string to convert. + * @return The converted string. + */ + public static function toTitleCase(value:String):String + { + var words:Array = value.split(" "); + var result:String = ""; + for (i in 0...words.length) { - return SerializerUtil.fromJSON(value); + var word:String = words[i]; + result += word.charAt(0).toUpperCase() + word.substr(1).toLowerCase(); + if (i < words.length - 1) + { + result += " "; + } } + return result; + } + + /** + * Converts a string to lower kebab case. For example, "Hello World" becomes "hello-world". + * + * @param value The string to convert. + * @return The converted string. + */ + public static function toLowerKebabCase(value:String):String + { + return value.toLowerCase().replace(' ', "-"); + } + + /** + * Converts a string to upper kebab case, aka screaming kebab case. For example, "Hello World" becomes "HELLO-WORLD". + * + * @param value The string to convert. + * @return The converted string. + */ + public static function toUpperKebabCase(value:String):String + { + return value.toUpperCase().replace(' ', "-"); + } + + /** + * Parses the string data as JSON and returns the resulting object. + * + * @return The parsed object. + */ + public static function parseJSON(value:String):Dynamic + { + return SerializerUtil.fromJSON(value); + } }