From 1e65cacb0efaa92991fd2290fe6f30b58e38ba7d Mon Sep 17 00:00:00 2001
From: FabsTheFabs <flamingkitty24@gmail.com>
Date: Fri, 31 May 2024 10:39:06 +0100
Subject: [PATCH 1/7] fix funkinsound compile error

---
 source/funkin/audio/FunkinSound.hx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx
index b94c6008c..cf4a71189 100644
--- a/source/funkin/audio/FunkinSound.hx
+++ b/source/funkin/audio/FunkinSound.hx
@@ -359,7 +359,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
 
     if (shouldLoadPartial)
     {
-      var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0, params.partialParams?.end ?? 1, params?.startingVolume ?? 1.0,
+      var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0.0, params.partialParams?.end ?? 1.0, params?.startingVolume ?? 1.0,
         params.loop ?? true, false, false, params.onComplete);
 
       if (music != null)

From 28444fd47814a4c3833310743d7d5ce1944ec9e9 Mon Sep 17 00:00:00 2001
From: FabsTheFabs <flamingkitty24@gmail.com>
Date: Fri, 31 May 2024 10:39:53 +0100
Subject: [PATCH 2/7] rank tweaks, favourite changes + rank anim fixes

---
 source/funkin/play/ResultState.hx          |  61 +++++++++--
 source/funkin/play/scoring/Scoring.hx      |  58 ++++++++++-
 source/funkin/ui/credits/CreditsState.hx   |   3 +-
 source/funkin/ui/freeplay/AlbumRoll.hx     |   2 +-
 source/funkin/ui/freeplay/FreeplayState.hx | 112 +++++++++++++++++----
 source/funkin/ui/freeplay/SongMenuItem.hx  |   7 +-
 source/funkin/ui/mainmenu/MainMenuState.hx |  13 ++-
 7 files changed, 220 insertions(+), 36 deletions(-)

diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx
index 79880038d..1ad19b41e 100644
--- a/source/funkin/play/ResultState.hx
+++ b/source/funkin/play/ResultState.hx
@@ -59,6 +59,8 @@ class ResultState extends MusicBeatSubState
   var gfGood:Null<FlxSprite> = null;
   var bfShit:Null<FlxAtlasSprite> = null;
 
+  var rankBg:FunkinSprite;
+
   public function new(params:ResultsStateParams)
   {
     super();
@@ -95,6 +97,8 @@ class ResultState extends MusicBeatSubState
     highscoreNew = new FlxSprite(310, 570);
 
     score = new ResultScore(35, 305, 10, params.scoreData.score);
+
+    rankBg = new FunkinSprite(0, 0);
   }
 
   override function create():Void
@@ -356,6 +360,12 @@ class ResultState extends MusicBeatSubState
       }
     });
 
+    rankBg.makeSolidColor(FlxG.width, FlxG.height, 0xFF000000);
+    rankBg.zIndex = 99999;
+    add(rankBg);
+
+   rankBg.alpha = 0;
+
     refresh();
 
     super.create();
@@ -654,18 +664,47 @@ class ResultState extends MusicBeatSubState
       }
       else
       {
-        openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> FreeplayState.build(
-          {
+        var rigged:Bool = true;
+        if (rank > Scoring.calculateRank(params?.prevScoreData))
+        //if (rigged)
+        {
+          trace('THE RANK IS Higher.....');
+
+          FlxTween.tween(rankBg, {alpha: 1}, 0.5,
             {
-              fromResults:
-                {
-                  oldRank: Scoring.calculateRank(params?.prevScoreData),
-                  newRank: rank,
-                  songId: params.songId,
-                  difficultyId: params.difficultyId
-                }
-            }
-          }, sticker)));
+              ease: FlxEase.expoOut,
+              onComplete: function(_) {
+                FlxG.switchState(FreeplayState.build(
+                  {
+                    {
+                      fromResults:
+                        {
+                          oldRank: Scoring.calculateRank(params?.prevScoreData),
+                          newRank: rank,
+                          songId: params.songId,
+                          difficultyId: params.difficultyId
+                        }
+                    }
+                  }));
+              }
+            });
+        }
+        else
+        {
+          trace('rank is lower...... and/or equal');
+          openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> FreeplayState.build(
+            {
+              {
+                fromResults:
+                  {
+                    oldRank: null,
+                    newRank: rank,
+                    songId: params.songId,
+                    difficultyId: params.difficultyId
+                  }
+              }
+            }, sticker)));
+        }
       }
     }
 
diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx
index 6155ec879..f941f3f01 100644
--- a/source/funkin/play/scoring/Scoring.hx
+++ b/source/funkin/play/scoring/Scoring.hx
@@ -349,7 +349,7 @@ class Scoring
 
   public static function calculateRank(scoreData:Null<SaveScoreData>):Null<ScoringRank>
   {
-    if (scoreData == null) return null;
+    if (scoreData?.tallies.totalNotes == 0 || scoreData == null) return null;
 
     // Perfect (Platinum) is a Sick Full Clear
     var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes;
@@ -394,6 +394,62 @@ enum abstract ScoringRank(String)
   var GOOD;
   var SHIT;
 
+  @:op(A > B) static function compare(a:Null<ScoringRank>, b:Null<ScoringRank>):Bool
+  {
+    if (a != null && b == null) return true;
+    if (a == null || b == null) return false;
+
+    var temp1:Int = 0;
+    var temp2:Int = 0;
+
+    // temp 1
+    switch (a)
+    {
+      case PERFECT_GOLD:
+        temp1 = 5;
+      case PERFECT:
+        temp1 = 4;
+      case EXCELLENT:
+        temp1 = 3;
+      case GREAT:
+        temp1 = 2;
+      case GOOD:
+        temp1 = 1;
+      case SHIT:
+        temp1 = 0;
+      default:
+        temp1 = -1;
+    }
+
+    // temp 2
+    switch (b)
+    {
+      case PERFECT_GOLD:
+        temp2 = 5;
+      case PERFECT:
+        temp2 = 4;
+      case EXCELLENT:
+        temp2 = 3;
+      case GREAT:
+        temp2 = 2;
+      case GOOD:
+        temp2 = 1;
+      case SHIT:
+        temp2 = 0;
+      default:
+        temp2 = -1;
+    }
+
+    if (temp1 > temp2)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
   /**
    * Delay in seconds
    */
diff --git a/source/funkin/ui/credits/CreditsState.hx b/source/funkin/ui/credits/CreditsState.hx
index 6be1fecf7..44769e9b3 100644
--- a/source/funkin/ui/credits/CreditsState.hx
+++ b/source/funkin/ui/credits/CreditsState.hx
@@ -4,6 +4,7 @@ import flixel.text.FlxText;
 import flixel.util.FlxColor;
 import funkin.audio.FunkinSound;
 import flixel.FlxSprite;
+import funkin.ui.mainmenu.MainMenuState;
 import flixel.group.FlxSpriteGroup;
 
 /**
@@ -199,7 +200,7 @@ class CreditsState extends MusicBeatState
 
   function exit():Void
   {
-    FlxG.switchState(funkin.ui.mainmenu.MainMenuState.new);
+    FlxG.switchState(() -> new MainMenuState());
   }
 
   public override function destroy():Void
diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx
index 50f4a432c..20cd91379 100644
--- a/source/funkin/ui/freeplay/AlbumRoll.hx
+++ b/source/funkin/ui/freeplay/AlbumRoll.hx
@@ -131,7 +131,7 @@ class AlbumRoll extends FlxSpriteGroup
 
     if (exitMovers == null) return;
 
-    exitMovers.set([newAlbumArt],
+    exitMovers.set([newAlbumArt, difficultyStars],
       {
         x: FlxG.width,
         speed: 0.4,
diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index 192c6e3ce..186c84c33 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -193,12 +193,18 @@ class FreeplayState extends MusicBeatSubState
 
   var fromResultsParams:Null<FromResultsParams> = null;
 
+  var prepForNewRank:Bool = false;
+
   public function new(?params:FreeplayStateParams, ?stickers:StickerSubState)
   {
     currentCharacter = params?.character ?? Constants.DEFAULT_CHARACTER;
 
     fromResultsParams = params?.fromResults;
 
+    if(fromResultsParams?.oldRank != null){
+      prepForNewRank = true;
+    }
+
     if (stickers != null)
     {
       stickerSubState = stickers;
@@ -235,11 +241,14 @@ class FreeplayState extends MusicBeatSubState
     isDebug = true;
     #end
 
-    FunkinSound.playMusic('freakyMenu',
+    if (prepForNewRank == false)
+    {
+      FunkinSound.playMusic('freakyMenu',
       {
         overrideExisting: true,
         restartTrack: false
       });
+    }
 
     // Add a null entry that represents the RANDOM option
     songs.push(null);
@@ -637,7 +646,7 @@ class FreeplayState extends MusicBeatSubState
       cardGlow.visible = true;
       FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.45, {ease: FlxEase.sineOut});
 
-      if (fromResultsParams != null)
+      if (prepForNewRank == true)
       {
         rankAnimStart(fromResultsParams);
       }
@@ -667,6 +676,11 @@ class FreeplayState extends MusicBeatSubState
     FlxG.cameras.add(rankCamera, false);
     rankBg.cameras = [rankCamera];
     rankBg.alpha = 0;
+
+    if (prepForNewRank == true)
+    {
+      rankCamera.fade(0xFF000000, 0, false, null, true);
+    }
   }
 
   var currentFilter:SongFilter = null;
@@ -826,6 +840,7 @@ class FreeplayState extends MusicBeatSubState
   function rankAnimStart(fromResults:Null<FromResultsParams>):Void
   {
     busy = true;
+    // grpCapsules.members[curSelected].forcePosition();
 
     dj.fistPump();
     // rankCamera.fade(FlxColor.BLACK, 0.5, true);
@@ -833,8 +848,14 @@ class FreeplayState extends MusicBeatSubState
     FlxG.sound.music.volume = 0;
     rankBg.alpha = 1;
 
-    originalPos.x = grpCapsules.members[curSelected].x;
-    originalPos.y = grpCapsules.members[curSelected].y;
+    grpCapsules.members[curSelected].doLerp = false;
+
+    // originalPos.x = grpCapsules.members[curSelected].x;
+    // originalPos.y = grpCapsules.members[curSelected].y;
+
+    originalPos.x = 320.488;
+    originalPos.y = 235.6;
+    trace(originalPos);
 
     grpCapsules.members[curSelected].ranking.alpha = 0;
     grpCapsules.members[curSelected].blurredRanking.alpha = 0;
@@ -846,11 +867,13 @@ class FreeplayState extends MusicBeatSubState
     FlxTween.tween(funnyCam, {"zoom": 1.1}, 0.6, {ease: FlxEase.sineIn});
 
     grpCapsules.members[curSelected].cameras = [rankCamera];
-    grpCapsules.members[curSelected].targetPos.set((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2),
+    // grpCapsules.members[curSelected].targetPos.set((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2),
+    //  (FlxG.height / 2) - (grpCapsules.members[curSelected].height / 2));
+
+    grpCapsules.members[curSelected].setPosition((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2),
       (FlxG.height / 2) - (grpCapsules.members[curSelected].height / 2));
 
     new FlxTimer().start(0.5, _ -> {
-      grpCapsules.members[curSelected].doLerp = false;
       rankDisplayNew(fromResults);
     });
   }
@@ -1028,6 +1051,12 @@ class FreeplayState extends MusicBeatSubState
 
     new FlxTimer().start(2, _ -> {
       // dj.fistPump();
+      prepForNewRank = false;
+      FunkinSound.playMusic('freakyMenu',
+      {
+        overrideExisting: true,
+        restartTrack: false
+      });
       FlxG.sound.music.fadeIn(4.0, 0.0, 1.0);
     });
   }
@@ -1095,7 +1124,7 @@ class FreeplayState extends MusicBeatSubState
     }
     #end
 
-    if (FlxG.keys.justPressed.F)
+    if (FlxG.keys.justPressed.F && !busy)
     {
       var targetSong = grpCapsules.members[curSelected]?.songData;
       if (targetSong != null)
@@ -1104,24 +1133,45 @@ class FreeplayState extends MusicBeatSubState
         var isFav = targetSong.toggleFavorite();
         if (isFav)
         {
-          FlxTween.tween(grpCapsules.members[realShit], {angle: 360}, 0.4,
+          grpCapsules.members[realShit].favIcon.visible = true;
+          grpCapsules.members[realShit].favIcon.animation.play('fav');
+          FunkinSound.playOnce(Paths.sound('fav'), 1);
+          busy = true;
+
+          grpCapsules.members[realShit].doLerp = false;
+          FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y - 5}, 0.1, {ease: FlxEase.expoOut});
+
+          FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y + 5}, 0.1,
             {
-              ease: FlxEase.elasticOut,
-              onComplete: _ -> {
-                grpCapsules.members[realShit].favIcon.visible = true;
-                grpCapsules.members[realShit].favIcon.animation.play('fav');
+              ease: FlxEase.expoIn,
+              startDelay: 0.1,
+              onComplete: function(_) {
+                grpCapsules.members[realShit].doLerp = true;
+                busy = false;
               }
             });
         }
         else
         {
-          grpCapsules.members[realShit].favIcon.animation.play('fav', false, true);
-          new FlxTimer().start((1 / 24) * 14, _ -> {
+          grpCapsules.members[realShit].favIcon.animation.play('fav', true, true, 9);
+          FunkinSound.playOnce(Paths.sound('unfav'), 1);
+          new FlxTimer().start(0.2, _ -> {
             grpCapsules.members[realShit].favIcon.visible = false;
           });
-          new FlxTimer().start((1 / 24) * 24, _ -> {
-            FlxTween.tween(grpCapsules.members[realShit], {angle: 0}, 0.4, {ease: FlxEase.elasticOut});
-          });
+
+          busy = true;
+          grpCapsules.members[realShit].doLerp = false;
+          FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y + 5}, 0.1, {ease: FlxEase.expoOut});
+
+          FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y - 5}, 0.1,
+            {
+              ease: FlxEase.expoIn,
+              startDelay: 0.1,
+              onComplete: function(_) {
+                grpCapsules.members[realShit].doLerp = true;
+                busy = false;
+              }
+            });
         }
       }
     }
@@ -1325,6 +1375,24 @@ class FreeplayState extends MusicBeatSubState
 
       var longestTimer:Float = 0;
 
+      // FlxTween.color(bgDad, 0.33, 0xFFFFFFFF, 0xFF555555, {ease: FlxEase.quadOut});
+      FlxTween.color(pinkBack, 0.25, 0xFFFFD863, 0xFFFFD0D5, {ease: FlxEase.quadOut});
+
+      cardGlow.visible = true;
+      cardGlow.alpha = 1;
+      cardGlow.scale.set(1, 1);
+      FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.25, {ease: FlxEase.sineOut});
+
+      orangeBackShit.visible = false;
+      alsoOrangeLOL.visible = false;
+
+      moreWays.visible = false;
+      funnyScroll.visible = false;
+      txtNuts.visible = false;
+      funnyScroll2.visible = false;
+      moreWays2.visible = false;
+      funnyScroll3.visible = false;
+
       for (grpSpr in exitMovers.keys())
       {
         var moveData:MoveData = exitMovers.get(grpSpr);
@@ -1555,6 +1623,7 @@ class FreeplayState extends MusicBeatSubState
     FunkinSound.playOnce(Paths.sound('confirmMenu'));
     dj.confirm();
 
+    grpCapsules.members[curSelected].forcePosition();
     grpCapsules.members[curSelected].songText.flickerText();
 
     // FlxTween.color(bgDad, 0.33, 0xFFFFFFFF, 0xFF555555, {ease: FlxEase.quadOut});
@@ -1689,6 +1758,7 @@ class FreeplayState extends MusicBeatSubState
       }
       else
       {
+        if(prepForNewRank == false){
         var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : "";
         // TODO: Stream the instrumental of the selected song?
         FunkinSound.playMusic(daSongCapsule.songData.songId,
@@ -1708,6 +1778,7 @@ class FreeplayState extends MusicBeatSubState
               FlxG.sound.music.fadeIn(2, 0, 0.4);
             }
           });
+        }
       }
       grpCapsules.members[curSelected].selected = true;
     }
@@ -1719,7 +1790,12 @@ class FreeplayState extends MusicBeatSubState
    */
   public static function build(?params:FreeplayStateParams, ?stickers:StickerSubState):MusicBeatState
   {
-    var result = new MainMenuState();
+    var result:MainMenuState;
+    if(params?.fromResults.oldRank != null){
+      result = new MainMenuState(true);
+    }else{
+      result = new MainMenuState(false);
+    }
 
     result.openSubState(new FreeplayState(params, stickers));
     result.persistentUpdate = false;
diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx
index ad6ea386e..b52032bc3 100644
--- a/source/funkin/ui/freeplay/SongMenuItem.hx
+++ b/source/funkin/ui/freeplay/SongMenuItem.hx
@@ -371,7 +371,7 @@ class SongMenuItem extends FlxSpriteGroup
       switch (i)
       {
         case 0:
-          if (newRating > 10)
+          if (newRating < 10)
           {
             bigNumbers[i].digit = 0;
           }
@@ -677,7 +677,7 @@ class FreeplayRank extends FlxSprite
   {
     rank = val;
 
-    if (rank == null)
+    if (rank == null || val == null)
     {
       this.visible = false;
     }
@@ -687,6 +687,8 @@ class FreeplayRank extends FlxSprite
 
       animation.play(val.getFreeplayRankIconAsset(), true, false);
 
+      trace(val.getFreeplayRankIconAsset());
+
       centerOffsets(false);
 
       switch (val)
@@ -707,6 +709,7 @@ class FreeplayRank extends FlxSprite
         // offset.y += 5;
         default:
           centerOffsets(false);
+          this.visible = false;
       }
       updateHitbox();
     }
diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx
index 22262006a..c504b3c3e 100644
--- a/source/funkin/ui/mainmenu/MainMenuState.hx
+++ b/source/funkin/ui/mainmenu/MainMenuState.hx
@@ -42,6 +42,15 @@ class MainMenuState extends MusicBeatState
   var magenta:FlxSprite;
   var camFollow:FlxObject;
 
+  var overrideMusic:Bool = false;
+
+  public function new(?_overrideMusic:Bool = false)
+  {
+    super();
+    overrideMusic = _overrideMusic;
+
+  }
+
   override function create():Void
   {
     #if discord_rpc
@@ -54,7 +63,7 @@ class MainMenuState extends MusicBeatState
     transIn = FlxTransitionableState.defaultTransIn;
     transOut = FlxTransitionableState.defaultTransOut;
 
-    playMenuMusic();
+    if(overrideMusic == false) playMenuMusic();
 
     // We want the state to always be able to begin with being able to accept inputs and show the anims of the menu items.
     persistentUpdate = true;
@@ -163,7 +172,7 @@ class MainMenuState extends MusicBeatState
 
   function playMenuMusic():Void
   {
-    FunkinSound.playMusic('freakyMenu',
+      FunkinSound.playMusic('freakyMenu',
       {
         overrideExisting: true,
         restartTrack: false

From 5d0db60810b37e3a076e3581ed2b33416ed1050c Mon Sep 17 00:00:00 2001
From: FabsTheFabs <flamingkitty24@gmail.com>
Date: Fri, 31 May 2024 10:40:51 +0100
Subject: [PATCH 3/7] assets submod

---
 assets | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/assets b/assets
index 4bc0b35f6..d64939d86 160000
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit 4bc0b35f6c7aa22086b85b6a635c6f0511d277fe
+Subproject commit d64939d866c70a831b76ed78930782b66871dcc2

From 63bd6f2ace9c093133f1c7e1c02de60ad969aa4a Mon Sep 17 00:00:00 2001
From: FabsTheFabs <flamingkitty24@gmail.com>
Date: Sun, 2 Jun 2024 00:25:52 +0100
Subject: [PATCH 4/7] sparks nd more fixes.. i think

---
 source/funkin/play/ResultState.hx          |   9 +-
 source/funkin/ui/freeplay/FreeplayState.hx | 194 +++++++++++++++------
 source/funkin/ui/freeplay/SongMenuItem.hx  |  15 ++
 3 files changed, 164 insertions(+), 54 deletions(-)

diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx
index 1ad19b41e..d38731e14 100644
--- a/source/funkin/play/ResultState.hx
+++ b/source/funkin/play/ResultState.hx
@@ -364,7 +364,7 @@ class ResultState extends MusicBeatSubState
     rankBg.zIndex = 99999;
     add(rankBg);
 
-   rankBg.alpha = 0;
+    rankBg.alpha = 0;
 
     refresh();
 
@@ -665,8 +665,7 @@ class ResultState extends MusicBeatSubState
       else
       {
         var rigged:Bool = true;
-        if (rank > Scoring.calculateRank(params?.prevScoreData))
-        //if (rigged)
+        if (rank > Scoring.calculateRank(params?.prevScoreData)) // if (rigged)
         {
           trace('THE RANK IS Higher.....');
 
@@ -682,7 +681,8 @@ class ResultState extends MusicBeatSubState
                           oldRank: Scoring.calculateRank(params?.prevScoreData),
                           newRank: rank,
                           songId: params.songId,
-                          difficultyId: params.difficultyId
+                          difficultyId: params.difficultyId,
+                          playRankAnim: true
                         }
                     }
                   }));
@@ -698,6 +698,7 @@ class ResultState extends MusicBeatSubState
                 fromResults:
                   {
                     oldRank: null,
+                    playRankAnim: false,
                     newRank: rank,
                     songId: params.songId,
                     difficultyId: params.difficultyId
diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index 186c84c33..e1d8eb81c 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -6,6 +6,7 @@ import flixel.addons.ui.FlxInputText;
 import flixel.FlxCamera;
 import flixel.FlxSprite;
 import flixel.group.FlxGroup;
+import funkin.graphics.shaders.GaussianBlurShader;
 import flixel.group.FlxGroup.FlxTypedGroup;
 import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
 import flixel.input.touch.FlxTouch;
@@ -45,6 +46,7 @@ import funkin.util.MathUtil;
 import lime.utils.Assets;
 import flixel.tweens.misc.ShakeTween;
 import funkin.effects.IntervalShake;
+import funkin.ui.freeplay.SongMenuItem.FreeplayRank;
 
 /**
  * Parameters used to initialize the FreeplayState.
@@ -66,6 +68,11 @@ typedef FromResultsParams =
    */
   var ?oldRank:ScoringRank;
 
+  /**
+   * Whether or not to play the rank animation on returning to freeplay.
+   */
+  var playRankAnim:Bool;
+
   /**
    * The new rank the song has.
    */
@@ -201,7 +208,8 @@ class FreeplayState extends MusicBeatSubState
 
     fromResultsParams = params?.fromResults;
 
-    if(fromResultsParams?.oldRank != null){
+    if (fromResultsParams?.playRankAnim == true)
+    {
       prepForNewRank = true;
     }
 
@@ -244,10 +252,10 @@ class FreeplayState extends MusicBeatSubState
     if (prepForNewRank == false)
     {
       FunkinSound.playMusic('freakyMenu',
-      {
-        overrideExisting: true,
-        restartTrack: false
-      });
+        {
+          overrideExisting: true,
+          restartTrack: false
+        });
     }
 
     // Add a null entry that represents the RANDOM option
@@ -837,6 +845,9 @@ class FreeplayState extends MusicBeatSubState
     return songsToFilter;
   }
 
+  var sparks:FlxSprite;
+  var sparksADD:FlxSprite;
+
   function rankAnimStart(fromResults:Null<FromResultsParams>):Void
   {
     busy = true;
@@ -848,6 +859,49 @@ class FreeplayState extends MusicBeatSubState
     FlxG.sound.music.volume = 0;
     rankBg.alpha = 1;
 
+    if (fromResults?.oldRank != null)
+    {
+      grpCapsules.members[curSelected].fakeRanking.rank = fromResults.oldRank;
+      grpCapsules.members[curSelected].fakeBlurredRanking.rank = fromResults.oldRank;
+
+      sparks = new FlxSprite(0, 0);
+      sparks.frames = Paths.getSparrowAtlas('freeplay/sparks');
+      sparks.animation.addByPrefix('sparks', 'sparks', 24, false);
+      sparks.visible = false;
+      sparks.blend = BlendMode.ADD;
+      sparks.setPosition(517, 134);
+      sparks.scale.set(0.5, 0.5);
+      add(sparks);
+      sparks.cameras = [rankCamera];
+
+      sparksADD = new FlxSprite(0, 0);
+      sparksADD.visible = false;
+      sparksADD.frames = Paths.getSparrowAtlas('freeplay/sparksadd');
+      sparksADD.animation.addByPrefix('sparks add', 'sparks add', 24, false);
+      sparksADD.setPosition(498, 116);
+      sparksADD.blend = BlendMode.ADD;
+      sparksADD.scale.set(0.5, 0.5);
+      add(sparksADD);
+      sparksADD.cameras = [rankCamera];
+
+      switch (fromResults.oldRank)
+      {
+        case SHIT:
+          sparksADD.color = 0xFF6044FF;
+        case GOOD:
+          sparksADD.color = 0xFFEF8764;
+        case GREAT:
+          sparksADD.color = 0xFFEAF6FF;
+        case EXCELLENT:
+          sparksADD.color = 0xFFFDCB42;
+        case PERFECT:
+          sparksADD.color = 0xFFFF58B4;
+        case PERFECT_GOLD:
+          sparksADD.color = 0xFFFFB619;
+      }
+      // sparksADD.color = sparks.color;
+    }
+
     grpCapsules.members[curSelected].doLerp = false;
 
     // originalPos.x = grpCapsules.members[curSelected].x;
@@ -857,8 +911,8 @@ class FreeplayState extends MusicBeatSubState
     originalPos.y = 235.6;
     trace(originalPos);
 
-    grpCapsules.members[curSelected].ranking.alpha = 0;
-    grpCapsules.members[curSelected].blurredRanking.alpha = 0;
+    grpCapsules.members[curSelected].ranking.visible = false;
+    grpCapsules.members[curSelected].blurredRanking.visible = false;
 
     rankCamera.zoom = 1.85;
     FlxTween.tween(rankCamera, {"zoom": 1.8}, 0.6, {ease: FlxEase.sineIn});
@@ -880,9 +934,8 @@ class FreeplayState extends MusicBeatSubState
 
   function rankDisplayNew(fromResults:Null<FromResultsParams>):Void
   {
-    grpCapsules.members[curSelected].ranking.alpha = 1;
-    grpCapsules.members[curSelected].blurredRanking.alpha = 1;
-
+    grpCapsules.members[curSelected].ranking.visible = true;
+    grpCapsules.members[curSelected].blurredRanking.visible = true;
     grpCapsules.members[curSelected].ranking.scale.set(20, 20);
     grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20);
 
@@ -895,7 +948,23 @@ class FreeplayState extends MusicBeatSubState
     FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1);
 
     new FlxTimer().start(0.1, _ -> {
-      trace(grpCapsules.members[curSelected].ranking.rank);
+      // trace(grpCapsules.members[curSelected].ranking.rank);
+      if (fromResults?.oldRank != null)
+      {
+        grpCapsules.members[curSelected].fakeRanking.visible = false;
+        grpCapsules.members[curSelected].fakeBlurredRanking.visible = false;
+
+        sparks.visible = true;
+        sparksADD.visible = true;
+        sparks.animation.play('sparks', true);
+        sparksADD.animation.play('sparks add', true);
+
+        sparks.animation.finishCallback = anim -> {
+          sparks.visible = false;
+          sparksADD.visible = false;
+        };
+      }
+
       switch (fromResultsParams?.newRank)
       {
         case SHIT:
@@ -1053,10 +1122,10 @@ class FreeplayState extends MusicBeatSubState
       // dj.fistPump();
       prepForNewRank = false;
       FunkinSound.playMusic('freakyMenu',
-      {
-        overrideExisting: true,
-        restartTrack: false
-      });
+        {
+          overrideExisting: true,
+          restartTrack: false
+        });
       FlxG.sound.music.fadeIn(4.0, 0.0, 1.0);
     });
   }
@@ -1092,35 +1161,56 @@ class FreeplayState extends MusicBeatSubState
       rankAnimStart(fromResultsParams);
     }
 
-    if (FlxG.keys.justPressed.H)
-    {
-      rankDisplayNew(fromResultsParams);
-    }
+    // if (FlxG.keys.justPressed.H)
+    // {
+    //   rankDisplayNew(fromResultsParams);
+    // }
+
+    // if (FlxG.keys.justPressed.G)
+    // {
+    //   rankAnimSlam(fromResultsParams);
+    // }
 
     if (FlxG.keys.justPressed.G)
     {
-      rankAnimSlam(fromResultsParams);
+      sparks.y -= 2;
+      trace(sparks.x, sparks.y);
+    }
+    if (FlxG.keys.justPressed.V)
+    {
+      sparks.x -= 2;
+      trace(sparks.x, sparks.y);
+    }
+    if (FlxG.keys.justPressed.N)
+    {
+      sparks.x += 2;
+      trace(sparks.x, sparks.y);
+    }
+    if (FlxG.keys.justPressed.B)
+    {
+      sparks.y += 2;
+      trace(sparks.x, sparks.y);
     }
 
     if (FlxG.keys.justPressed.I)
     {
-      confirmTextGlow.y -= 1;
-      trace(confirmTextGlow.x, confirmTextGlow.y);
+      sparksADD.y -= 2;
+      trace(sparksADD.x, sparksADD.y);
     }
     if (FlxG.keys.justPressed.J)
     {
-      confirmTextGlow.x -= 1;
-      trace(confirmTextGlow.x, confirmTextGlow.y);
+      sparksADD.x -= 2;
+      trace(sparksADD.x, sparksADD.y);
     }
     if (FlxG.keys.justPressed.L)
     {
-      confirmTextGlow.x += 1;
-      trace(confirmTextGlow.x, confirmTextGlow.y);
+      sparksADD.x += 2;
+      trace(sparksADD.x, sparksADD.y);
     }
     if (FlxG.keys.justPressed.K)
     {
-      confirmTextGlow.y += 1;
-      trace(confirmTextGlow.x, confirmTextGlow.y);
+      sparksADD.y += 2;
+      trace(sparksADD.x, sparksADD.y);
     }
     #end
 
@@ -1758,26 +1848,27 @@ class FreeplayState extends MusicBeatSubState
       }
       else
       {
-        if(prepForNewRank == false){
-        var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : "";
-        // TODO: Stream the instrumental of the selected song?
-        FunkinSound.playMusic(daSongCapsule.songData.songId,
-          {
-            startingVolume: 0.0,
-            overrideExisting: true,
-            restartTrack: false,
-            pathsFunction: INST,
-            suffix: potentiallyErect,
-            partialParams:
-              {
-                loadPartial: true,
-                start: 0,
-                end: 0.1
-              },
-            onLoad: function() {
-              FlxG.sound.music.fadeIn(2, 0, 0.4);
-            }
-          });
+        if (prepForNewRank == false)
+        {
+          var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : "";
+          // TODO: Stream the instrumental of the selected song?
+          FunkinSound.playMusic(daSongCapsule.songData.songId,
+            {
+              startingVolume: 0.0,
+              overrideExisting: true,
+              restartTrack: false,
+              pathsFunction: INST,
+              suffix: potentiallyErect,
+              partialParams:
+                {
+                  loadPartial: true,
+                  start: 0,
+                  end: 0.1
+                },
+              onLoad: function() {
+                FlxG.sound.music.fadeIn(2, 0, 0.4);
+              }
+            });
         }
       }
       grpCapsules.members[curSelected].selected = true;
@@ -1791,9 +1882,12 @@ class FreeplayState extends MusicBeatSubState
   public static function build(?params:FreeplayStateParams, ?stickers:StickerSubState):MusicBeatState
   {
     var result:MainMenuState;
-    if(params?.fromResults.oldRank != null){
+    if (params?.fromResults.playRankAnim == true)
+    {
       result = new MainMenuState(true);
-    }else{
+    }
+    else
+    {
       result = new MainMenuState(false);
     }
 
diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx
index b52032bc3..3af75c105 100644
--- a/source/funkin/ui/freeplay/SongMenuItem.hx
+++ b/source/funkin/ui/freeplay/SongMenuItem.hx
@@ -39,9 +39,13 @@ class SongMenuItem extends FlxSpriteGroup
 
   public var songText:CapsuleText;
   public var favIcon:FlxSprite;
+
   public var ranking:FreeplayRank;
   public var blurredRanking:FreeplayRank;
 
+  public var fakeRanking:FreeplayRank;
+  public var fakeBlurredRanking:FreeplayRank;
+
   var ranks:Array<String> = ["fail", "average", "great", "excellent", "perfect", "perfectsick"];
 
   public var targetPos:FlxPoint = new FlxPoint();
@@ -131,12 +135,23 @@ class SongMenuItem extends FlxSpriteGroup
     // doesn't get added, simply is here to help with visibility of things for the pop in!
     grpHide = new FlxGroup();
 
+    fakeRanking = new FreeplayRank(420, 41);
+    add(fakeRanking);
+
+    fakeBlurredRanking = new FreeplayRank(fakeRanking.x, fakeRanking.y);
+    fakeBlurredRanking.shader = new GaussianBlurShader(1);
+    add(fakeBlurredRanking);
+
+    fakeRanking.visible = false;
+    fakeBlurredRanking.visible = false;
+
     ranking = new FreeplayRank(420, 41);
     add(ranking);
 
     blurredRanking = new FreeplayRank(ranking.x, ranking.y);
     blurredRanking.shader = new GaussianBlurShader(1);
     add(blurredRanking);
+
     // ranking.loadGraphic(Paths.image('freeplay/ranks/' + rank));
     // ranking.scale.x = ranking.scale.y = realScaled;
     // ranking.alpha = 0.75;

From b96fa51045f4cae5fa889eade75ac1f1c676034a Mon Sep 17 00:00:00 2001
From: FabsTheFabs <flamingkitty24@gmail.com>
Date: Sun, 2 Jun 2024 00:26:13 +0100
Subject: [PATCH 5/7] assets submod!!

---
 assets | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/assets b/assets
index d64939d86..ad8a0a28a 160000
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit d64939d866c70a831b76ed78930782b66871dcc2
+Subproject commit ad8a0a28addb3153c01bca2f8a2fdea05c5ac9ea

From 8248cffbafb1621b5c2811f01a02ee62bd3b48ee Mon Sep 17 00:00:00 2001
From: Cameron Taylor <cameron.taylor.ninja@gmail.com>
Date: Sat, 1 Jun 2024 20:36:14 -0400
Subject: [PATCH 6/7] small bool cleanings, and maybe fixes

---
 source/funkin/ui/freeplay/FreeplayState.hx | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index e1d8eb81c..e97ab391b 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -1121,12 +1121,6 @@ class FreeplayState extends MusicBeatSubState
     new FlxTimer().start(2, _ -> {
       // dj.fistPump();
       prepForNewRank = false;
-      FunkinSound.playMusic('freakyMenu',
-        {
-          overrideExisting: true,
-          restartTrack: false
-        });
-      FlxG.sound.music.fadeIn(4.0, 0.0, 1.0);
     });
   }
 
@@ -1527,6 +1521,7 @@ class FreeplayState extends MusicBeatSubState
               overrideExisting: true,
               restartTrack: false
             });
+          FlxG.sound.music.fadeIn(4.0, 0.0, 1.0);
           close();
         }
         else
@@ -1842,13 +1837,13 @@ class FreeplayState extends MusicBeatSubState
           {
             startingVolume: 0.0,
             overrideExisting: true,
-            restartTrack: true
+            restartTrack: false
           });
         FlxG.sound.music.fadeIn(2, 0, 0.8);
       }
       else
       {
-        if (prepForNewRank == false)
+        if (!prepForNewRank)
         {
           var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : "";
           // TODO: Stream the instrumental of the selected song?
@@ -1882,14 +1877,9 @@ class FreeplayState extends MusicBeatSubState
   public static function build(?params:FreeplayStateParams, ?stickers:StickerSubState):MusicBeatState
   {
     var result:MainMenuState;
-    if (params?.fromResults.playRankAnim == true)
-    {
-      result = new MainMenuState(true);
-    }
+    if (params?.fromResults.playRankAnim) result = new MainMenuState(true);
     else
-    {
       result = new MainMenuState(false);
-    }
 
     result.openSubState(new FreeplayState(params, stickers));
     result.persistentUpdate = false;

From 7aee1f900af2d19df18252a72eb382326b878c2f Mon Sep 17 00:00:00 2001
From: EliteMasterEric <ericmyllyoja@gmail.com>
Date: Fri, 31 May 2024 21:55:27 -0400
Subject: [PATCH 7/7] Fix a Results->Freeplay crash

---
 source/funkin/ui/freeplay/FreeplayState.hx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index e97ab391b..0dd520ee3 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -944,7 +944,7 @@ class FreeplayState extends MusicBeatSubState
 
     FlxTween.tween(grpCapsules.members[curSelected].ranking, {"scale.x": 1, "scale.y": 1}, 0.1);
 
-    grpCapsules.members[curSelected].blurredRanking.animation.play(grpCapsules.members[curSelected].blurredRanking.animation.curAnim.name, true);
+    grpCapsules.members[curSelected].blurredRanking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true);
     FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1);
 
     new FlxTimer().start(0.1, _ -> {