From 67e096e4430a84bac3e04da02fe249240866c7e0 Mon Sep 17 00:00:00 2001
From: EliteMasterEric <ericmyllyoja@gmail.com>
Date: Mon, 1 Apr 2024 21:59:53 -0400
Subject: [PATCH] Bunch of results screen fixes

---
 source/funkin/Highscore.hx                    |  4 ++
 source/funkin/play/PauseSubState.hx           |  2 +
 source/funkin/play/PlayState.hx               | 43 +++++++++---
 source/funkin/play/ResultState.hx             | 68 +++++++++++++------
 source/funkin/play/components/TallyCounter.hx | 23 +++++--
 source/funkin/ui/freeplay/FreeplayState.hx    |  4 +-
 6 files changed, 106 insertions(+), 38 deletions(-)

diff --git a/source/funkin/Highscore.hx b/source/funkin/Highscore.hx
index 996e2367e..94f41cea4 100644
--- a/source/funkin/Highscore.hx
+++ b/source/funkin/Highscore.hx
@@ -59,6 +59,7 @@ abstract Tallies(RawTallies)
         totalNotes: 0,
         totalNotesHit: 0,
         maxCombo: 0,
+        score: 0,
         isNewHighscore: false
       }
   }
@@ -81,6 +82,9 @@ typedef RawTallies =
   var good:Int;
   var sick:Int;
   var maxCombo:Int;
+
+  var score:Int;
+
   var isNewHighscore:Bool;
 
   /**
diff --git a/source/funkin/play/PauseSubState.hx b/source/funkin/play/PauseSubState.hx
index ed847402a..2af04749f 100644
--- a/source/funkin/play/PauseSubState.hx
+++ b/source/funkin/play/PauseSubState.hx
@@ -567,6 +567,8 @@ class PauseSubState extends MusicBeatSubState
     PlayStatePlaylist.campaignDifficulty = difficulty;
     PlayState.instance.currentDifficulty = PlayStatePlaylist.campaignDifficulty;
 
+    FreeplayState.rememberedDifficulty = difficulty;
+
     PlayState.instance.needsReset = true;
 
     state.close();
diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx
index 274ee4fe8..438941f90 100644
--- a/source/funkin/play/PlayState.hx
+++ b/source/funkin/play/PlayState.hx
@@ -2731,7 +2731,7 @@ class PlayState extends MusicBeatSubState
    */
   public function endSong(rightGoddamnNow:Bool = false):Void
   {
-    FlxG.sound.music.volume = 0;
+    if (FlxG.sound.music != null) FlxG.sound.music.volume = 0;
     vocals.volume = 0;
     mayPauseGame = false;
 
@@ -2749,6 +2749,8 @@ class PlayState extends MusicBeatSubState
 
     deathCounter = 0;
 
+    var isNewHighscore = false;
+
     if (currentSong != null && currentSong.validScore)
     {
       // crackhead double thingie, sets whether was new highscore, AND saves the song!
@@ -2779,11 +2781,14 @@ class PlayState extends MusicBeatSubState
         #if newgrounds
         NGio.postScore(score, currentSong.id);
         #end
+        isNewHighscore = true;
       }
     }
 
     if (PlayStatePlaylist.isStoryMode)
     {
+      isNewHighscore = false;
+
       PlayStatePlaylist.campaignScore += songScore;
 
       // Pop the next song ID from the list.
@@ -2833,6 +2838,7 @@ class PlayState extends MusicBeatSubState
             #if newgrounds
             NGio.postScore(score, 'Level ${PlayStatePlaylist.campaignId}');
             #end
+            isNewHighscore = true;
           }
         }
 
@@ -2844,11 +2850,11 @@ class PlayState extends MusicBeatSubState
         {
           if (rightGoddamnNow)
           {
-            moveToResultsScreen();
+            moveToResultsScreen(isNewHighscore);
           }
           else
           {
-            zoomIntoResultsScreen();
+            zoomIntoResultsScreen(isNewHighscore);
           }
         }
       }
