From 1adef489952aaab9c6787a9d0a69eb47b4bed862 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 16 Apr 2024 22:12:07 -0400 Subject: [PATCH 1/2] some cleanins with letter sorts --- checkstyle.json | 3 +- source/funkin/ui/freeplay/FreeplayState.hx | 79 ++++++------ source/funkin/ui/freeplay/LetterSort.hx | 134 +++++++++------------ 3 files changed, 103 insertions(+), 113 deletions(-) diff --git a/checkstyle.json b/checkstyle.json index 5300d94ad..3da04230f 100644 --- a/checkstyle.json +++ b/checkstyle.json @@ -550,7 +550,8 @@ { "props": { "policy": "onlySingle", - "allowException": true + "allowException": true, + "severity": "IGNORE" }, "type": "StringLiteral" }, diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 2fc1128cd..e71681874 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -539,47 +539,14 @@ class FreeplayState extends MusicBeatSubState * Given the current filter, rebuild the current song list. * * @param filterStuff A filter to apply to the song list (regex, startswith, all, favorite) - * @param force + * @param force Whether the capsules should "jump" back in or not using their animation * @param onlyIfChanged Only apply the filter if the song list has changed */ public function generateSongList(filterStuff:Null, force:Bool = false, onlyIfChanged:Bool = true):Void { var tempSongs:Array = songs; - if (filterStuff != null) - { - switch (filterStuff.filterType) - { - case REGEXP: - // filterStuff.filterData has a string with the first letter of the sorting range, and the second one - // this creates a filter to return all the songs that start with a letter between those two - - // if filterData looks like "A-C", the regex should look something like this: ^[A-C].* - // to get every song that starts between A and C - var filterRegexp:EReg = new EReg('^[' + filterStuff.filterData + '].*', 'i'); - tempSongs = tempSongs.filter(str -> { - if (str == null) return true; // Random - return filterRegexp.match(str.songName); - }); - - case STARTSWITH: - // extra note: this is essentially a "search" - - tempSongs = tempSongs.filter(str -> { - if (str == null) return true; // Random - return str.songName.toLowerCase().startsWith(filterStuff.filterData); - }); - case ALL: - // no filter! - case FAVORITE: - tempSongs = tempSongs.filter(str -> { - if (str == null) return true; // Random - return str.isFav; - }); - default: - // return all on default - } - } + if (filterStuff != null) tempSongs = sortSongs(tempSongs, filterStuff); // Filter further by current selected difficulty. if (currentDifficulty != null) @@ -657,6 +624,48 @@ class FreeplayState extends MusicBeatSubState changeDiff(); } + /** + * Filters an array of songs based on a filter + * @param songsToFilter What data to use when filtering + * @param songFilter The filter to apply + * @return Array + */ + public function sortSongs(songsToFilter:Array, songFilter:SongFilter):Array + { + switch (songFilter.filterType) + { + case REGEXP: + // filterStuff.filterData has a string with the first letter of the sorting range, and the second one + // this creates a filter to return all the songs that start with a letter between those two + + // if filterData looks like "A-C", the regex should look something like this: ^[A-C].* + // to get every song that starts between A and C + var filterRegexp:EReg = new EReg('^[' + songFilter.filterData + '].*', 'i'); + songsToFilter = songsToFilter.filter(str -> { + if (str == null) return true; // Random + return filterRegexp.match(str.songName); + }); + + case STARTSWITH: + // extra note: this is essentially a "search" + + songsToFilter = songsToFilter.filter(str -> { + if (str == null) return true; // Random + return str.songName.toLowerCase().startsWith(songFilter.filterData); + }); + case ALL: + // no filter! + case FAVORITE: + songsToFilter = songsToFilter.filter(str -> { + if (str == null) return true; // Random + return str.isFav; + }); + default: + // return all on default + } + return songsToFilter; + } + var touchY:Float = 0; var touchX:Float = 0; var dxTouch:Float = 0; diff --git a/source/funkin/ui/freeplay/LetterSort.hx b/source/funkin/ui/freeplay/LetterSort.hx index 8017abe33..e813c9198 100644 --- a/source/funkin/ui/freeplay/LetterSort.hx +++ b/source/funkin/ui/freeplay/LetterSort.hx @@ -39,7 +39,6 @@ class LetterSort extends FlxTypedSpriteGroup var letter:FreeplayLetter = new FreeplayLetter(i * 80, 0, i); letter.x += 50; letter.y += 50; - letter.ogY = y; // letter.visible = false; add(letter); @@ -82,6 +81,26 @@ class LetterSort extends FlxTypedSpriteGroup } public function changeSelection(diff:Int = 0):Void + { + doLetterChangeAnims(diff); + + var multiPosOrNeg:Float = diff > 0 ? 1 : -1; + + // if we're moving left (diff < 0), we want control of the right arrow, and vice versa + var arrowToMove:FlxSprite = diff < 0 ? leftArrow : rightArrow; + arrowToMove.offset.x = 3 * multiPosOrNeg; + + new FlxTimer().start(2 / 24, function(_) { + arrowToMove.offset.x = 0; + }); + } + + /** + * Buncho timers and stuff to move the letters and seperators + * Seperated out so we can call it again on letters with songs within them + * @param diff + */ + function doLetterChangeAnims(diff:Int):Void { var ezTimer:Int->FlxSprite->Float->Void = function(frameNum:Int, spr:FlxSprite, offsetNum:Float) { new FlxTimer().start(frameNum / 24, function(_) { @@ -91,84 +110,39 @@ class LetterSort extends FlxTypedSpriteGroup var positions:Array = [-10, -22, 2, 0]; - if (diff < 0) + // if we're moving left, we want to move the positions the same amount, but negative direciton + var multiPosOrNeg:Float = diff > 0 ? 1 : -1; + + for (sep in grpSeperators) { - for (sep in grpSeperators) - { - ezTimer(0, sep, positions[0]); - ezTimer(1, sep, positions[1]); - ezTimer(2, sep, positions[2]); - ezTimer(3, sep, positions[3]); - } - - for (index => letter in letters) - { - letter.offset.x = positions[0]; - - new FlxTimer().start(1 / 24, function(_) { - letter.offset.x = positions[1]; - if (index == 0) letter.visible = false; - }); - - new FlxTimer().start(2 / 24, function(_) { - letter.offset.x = positions[2]; - if (index == 0.) letter.visible = true; - }); - - if (index == 2) - { - ezTimer(3, letter, 0); - // letter.offset.x = 0; - continue; - } - - ezTimer(3, letter, positions[3]); - } - - leftArrow.offset.x = 3; - new FlxTimer().start(2 / 24, function(_) { - leftArrow.offset.x = 0; - }); + ezTimer(0, sep, positions[0] * multiPosOrNeg); + ezTimer(1, sep, positions[1] * multiPosOrNeg); + ezTimer(2, sep, positions[2] * multiPosOrNeg); + ezTimer(3, sep, positions[3] * multiPosOrNeg); } - else if (diff > 0) + + for (index => letter in letters) { - for (sep in grpSeperators) - { - ezTimer(0, sep, -positions[0]); - ezTimer(1, sep, -positions[1]); - ezTimer(2, sep, -positions[2]); - ezTimer(3, sep, -positions[3]); - } - // same timing and functions and shit as the left one... except to the right!! + letter.offset.x = positions[0] * multiPosOrNeg; - for (index => letter in letters) - { - letter.offset.x = -positions[0]; - - new FlxTimer().start(1 / 24, function(_) { - letter.offset.x = -positions[1]; - if (index == 0) letter.visible = false; - }); - - new FlxTimer().start(2 / 24, function(_) { - letter.offset.x = -positions[2]; - if (index == 0) letter.visible = true; - }); - - if (index == 2) - { - ezTimer(3, letter, 0); - // letter.offset.x = 0; - continue; - } - - ezTimer(3, letter, -positions[3]); - } - - rightArrow.offset.x = -3; - new FlxTimer().start(2 / 24, function(_) { - rightArrow.offset.x = 0; + new FlxTimer().start(1 / 24, function(_) { + letter.offset.x = positions[1] * multiPosOrNeg; + if (index == 0) letter.visible = false; }); + + new FlxTimer().start(2 / 24, function(_) { + letter.offset.x = positions[2] * multiPosOrNeg; + if (index == 0.) letter.visible = true; + }); + + if (index == 2) + { + ezTimer(3, letter, 0); + // letter.offset.x = 0; + continue; + } + + ezTimer(3, letter, positions[3] * multiPosOrNeg); } curSelection += diff; @@ -182,6 +156,9 @@ class LetterSort extends FlxTypedSpriteGroup } } +/** + * The actual FlxAtlasSprite for the letters, with their animation code stuff and regex stuff + */ class FreeplayLetter extends FlxAtlasSprite { /** @@ -201,8 +178,6 @@ class FreeplayLetter extends FlxAtlasSprite */ public var curLetter:Int = 0; - public var ogY:Float = 0; - public function new(x:Float, y:Float, ?letterInd:Int) { super(x, y, Paths.animateAtlas("freeplay/sortedLetters")); @@ -231,6 +206,11 @@ class FreeplayLetter extends FlxAtlasSprite } } + /** + * Changes the letter graphic/anim, used in the LetterSort class above + * @param diff -1 or 1, to go left or right in the animation array + * @param curSelection what the current letter selection is, to play the bouncing anim if it matches the current letter + */ public function changeLetter(diff:Int = 0, ?curSelection:Int):Void { curLetter += diff; @@ -238,7 +218,7 @@ class FreeplayLetter extends FlxAtlasSprite if (curLetter < 0) curLetter = regexLetters.length - 1; if (curLetter >= regexLetters.length) curLetter = 0; - var animName:String = animLetters[curLetter] + " move"; + var animName:String = animLetters[curLetter] + ' move'; switch (animLetters[curLetter]) { From c3e777154e6d3655317b06c0261eefec7ca6c47c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 16 Apr 2024 21:11:56 -0400 Subject: [PATCH 2/2] fix letter sort regex, and tiny LetterSort.hx cleanin --- source/funkin/ui/freeplay/FreeplayState.hx | 6 ++ source/funkin/ui/freeplay/LetterSort.hx | 72 ++++++++++++---------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 3ac441212..2fc1128cd 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -553,12 +553,18 @@ class FreeplayState extends MusicBeatSubState case REGEXP: // filterStuff.filterData has a string with the first letter of the sorting range, and the second one // this creates a filter to return all the songs that start with a letter between those two + + // if filterData looks like "A-C", the regex should look something like this: ^[A-C].* + // to get every song that starts between A and C var filterRegexp:EReg = new EReg('^[' + filterStuff.filterData + '].*', 'i'); tempSongs = tempSongs.filter(str -> { if (str == null) return true; // Random return filterRegexp.match(str.songName); }); + case STARTSWITH: + // extra note: this is essentially a "search" + tempSongs = tempSongs.filter(str -> { if (str == null) return true; // Random return str.songName.toLowerCase().startsWith(filterStuff.filterData); diff --git a/source/funkin/ui/freeplay/LetterSort.hx b/source/funkin/ui/freeplay/LetterSort.hx index 7e71b6aa1..8017abe33 100644 --- a/source/funkin/ui/freeplay/LetterSort.hx +++ b/source/funkin/ui/freeplay/LetterSort.hx @@ -54,7 +54,7 @@ class LetterSort extends FlxTypedSpriteGroup // don't put the last seperator if (i == 4) continue; - var sep:FlxSprite = new FlxSprite((i * 80) + 55, 20).loadGraphic(Paths.image("freeplay/seperator")); + var sep:FlxSprite = new FlxSprite((i * 80) + 60, 20).loadGraphic(Paths.image("freeplay/seperator")); // sep.animation.play("seperator"); sep.color = letter.color.getDarkened(darkness); add(sep); @@ -70,7 +70,7 @@ class LetterSort extends FlxTypedSpriteGroup changeSelection(0); } - override function update(elapsed:Float) + override function update(elapsed:Float):Void { super.update(elapsed); @@ -81,7 +81,7 @@ class LetterSort extends FlxTypedSpriteGroup } } - public function changeSelection(diff:Int = 0) + public function changeSelection(diff:Int = 0):Void { var ezTimer:Int->FlxSprite->Float->Void = function(frameNum:Int, spr:FlxSprite, offsetNum:Float) { new FlxTimer().start(frameNum / 24, function(_) { @@ -172,20 +172,33 @@ class LetterSort extends FlxTypedSpriteGroup } curSelection += diff; - if (curSelection < 0) curSelection = letters[0].arr.length - 1; - if (curSelection >= letters[0].arr.length) curSelection = 0; + if (curSelection < 0) curSelection = letters[0].regexLetters.length - 1; + if (curSelection >= letters[0].regexLetters.length) curSelection = 0; for (letter in letters) letter.changeLetter(diff, curSelection); - if (changeSelectionCallback != null) changeSelectionCallback(letters[2].arr[letters[2].curLetter]); // bullshit and long lol! + if (changeSelectionCallback != null) changeSelectionCallback(letters[2].regexLetters[letters[2].curLetter]); // bullshit and long lol! } } class FreeplayLetter extends FlxAtlasSprite { - public var arr:Array = []; + /** + * A preformatted array of letter strings, for use when doing regex + * ex: ['A-B', 'C-D', 'E-H', 'I-L' ...] + */ + public var regexLetters:Array = []; + /** + * A preformatted array of the letters, for use when accessing symbol animation info + * ex: ['AB', 'CD', 'EH', 'IL' ...] + */ + public var animLetters:Array = []; + + /** + * The current letter in the regexLetters array this FreeplayLetter is on + */ public var curLetter:Int = 0; public var ogY:Float = 0; @@ -193,46 +206,43 @@ class FreeplayLetter extends FlxAtlasSprite public function new(x:Float, y:Float, ?letterInd:Int) { super(x, y, Paths.animateAtlas("freeplay/sortedLetters")); - // frames = Paths.getSparrowAtlas("freeplay/letterStuff"); - // this.anim.play("AB"); - // trace(this.anim.symbolDictionary); - var alphabet:String = "AB-CD-EH-I L-MN-OR-s-t-UZ"; - arr = alphabet.split("-"); - arr.insert(0, "ALL"); - arr.insert(0, "fav"); - arr.insert(0, "#"); + // this is used for the regex + // /^[OR].*/gi doesn't work for showing the song Pico, so now it's + // /^[O-R].*/gi ant it works for displaying Pico + // https://regex101.com/r/bWFPfS/1 + // we split by underscores, simply for nice lil convinience + var alphabet:String = 'A-B_C-D_E-H_I-L_M-N_O-R_S_T_U-Z'; + regexLetters = alphabet.split('_'); + regexLetters.insert(0, 'ALL'); + regexLetters.insert(0, 'fav'); + regexLetters.insert(0, '#'); - // trace(arr); - - // for (str in arr) - // { - // animation.addByPrefix(str, str + " "); // string followed by a space! intentional! - // } - - // animation.addByPrefix("arrow", "mini arrow"); - // animation.addByPrefix("seperator", "seperator"); + // the symbols from flash don't have dashes, so we clean this up for use with animations + // (we don't need to re-export, rule of thumb is to accomodate files named in flash from dave + // until we get him programming classes (and since i cant find the .fla file....)) + animLetters = regexLetters.map(animLetter -> animLetter.replace('-', '')); if (letterInd != null) { - this.anim.play(arr[letterInd] + " move"); + this.anim.play(animLetters[letterInd] + " move"); this.anim.pause(); curLetter = letterInd; } } - public function changeLetter(diff:Int = 0, ?curSelection:Int) + public function changeLetter(diff:Int = 0, ?curSelection:Int):Void { curLetter += diff; - if (curLetter < 0) curLetter = arr.length - 1; - if (curLetter >= arr.length) curLetter = 0; + if (curLetter < 0) curLetter = regexLetters.length - 1; + if (curLetter >= regexLetters.length) curLetter = 0; - var animName:String = arr[curLetter] + " move"; + var animName:String = animLetters[curLetter] + " move"; - switch (arr[curLetter]) + switch (animLetters[curLetter]) { - case "I L": + case "IL": animName = "IL move"; case "s": animName = "S move";