From 1cffc36ba8aa51b90523ff7fbe4464eca957cc29 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 1 Jun 2024 01:17:11 +0100 Subject: [PATCH] results timing redo + fixed anims for all ranks --- source/funkin/play/ResultState.hx | 280 +++++++++++++++++++++----- source/funkin/play/scoring/Scoring.hx | 70 ++++++- 2 files changed, 293 insertions(+), 57 deletions(-) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 8b8c0aea3..8a7332a83 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -5,6 +5,7 @@ import funkin.ui.story.StoryMenuState; import funkin.graphics.adobeanimate.FlxAtlasSprite; import flixel.FlxSprite; import funkin.graphics.FunkinSprite; +import flixel.effects.FlxFlicker; import flixel.graphics.frames.FlxBitmapFont; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxPoint; @@ -55,8 +56,10 @@ class ResultState extends MusicBeatSubState final score:ResultScore; var bfPerfect:Null = null; + var heartsPerfect:Null = null; var bfExcellent:Null = null; var bfGreat:Null = null; + var gfGreat:Null = null; var bfGood:Null = null; var gfGood:Null = null; var bfShit:Null = null; @@ -94,15 +97,15 @@ class ResultState extends MusicBeatSubState clearPercentSmall.zIndex = 1000; clearPercentSmall.visible = false; - bgFlash = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90); + bgFlash = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFF1A6, 0xFFFFF1BE], 90); resultsAnim = FunkinSprite.createSparrow(-200, -10, "resultScreen/results"); - ratingsPopin = FunkinSprite.createSparrow(-150, 120, "resultScreen/ratingsPopin"); + ratingsPopin = FunkinSprite.createSparrow(-135, 135, "resultScreen/ratingsPopin"); - scorePopin = FunkinSprite.createSparrow(-180, 520, "resultScreen/scorePopin"); + scorePopin = FunkinSprite.createSparrow(-180, 515, "resultScreen/scorePopin"); - highscoreNew = new FlxSprite(310, 570); + highscoreNew = new FlxSprite(44, 557); score = new ResultScore(35, 305, 10, params.scoreData.score); } @@ -136,14 +139,14 @@ class ResultState extends MusicBeatSubState bgFlash.scrollFactor.set(); bgFlash.visible = false; bgFlash.zIndex = 20; - bgFlash.cameras = [cameraBG]; + //bgFlash.cameras = [cameraBG]; add(bgFlash); // The sound system which falls into place behind the score text. Plays every time! var soundSystem:FlxSprite = FunkinSprite.createSparrow(-15, -180, 'resultScreen/soundSystem'); soundSystem.animation.addByPrefix("idle", "sound system", 24, false); soundSystem.visible = false; - new FlxTimer().start(0.3, _ -> { + new FlxTimer().start(8/24, _ -> { soundSystem.animation.play("idle"); soundSystem.visible = true; }); @@ -153,7 +156,22 @@ class ResultState extends MusicBeatSubState switch (rank) { case PERFECT | PERFECT_GOLD: - bfPerfect = new FlxAtlasSprite(370, -180, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); + heartsPerfect = new FlxAtlasSprite(1342, 370, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT/hearts", "shared")); + heartsPerfect.visible = false; + heartsPerfect.zIndex = 501; + add(heartsPerfect); + + heartsPerfect.anim.onComplete = () -> { + if (heartsPerfect != null) + { + //bfPerfect.anim.curFrame = 137; + heartsPerfect.anim.curFrame = 43; + heartsPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! + } + }; + + + bfPerfect = new FlxAtlasSprite(1342, 370, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); bfPerfect.visible = false; bfPerfect.zIndex = 500; add(bfPerfect); @@ -161,36 +179,57 @@ class ResultState extends MusicBeatSubState bfPerfect.anim.onComplete = () -> { if (bfPerfect != null) { + //bfPerfect.anim.curFrame = 137; bfPerfect.anim.curFrame = 137; bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! } }; case EXCELLENT: - bfExcellent = new FlxAtlasSprite(380, -170, Paths.animateAtlas("resultScreen/results-bf/resultsEXCELLENT", "shared")); + bfExcellent = new FlxAtlasSprite(1329, 429, Paths.animateAtlas("resultScreen/results-bf/resultsEXCELLENT", "shared")); bfExcellent.visible = false; bfExcellent.zIndex = 500; add(bfExcellent); - bfExcellent.onAnimationFinish.add((animName) -> { + bfExcellent.anim.onComplete = () -> { if (bfExcellent != null) { - bfExcellent.playAnimation('Loop Start'); + bfExcellent.anim.curFrame = 28; + bfExcellent.anim.play(); // unpauses this anim, since it's on PlayOnce! } - }); + }; + case GREAT: - bfGreat = new FlxAtlasSprite(640, 200, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT", "shared")); + gfGreat = new FlxAtlasSprite(802, 331, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT/gf", "shared")); + gfGreat.visible = false; + gfGreat.zIndex = 499; + add(gfGreat); + + gfGreat.scale.set(0.93, 0.93); + + gfGreat.anim.onComplete = () -> { + if (gfGreat != null) + { + gfGreat.anim.curFrame = 9; + gfGreat.anim.play(); // unpauses this anim, since it's on PlayOnce! + } + }; + + bfGreat = new FlxAtlasSprite(929, 363, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT/bf", "shared")); bfGreat.visible = false; bfGreat.zIndex = 500; add(bfGreat); - bfGreat.onAnimationFinish.add((animName) -> { + bfGreat.scale.set(0.93, 0.93); + + bfGreat.anim.onComplete = () -> { if (bfGreat != null) { - bfGreat.playAnimation('Loop Start'); + bfGreat.anim.curFrame = 15; + bfGreat.anim.play(); // unpauses this anim, since it's on PlayOnce! } - }); + }; case GOOD: gfGood = FunkinSprite.createSparrow(625, 325, 'resultScreen/results-bf/resultsGOOD/resultGirlfriendGOOD'); @@ -250,7 +289,7 @@ class ResultState extends MusicBeatSubState var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); blackTopBar.y = -blackTopBar.height; - FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut}); + FlxTween.tween(blackTopBar, {y: 0}, 7/24, {ease: FlxEase.quartOut, startDelay: 3/24}); blackTopBar.zIndex = 1010; add(blackTopBar); @@ -258,7 +297,7 @@ class ResultState extends MusicBeatSubState resultsAnim.visible = false; resultsAnim.zIndex = 1200; add(resultsAnim); - new FlxTimer().start(0.3, _ -> { + new FlxTimer().start(6/24, _ -> { resultsAnim.visible = true; resultsAnim.animation.play("result"); }); @@ -267,7 +306,7 @@ class ResultState extends MusicBeatSubState ratingsPopin.visible = false; ratingsPopin.zIndex = 1200; add(ratingsPopin); - new FlxTimer().start(1.0, _ -> { + new FlxTimer().start(21/24, _ -> { ratingsPopin.visible = true; ratingsPopin.animation.play("idle"); }); @@ -276,23 +315,49 @@ class ResultState extends MusicBeatSubState scorePopin.visible = false; scorePopin.zIndex = 1200; add(scorePopin); - new FlxTimer().start(1.0, _ -> { + new FlxTimer().start(36/24, _ -> { scorePopin.visible = true; scorePopin.animation.play("score"); scorePopin.animation.finishCallback = anim -> { - score.visible = true; - score.animateNumbers(); + }; }); + new FlxTimer().start(37/24, _ -> { + score.visible = true; + score.animateNumbers(); + startRankTallySequence(); + }); + + new FlxTimer().start(rank.getBFDelay(), _ -> { + afterRankTallySequence(); + }); + + new FlxTimer().start(rank.getFlashDelay(), _ -> { + displayRankText(); + }); + highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); - highscoreNew.animation.addByPrefix("new", "NEW HIGHSCORE", 24); + highscoreNew.animation.addByPrefix("new", "highscoreAnim0", 24, false); highscoreNew.visible = false; - highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); + //highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); highscoreNew.updateHitbox(); highscoreNew.zIndex = 1200; add(highscoreNew); + new FlxTimer().start(rank.getHighscoreDelay(), _ -> { + if (params.isNewHighscore ?? false) + { + highscoreNew.visible = true; + highscoreNew.animation.play("new"); + highscoreNew.animation.finishCallback = _ -> highscoreNew.animation.play("new", true, false, 16); + } + else + { + highscoreNew.visible = false; + } + }); + var hStuf:Int = 50; var ratingGrp:FlxTypedGroup = new FlxTypedGroup(); @@ -310,7 +375,10 @@ class ResultState extends MusicBeatSubState ratingGrp.add(maxCombo); hStuf += 2; - var extraYOffset:Float = 5; + var extraYOffset:Float = 7; + + hStuf += 2; + var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, params.scoreData.tallies.sick, 0xFF89E59E); ratingGrp.add(tallySick); @@ -339,20 +407,17 @@ class ResultState extends MusicBeatSubState }); } - ratingsPopin.animation.finishCallback = anim -> { - startRankTallySequence(); - if (params.isNewHighscore ?? false) - { - highscoreNew.visible = true; - highscoreNew.animation.play("new"); - FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); - } - else - { - highscoreNew.visible = false; - } - }; + // if (params.isNewHighscore ?? false) + // { + // highscoreNew.visible = true; + // highscoreNew.animation.play("new"); + // //FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); + // } + // else + // { + // highscoreNew.visible = false; + // } new FlxTimer().start(rank.getMusicDelay(), _ -> { if (rank.hasMusicIntro()) @@ -392,6 +457,8 @@ class ResultState extends MusicBeatSubState function startRankTallySequence():Void { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 5/24); var clearPercentFloat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100; clearPercentTarget = Math.floor(clearPercentFloat); // Prevent off-by-one errors. @@ -400,8 +467,8 @@ class ResultState extends MusicBeatSubState trace('Clear percent target: ' + clearPercentFloat + ', round: ' + clearPercentTarget); - var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 300, FlxG.height / 2 - 100, clearPercentLerp); - FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 1.5, + var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 190, FlxG.height / 2 - 70, clearPercentLerp); + FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 58/24, { ease: FlxEase.quartOut, onUpdate: _ -> { @@ -416,10 +483,6 @@ class ResultState extends MusicBeatSubState // Play confirm sound. FunkinSound.playOnce(Paths.sound('confirmMenu')); - // Flash background. - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - // Just to be sure that the lerp didn't mess things up. clearPercentCounter.curNumber = clearPercentTarget; @@ -428,7 +491,7 @@ class ResultState extends MusicBeatSubState clearPercentCounter.flash(false); }); - displayRankText(); + //displayRankText(); // previously 2.0 seconds new FlxTimer().start(0.25, _ -> { @@ -441,7 +504,7 @@ class ResultState extends MusicBeatSubState } }); - afterRankTallySequence(); + //afterRankTallySequence(); }); } }); @@ -466,7 +529,6 @@ class ResultState extends MusicBeatSubState { highscoreNew.visible = true; highscoreNew.animation.play("new"); - FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); } else { @@ -480,27 +542,36 @@ class ResultState extends MusicBeatSubState function displayRankText():Void { + bgFlash.visible = true; + bgFlash.alpha = 1; + FlxTween.tween(bgFlash, {alpha: 0}, 14/24); + var rankTextVert:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getVerTextAsset()), Y, 0, 30); - rankTextVert.x = FlxG.width - 64; + rankTextVert.x = FlxG.width - 44; rankTextVert.y = 100; rankTextVert.zIndex = 990; add(rankTextVert); - // Scrolling. - rankTextVert.velocity.y = -50; + FlxFlicker.flicker(rankTextVert, 2/24 * 3, 2/24, true); - for (i in 0...10) + // Scrolling. + new FlxTimer().start(30/24, _ -> { + rankTextVert.velocity.y = -80; + }); + + + for (i in 0...12) { var rankTextBack:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getHorTextAsset()), X, 10, 0); rankTextBack.x = FlxG.width / 2 - 320; - rankTextBack.y = 50 + (150 * i / 2) + 10; + rankTextBack.y = 50 + (135 * i / 2) + 10; // rankTextBack.angle = -3.8; rankTextBack.zIndex = 100; rankTextBack.cameras = [cameraScroll]; add(rankTextBack); // Scrolling. - rankTextBack.velocity.x = (i % 2 == 0) ? -10.0 : 10.0; + rankTextBack.velocity.x = (i % 2 == 0) ? -7.0 : 7.0; } refresh(); @@ -508,6 +579,7 @@ class ResultState extends MusicBeatSubState function afterRankTallySequence():Void { + showSmallClearPercent(); switch (rank) @@ -522,6 +594,17 @@ class ResultState extends MusicBeatSubState bfPerfect.visible = true; bfPerfect.playAnimation(''); } + new FlxTimer().start(106 / 24, _ -> { + if (heartsPerfect == null) + { + trace("Could not build heartsPerfect animation!"); + } + else + { + heartsPerfect.visible = true; + heartsPerfect.playAnimation(''); + } + }); case EXCELLENT: if (bfExcellent == null) { @@ -530,7 +613,7 @@ class ResultState extends MusicBeatSubState else { bfExcellent.visible = true; - bfExcellent.playAnimation('Intro'); + bfExcellent.playAnimation(''); } case GREAT: if (bfGreat == null) @@ -540,8 +623,20 @@ class ResultState extends MusicBeatSubState else { bfGreat.visible = true; - bfGreat.playAnimation('Intro'); + bfGreat.playAnimation(''); } + + new FlxTimer().start(6 / 24, _ -> { + if (gfGreat == null) + { + trace("Could not build GREAT animation for gf!"); + } + else + { + gfGreat.visible = true; + gfGreat.playAnimation(''); + } + }); case SHIT: if (bfShit == null) { @@ -627,7 +722,9 @@ class ResultState extends MusicBeatSubState refresh(); } - movingSongStuff = true; + new FlxTimer().start(2.5, _ -> { + movingSongStuff = true; + }); } var movingSongStuff:Bool = false; @@ -647,6 +744,79 @@ class ResultState extends MusicBeatSubState override function update(elapsed:Float):Void { + // if(FlxG.keys.justPressed.R){ + // FlxG.switchState(() -> new funkin.play.ResultState( + // { + // storyMode: false, + // title: "Cum Song Erect by Kawai Sprite", + // songId: "cum", + // difficultyId: "nightmare", + // isNewHighscore: true, + // scoreData: + // { + // score: 1_234_567, + // tallies: + // { + // sick: 200, + // good: 0, + // bad: 0, + // shit: 0, + // missed: 0, + // combo: 0, + // maxCombo: 69, + // totalNotesHit: 200, + // totalNotes: 200 // 0, + // } + // }, + // })); + // } + + // if(heartsPerfect != null){ + // if (FlxG.keys.justPressed.I) + // { + // heartsPerfect.y -= 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // if (FlxG.keys.justPressed.J) + // { + // heartsPerfect.x -= 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // if (FlxG.keys.justPressed.L) + // { + // heartsPerfect.x += 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // if (FlxG.keys.justPressed.K) + // { + // heartsPerfect.y += 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // } + + // if(bfGreat != null){ + // if (FlxG.keys.justPressed.W) + // { + // bfGreat.y -= 1; + // trace(bfGreat.x, bfGreat.y); + // } + // if (FlxG.keys.justPressed.A) + // { + // bfGreat.x -= 1; + // trace(bfGreat.x, bfGreat.y); + // } + // if (FlxG.keys.justPressed.D) + // { + // bfGreat.x += 1; + // trace(bfGreat.x, bfGreat.y); + // } + // if (FlxG.keys.justPressed.S) + // { + // bfGreat.y += 1; + // trace(bfGreat.x, bfGreat.y); + // } + // } + // maskShaderSongName.swagSprX = songName.x; maskShaderDifficulty.swagSprX = difficulty.x; diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index 6155ec879..04bd81cf8 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -403,9 +403,75 @@ enum abstract ScoringRank(String) { case PERFECT_GOLD | PERFECT: // return 2.5; - return 5.0; + return 95/24; case EXCELLENT: - return 1.75; + return 0; + case GREAT: + return 5/24; + case GOOD: + return 3/24; + case SHIT: + return 2/24; + default: + return 3.5; + } + } + + public function getBFDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 95/24; + case EXCELLENT: + return 97/24; + case GREAT: + return 95/24; + case GOOD: + return 95/24; + case SHIT: + return 95/24; + default: + return 3.5; + } + } + + public function getFlashDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 129/24; + case EXCELLENT: + return 122/24; + case GREAT: + return 109/24; + case GOOD: + return 107/24; + case SHIT: + return 186/24; + default: + return 3.5; + } + } + + public function getHighscoreDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 140/24; + case EXCELLENT: + return 140/24; + case GREAT: + return 129/24; + case GOOD: + return 127/24; + case SHIT: + return 207/24; default: return 3.5; }