@@ -2909,11 +2915,11 @@ class PlayState extends MusicBeatSubState
       {
         if (rightGoddamnNow)
         {
-          moveToResultsScreen();
+          moveToResultsScreen(isNewHighscore);
         }
         else
         {
-          zoomIntoResultsScreen();
+          zoomIntoResultsScreen(isNewHighscore);
         }
       }
     }
@@ -2987,7 +2993,7 @@ class PlayState extends MusicBeatSubState
   /**
    * Play the camera zoom animation and then move to the results screen once it's done.
    */
-  function zoomIntoResultsScreen():Void
+  function zoomIntoResultsScreen(isNewHighscore:Bool):Void
   {
     trace('WENT TO RESULTS SCREEN!');
 
@@ -3044,7 +3050,7 @@ class PlayState extends MusicBeatSubState
         {
           ease: FlxEase.expoIn,
           onComplete: function(_) {
-            moveToResultsScreen();
+            moveToResultsScreen(isNewHighscore);
           }
         });
     });
@@ -3053,7 +3059,7 @@ class PlayState extends MusicBeatSubState
   /**
    * Move to the results screen right goddamn now.
    */
-  function moveToResultsScreen():Void
+  function moveToResultsScreen(isNewHighscore:Bool):Void
   {
     persistentUpdate = false;
     vocals.stop();
@@ -3065,7 +3071,24 @@ class PlayState extends MusicBeatSubState
       {
         storyMode: PlayStatePlaylist.isStoryMode,
         title: PlayStatePlaylist.isStoryMode ? ('${PlayStatePlaylist.campaignTitle}') : ('${currentChart.songName} by ${currentChart.songArtist}'),
-        tallies: talliesToUse,
+        scoreData:
+          {
+            score: songScore,
+            tallies:
+              {
+                sick: Highscore.tallies.sick,
+                good: Highscore.tallies.good,
+                bad: Highscore.tallies.bad,
+                shit: Highscore.tallies.shit,
+                missed: Highscore.tallies.missed,
+                combo: Highscore.tallies.combo,
+                maxCombo: Highscore.tallies.maxCombo,
+                totalNotesHit: Highscore.tallies.totalNotesHit,
+                totalNotes: Highscore.tallies.totalNotes,
+              },
+            accuracy: Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes,
+          },
+        isNewHighscore: isNewHighscore
       });
     res.camera = camHUD;
     openSubState(res);
@@ -3212,7 +3235,7 @@ class PlayState extends MusicBeatSubState
     // Don't go back in time to before the song started.
     targetTimeMs = Math.max(0, targetTimeMs);
 
-    FlxG.sound.music.time = targetTimeMs;
+    if (FlxG.sound.music != null) FlxG.sound.music.time = targetTimeMs;
 
     handleSkippedNotes();
     SongEventRegistry.handleSkippedEvents(songEvents, Conductor.instance.songPosition);
diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx
index 821f4ba3c..7dbaf087f 100644
--- a/source/funkin/play/ResultState.hx
+++ b/source/funkin/play/ResultState.hx
@@ -1,5 +1,6 @@
 package funkin.play;
 
+import funkin.util.MathUtil;
 import funkin.ui.story.StoryMenuState;
 import funkin.graphics.adobeanimate.FlxAtlasSprite;
 import flixel.FlxSprite;
@@ -16,6 +17,8 @@ import flixel.tweens.FlxTween;
 import funkin.audio.FunkinSound;
 import flixel.util.FlxGradient;
 import flixel.util.FlxTimer;
+import funkin.save.Save;
+import funkin.save.Save.SaveScoreData;
 import funkin.graphics.shaders.LeftMaskShader;
 import funkin.play.components.TallyCounter;
 
