diff --git a/assets/data/alphabet.xml b/assets/data/alphabet.xml index fc1cbbe4..a1ee94b3 100644 --- a/assets/data/alphabet.xml +++ b/assets/data/alphabet.xml @@ -58,6 +58,8 @@ + + diff --git a/buildnumber.txt b/buildnumber.txt index 6c8526a8..a99c3866 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -370 \ No newline at end of file +380 \ No newline at end of file diff --git a/source/funkin/menus/MainMenuState.hx b/source/funkin/menus/MainMenuState.hx index 3228c41b..6b155b22 100644 --- a/source/funkin/menus/MainMenuState.hx +++ b/source/funkin/menus/MainMenuState.hx @@ -175,7 +175,7 @@ class MainMenuState extends MusicBeatState trace("Freeplay Menu Selected"); case 'options': - FlxG.switchState(new OptionsMenu()); + FlxG.switchState(new OptionsMenu(false)); } }); }); diff --git a/source/funkin/options/KeybindsOptions.hx b/source/funkin/options/KeybindsOptions.hx index 8c5809b4..1b821d1d 100644 --- a/source/funkin/options/KeybindsOptions.hx +++ b/source/funkin/options/KeybindsOptions.hx @@ -163,7 +163,7 @@ class KeybindsOptions extends MusicBeatState { var minH = FlxG.height / 2; var maxH = alphabets.members[alphabets.length-1].y + alphabets.members[alphabets.length-1].height - (FlxG.height / 2); if (minH < maxH) - camFollow.setPosition(FlxG.width / 2, FlxMath.bound(alphabet.y + (alphabet.height / 2) + 75, minH, maxH)); + camFollow.setPosition(FlxG.width / 2, FlxMath.bound(alphabet.y + (alphabet.height / 2) - (35), minH, maxH)); else camFollow.setPosition(FlxG.width / 2, FlxG.height / 2); } @@ -175,6 +175,9 @@ class KeybindSetting extends FlxTypedSpriteGroup { public var bind1:Alphabet; public var bind2:Alphabet; public var icon:FlxSprite; + + public var option1:Null; + public var option2:Null; public function new(x:Float, y:Float, name:String, value:String, ?sparrowIcon:String, ?sparrowAnim:String) { super(); title = new Alphabet(0, 0, name, true); @@ -182,22 +185,23 @@ class KeybindSetting extends FlxTypedSpriteGroup { add(title); + var controlArrayP1:Array = Reflect.field(Options, 'P1_${value}'); + var controlArrayP2:Array = Reflect.field(Options, 'P2_${value}'); + + option1 = controlArrayP1[0]; + option2 = controlArrayP2[0]; + for(i in 1...3) { var b = null; if (i == 1) b = bind1 = new Alphabet(0, 0, "", false); else b = bind2 = new Alphabet(0, 0, "", false); - // TODO: Fix Alphabet!! - var controlArrayP1:Array = Reflect.field(Options, 'P1_${value}'); - var controlArrayP2:Array = Reflect.field(Options, 'P2_${value}'); - @:privateAccess - b._finalText = '${(i == 1 ? controlArrayP1 : controlArrayP2)[0]}'; - b.addText(); b.setPosition(FlxG.width * (0.25 * (i+1)) - x, -60); add(b); } + updateText(); if (sparrowIcon != null) { icon = new FlxSprite(); @@ -214,4 +218,14 @@ class KeybindSetting extends FlxTypedSpriteGroup { setPosition(x, y); } + + public function updateText() { + // TODO: Fix Alphabet!! + @:privateAccess + bind1._finalText = '${CoolUtil.keyToString(option1)}'; + @:privateAccess + bind2._finalText = '${CoolUtil.keyToString(option2)}'; + bind1.addText(); + bind2.addText(); + } } \ No newline at end of file diff --git a/source/funkin/options/OptionsMenu.hx b/source/funkin/options/OptionsMenu.hx index 35116c54..fc811102 100644 --- a/source/funkin/options/OptionsMenu.hx +++ b/source/funkin/options/OptionsMenu.hx @@ -7,8 +7,10 @@ import flixel.math.FlxMath; import flixel.FlxSprite; import flixel.FlxG; import flixel.effects.FlxFlicker; +import funkin.menus.MainMenuState; class OptionsMenu extends MusicBeatState { + public static var fromPlayState:Bool = false; public var options = [ { name: 'Controls', @@ -25,6 +27,11 @@ class OptionsMenu extends MusicBeatState { public var curSelected:Int = -1; public var canSelect:Bool = true; public var alphabets:FlxTypedGroup; + + public function new(?fromPlayState:Bool) { + super(); + if (fromPlayState != null) OptionsMenu.fromPlayState = fromPlayState; + } public override function create() { var bg:FlxSprite = new FlxSprite(-80).loadGraphic(Paths.image('menuBGBlue')); bg.scrollFactor.set(); @@ -57,6 +64,11 @@ class OptionsMenu extends MusicBeatState { FlxTransitionableState.skipNextTransOut = true; FlxG.switchState(Type.createInstance(options[curSelected].state, [])); }); + } else if (controls.BACK) { + if (fromPlayState) + FlxG.switchState(new PlayState()); + else + FlxG.switchState(new MainMenuState()); } } diff --git a/source/funkin/system/CoolUtil.hx b/source/funkin/system/CoolUtil.hx index 87ddd248..d9911951 100644 --- a/source/funkin/system/CoolUtil.hx +++ b/source/funkin/system/CoolUtil.hx @@ -1,5 +1,6 @@ package funkin.system; +import flixel.input.keyboard.FlxKey; import lime.utils.Assets; import flixel.animation.FlxAnimation; import flixel.util.FlxColor; @@ -83,6 +84,11 @@ class CoolUtil return null; } + /** + * Plays a specified Menu SFX. + * @param menuSFX Menu SFX to play + * @param volume At which volume it should play + */ public static function playMenuSFX(menuSFX:Int = 0, volume:Float = 1) { FlxG.sound.play(Paths.sound(switch(menuSFX) { case 1: 'confirmMenu'; @@ -112,4 +118,41 @@ class CoolUtil anim1.frames = anim2.frames; anim2.frames = old; } + + public static function keyToString(key:Null):String { + return switch(key) { + case null | 0 | NONE: "---"; + case LEFT: "←"; + case DOWN: "↓"; + case UP: "↑"; + case RIGHT: "→"; + case ESCAPE: "ESC"; + case BACKSPACE: "[←]"; + 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 NUMPADPLUS: "#+"; + case NUMPADMINUS: "#-"; + case NUMPADPERIOD: "#."; + 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 PERIOD: "."; + default: key.toString(); + } + } } \ No newline at end of file diff --git a/source/funkin/ui/Alphabet.hx b/source/funkin/ui/Alphabet.hx index 235b9db0..f0a79ed1 100644 --- a/source/funkin/ui/Alphabet.hx +++ b/source/funkin/ui/Alphabet.hx @@ -1,5 +1,10 @@ package funkin.ui; +import openfl.utils.Assets; +import openfl.utils.AssetLibrary; +import haxe.xml.Access; +import funkin.mods.LimeLibrarySymbol; +import funkin.mods.ModsAssetLibrary; import flixel.FlxG; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; @@ -40,6 +45,28 @@ class Alphabet extends FlxSpriteGroup var isBold:Bool = false; + public function refreshAlphabetXML(path:String) { + trace("Needs refresh!!"); + AlphaCharacter.__alphaPath = path; + try { + var xml = new Access(Xml.parse(Assets.getText(path)).firstElement()); + AlphaCharacter.boldAnims = []; + AlphaCharacter.letterAnims = []; + + for(e in xml.elements) { + var bold = e.name == "bold"; + var list = bold ? AlphaCharacter.boldAnims : AlphaCharacter.letterAnims; + for(e in e.nodes.letter) { + if (!e.has.char || !e.has.anim) continue; + var name = e.att.char; + var anim = e.att.anim; + list[name] = anim; + } + } + } catch(e) { + trace(e.details()); + } + } public function new(x:Float, y:Float, text:String = "", ?bold:Bool = false, typed:Bool = false) { super(x, y); @@ -48,6 +75,28 @@ class Alphabet extends FlxSpriteGroup this.text = text; isBold = bold; + var alphabetPath = Paths.xml("alphabet"); + if (alphabetPath != AlphaCharacter.__alphaPath) { + refreshAlphabetXML(alphabetPath); + } else { + var libThing = new LimeLibrarySymbol(alphabetPath); + if (libThing.library is AssetLibrary) { + var library = cast(libThing.library, AssetLibrary); + @:privateAccess + if (library.__proxy != null && library.__proxy is AssetLibrary) { + @:privateAccess + library = cast(library.__proxy, AssetLibrary); + } + if (library is ModsAssetLibrary) { + var modLib = cast(library, ModsAssetLibrary); + @:privateAccess + if (!modLib.__isCacheValid(modLib.cachedBytes, libThing.symbolName)) { + refreshAlphabetXML(alphabetPath); + } + } + } + } + if (text != "") { if (typed) @@ -68,45 +117,27 @@ class Alphabet extends FlxSpriteGroup var xPos:Float = 0; for (character in splitWords) { - // if (character.fastCodeAt() == " ") - // { - // } - 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 - x; + + if (lastWasSpace) { - if (lastSprite != null) - { - xPos = lastSprite.x + lastSprite.width; - } - - if (lastWasSpace) - { - xPos += 40; - lastWasSpace = false; - } - - // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); - var letter:AlphaCharacter = new AlphaCharacter(xPos, 0); - - if (isBold) - letter.createBold(character); - else - { - letter.createLetter(character); - } - - add(letter); - - lastSprite = letter; + xPos += 40; + lastWasSpace = false; } - // loopNum += 1; + var letter:AlphaCharacter = new AlphaCharacter(xPos, 0); + if (isBold) + letter.createBold(character); + else + letter.createLetter(character); + + add(letter); + + lastSprite = letter; } } @@ -145,72 +176,72 @@ class Alphabet extends FlxSpriteGroup 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; @@ -234,11 +265,9 @@ class Alphabet extends FlxSpriteGroup class AlphaCharacter extends FlxSprite { - public static var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; - - public static var numbers:String = "1234567890"; - - public static var symbols:String = "|~#$%()*+-:;<=>@[]^_.,'!?"; + @:dox(hide) @:noCompletion public static var __alphaPath:String = null; + public static var boldAnims:Map = []; + public static var letterAnims:Map = []; public var row:Int = 0; @@ -253,25 +282,26 @@ class AlphaCharacter extends FlxSprite public function createBold(letter:String) { - animation.addByPrefix(letter, letter.toUpperCase() + " bold", 24); + letter = letter.toUpperCase(); + if (boldAnims[letter] == null) { + visible = false; + return; + } + animation.addByPrefix(letter, boldAnims[letter], 24); animation.play(letter); updateHitbox(); } public function createLetter(letter:String):Void { - var letterCase:String = "lowercase"; - if (letter.toLowerCase() != letter) - { - letterCase = 'capital'; - } - - animation.addByPrefix(letter, letter + " " + letterCase, 24); + if (letterAnims[letter] == null) { + visible = false; + return; + } + animation.addByPrefix(letter, letterAnims[letter], 24); animation.play(letter); updateHitbox(); - FlxG.log.add('the row' + row); - y = (110 - height); y += row * 60; }