@@ -42,12 +45,15 @@ class ResultState extends MusicBeatSubState
 
   override function create():Void
   {
-    if (params.tallies.sick == params.tallies.totalNotesHit
-      && params.tallies.maxCombo == params.tallies.totalNotesHit) resultsVariation = PERFECT;
-    else if (params.tallies.missed + params.tallies.bad + params.tallies.shit >= params.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;
+    /*
+      if (params.scoreData.sick == params.scoreData.totalNotesHit
+        && params.scoreData.maxCombo == params.scoreData.totalNotesHit) resultsVariation = PERFECT;
+      else if (params.scoreData.missed + params.scoreData.bad + params.scoreData.shit >= params.scoreData.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;
+     */
+    resultsVariation = NORMAL;
 
     FunkinSound.playMusic('results$resultsVariation',
       {
@@ -130,12 +136,16 @@ class ResultState extends MusicBeatSubState
 
     var diffSpr:String = switch (PlayState.instance.currentDifficulty)
     {
-      case 'EASY':
+      case 'easy':
         'difEasy';
-      case 'NORMAL':
+      case 'normal':
         'difNormal';
-      case 'HARD':
+      case 'hard':
         'difHard';
+      case 'erect':
+        'difErect';
+      case 'nightmare':
+        'difNightmare';
       case _:
         'difNormal';
     }
@@ -195,29 +205,33 @@ class ResultState extends MusicBeatSubState
      * NOTE: We display how many notes were HIT, not how many notes there were in total.
      *
      */
-    var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, params.tallies.totalNotesHit);
+    var totalHit:TallyCounter = new TallyCounter(375, hStuf * 3, params.scoreData.tallies.totalNotesHit);
     ratingGrp.add(totalHit);
 
-    var maxCombo:TallyCounter = new TallyCounter(375, hStuf * 4, params.tallies.maxCombo);
+    var maxCombo:TallyCounter = new TallyCounter(375, hStuf * 4, params.scoreData.tallies.maxCombo);
     ratingGrp.add(maxCombo);
 
     hStuf += 2;
     var extraYOffset:Float = 5;
-    var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, params.tallies.sick, 0xFF89E59E);
+    var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, params.scoreData.tallies.sick, 0xFF89E59E);
     ratingGrp.add(tallySick);
 
-    var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, params.tallies.good, 0xFF89C9E5);
+    var tallyGood:TallyCounter = new TallyCounter(210, (hStuf * 6) + extraYOffset, params.scoreData.tallies.good, 0xFF89C9E5);
     ratingGrp.add(tallyGood);
 
-    var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, params.tallies.bad, 0xFFE6CF8A);
+    var tallyBad:TallyCounter = new TallyCounter(190, (hStuf * 7) + extraYOffset, params.scoreData.tallies.bad, 0xFFE6CF8A);
     ratingGrp.add(tallyBad);
 
-    var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, params.tallies.shit, 0xFFE68C8A);
+    var tallyShit:TallyCounter = new TallyCounter(220, (hStuf * 8) + extraYOffset, params.scoreData.tallies.shit, 0xFFE68C8A);
     ratingGrp.add(tallyShit);
 
-    var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, params.tallies.missed, 0xFFC68AE6);
+    var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, params.scoreData.tallies.missed, 0xFFC68AE6);
     ratingGrp.add(tallyMissed);
 
+    var score:TallyCounter = new TallyCounter(825, 630, params.scoreData.score, RIGHT);
+    score.scale.set(2, 2);
+    ratingGrp.add(score);
+
     for (ind => rating in ratingGrp.members)
     {
       rating.visible = false;
@@ -235,9 +249,16 @@ class ResultState extends MusicBeatSubState
         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});
+        if (params.isNewHighscore)
+        {
+          highscoreNew.visible = true;
+          highscoreNew.animation.play("new");
+          FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut});
+        }
+        else
+        {
+          highscoreNew.visible = false;
+        }
       };
 
       switch (resultsVariation)
@@ -276,8 +297,6 @@ class ResultState extends MusicBeatSubState
       }
     });
 
-    if (params.tallies.isNewHighscore) trace("ITS A NEW HIGHSCORE!!!");
-
     super.create();
   }
 
@@ -393,8 +412,13 @@ typedef ResultsStateParams =
    */
   var title:String;
 
+  /**
+   * Whether the displayed score is a new highscore
+   */
+  var isNewHighscore:Bool;
+
   /**
    * The score, accuracy, and judgements.
    */
-  var tallies:Highscore.Tallies;
+  var scoreData:SaveScoreData;
 };
diff --git a/source/funkin/play/components/TallyCounter.hx b/source/funkin/play/components/TallyCounter.hx
index 77e6ef4ec..35a8f3f51 100644
--- a/source/funkin/play/components/TallyCounter.hx
+++ b/source/funkin/play/components/TallyCounter.hx
@@ -6,6 +6,8 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
 import flixel.math.FlxMath;
 import flixel.tweens.FlxEase;
 import flixel.tweens.FlxTween;
+import flixel.text.FlxText.FlxTextAlign;
+import funkin.util.MathUtil;
 
 /**
  * Numerical counters used next to each judgement in the Results screen.
@@ -13,18 +15,23 @@ import flixel.tweens.FlxTween;
 class TallyCounter extends FlxTypedSpriteGroup<FlxSprite>
 {
   public var curNumber:Float = 0;
-
   public var neededNumber:Int = 0;
+
   public var flavour:Int = 0xFFFFFFFF;
 
-  public function new(x:Float, y:Float, neededNumber:Int = 0, ?flavour:Int = 0xFFFFFFFF)
+  public var align:FlxTextAlign = FlxTextAlign.LEFT;
+
+  public function new(x:Float, y:Float, neededNumber:Int = 0, ?flavour:Int = 0xFFFFFFFF, align:FlxTextAlign = FlxTextAlign.LEFT)
   {
     super(x, y);
 
+    this.align = align;
+
     this.flavour = flavour;
 
     this.neededNumber = neededNumber;
-    drawNumbers();
+
+    if (curNumber == neededNumber) drawNumbers();
   }
 
   var tmr:Float = 0;
@@ -41,6 +48,8 @@ class TallyCounter extends FlxTypedSpriteGroup<FlxSprite>
     var seperatedScore:Array<Int> = [];
     var tempCombo:Int = Math.round(curNumber);
 
+    var fullNumberDigits:Int = Std.int(Math.max(1, Math.ceil(MathUtil.logBase(10, neededNumber))));
+
     while (tempCombo != 0)
     {
       seperatedScore.push(tempCombo % 10);
@@ -55,7 +64,13 @@ class TallyCounter extends FlxTypedSpriteGroup<FlxSprite>
     {
       if (ind >= members.length)
       {
-        var numb:TallyNumber = new TallyNumber(ind * 43, 0, num);
+        var xPos = ind * (43 * this.scale.x);
+        if (this.align == FlxTextAlign.RIGHT)
+        {
+          xPos -= (fullNumberDigits * (43 * this.scale.x));
+        }
+        var numb:TallyNumber = new TallyNumber(xPos, 0, num);
+        numb.scale.set(this.scale.x, this.scale.y);
         add(numb);
         numb.color = flavour;
       }
diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index 6cb0d1d9a..058f61a5b 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -133,8 +133,8 @@ class FreeplayState extends MusicBeatSubState
 
   var stickerSubState:StickerSubState;
 
-  static var rememberedDifficulty:Null<String> = Constants.DEFAULT_DIFFICULTY;
-  static var rememberedSongId:Null<String> = null;
+  public static var rememberedDifficulty:Null<String> = Constants.DEFAULT_DIFFICULTY;
+  public static var rememberedSongId:Null<String> = null;
 
   public function new(?params:FreeplayStateParams, ?stickers:StickerSubState)
   {