diff --git a/assets b/assets index aa1231e8c..3a9e05108 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit aa1231e8cf2990bb902eac3b37815c010fa9919a +Subproject commit 3a9e0510841533f96228609dcd50f2515443bb90 diff --git a/source/funkin/play/Countdown.hx b/source/funkin/play/Countdown.hx index 55c2a8992..542cb067c 100644 --- a/source/funkin/play/Countdown.hx +++ b/source/funkin/play/Countdown.hx @@ -11,6 +11,7 @@ import funkin.modding.events.ScriptEvent.CountdownScriptEvent; import flixel.util.FlxTimer; import funkin.util.EaseUtil; import funkin.audio.FunkinSound; +import openfl.utils.Assets; class Countdown { @@ -19,6 +20,20 @@ class Countdown */ public static var countdownStep(default, null):CountdownStep = BEFORE; + /** + * Which alternate countdown sound effect to use. + * You can set this via script. + * For example, in Week 6 it is `-pixel`. + */ + public static var soundSuffix:String = ''; + + /** + * Which alternate graphic on countdown to use. + * You can set this via script. + * For example, in Week 6 it is `-pixel`. + */ + public static var graphicSuffix:String = ''; + /** * The currently running countdown. This will be null if there is no countdown running. */ @@ -30,7 +45,7 @@ class Countdown * This will automatically stop and restart the countdown if it is already running. * @returns `false` if the countdown was cancelled by a script. */ - public static function performCountdown(isPixelStyle:Bool):Bool + public static function performCountdown():Bool { countdownStep = BEFORE; var cancelled:Bool = propagateCountdownEvent(countdownStep); @@ -65,10 +80,10 @@ class Countdown // PlayState.instance.dispatchEvent(new SongTimeScriptEvent(SONG_BEAT_HIT, 0, 0)); // Countdown graphic. - showCountdownGraphic(countdownStep, isPixelStyle); + showCountdownGraphic(countdownStep, graphicSuffix.toLowerCase().contains('pixel')); // Countdown sound. - playCountdownSound(countdownStep, isPixelStyle); + playCountdownSound(countdownStep); // Event handling bullshit. var cancelled:Bool = propagateCountdownEvent(countdownStep); @@ -177,55 +192,33 @@ class Countdown } /** - * Retrieves the graphic to use for this step of the countdown. - * TODO: Make this less dumb. Unhardcode it? Use modules? Use notestyles? - * - * This is public so modules can do lol funny shit. + * Reset the countdown configuration to the default. */ - public static function showCountdownGraphic(index:CountdownStep, isPixelStyle:Bool):Void + public static function reset() + { + soundSuffix = ''; + graphicSuffix = ''; + } + + /** + * Retrieves the graphic to use for this step of the countdown. + */ + public static function showCountdownGraphic(index:CountdownStep, isGraphicPixel:Bool):Void { var spritePath:String = null; - - var fadeEase = FlxEase.cubeInOut; - - if (isPixelStyle) - { - fadeEase = EaseUtil.stepped(8); - switch (index) - { - case TWO: - spritePath = 'weeb/pixelUI/ready-pixel'; - case ONE: - spritePath = 'weeb/pixelUI/set-pixel'; - case GO: - spritePath = 'weeb/pixelUI/date-pixel'; - default: - // null - } - } - else - { - switch (index) - { - case TWO: - spritePath = 'ready'; - case ONE: - spritePath = 'set'; - case GO: - spritePath = 'go'; - default: - // null - } - } + spritePath = resolveGraphicPath(graphicSuffix, index); if (spritePath == null) return; var countdownSprite:FunkinSprite = FunkinSprite.create(spritePath); countdownSprite.scrollFactor.set(0, 0); - if (isPixelStyle) countdownSprite.setGraphicSize(Std.int(countdownSprite.width * Constants.PIXEL_ART_SCALE)); + if (isGraphicPixel) countdownSprite.setGraphicSize(Std.int(countdownSprite.width * Constants.PIXEL_ART_SCALE)); - countdownSprite.antialiasing = !isPixelStyle; + var fadeEase = FlxEase.cubeInOut; + if (isGraphicPixel) fadeEase = EaseUtil.stepped(8); + + countdownSprite.antialiasing = !isGraphicPixel; countdownSprite.updateHitbox(); countdownSprite.screenCenter(); @@ -247,52 +240,55 @@ class Countdown PlayState.instance.add(countdownSprite); } + static function resolveGraphicPath(suffix:String, index:CountdownStep):Null + { + var basePath:String = 'ui/countdown/'; + var indexString:String = null; + switch (index) + { + case TWO: + indexString = 'ready'; + case ONE: + indexString = 'set'; + case GO: + indexString = 'go'; + default: + // null + } + basePath += indexString; + var spritePath:String = basePath + suffix; + while (!Assets.exists(Paths.image(spritePath)) && suffix.length > 0) + { + suffix = suffix.split('-').slice(0, -1).join('-'); + spritePath = basePath + suffix; + } + if (!Assets.exists(Paths.image(spritePath))) return null; + trace('Resolved sprite path: ' + Paths.image(spritePath)); + return spritePath; + } + /** * Retrieves the sound file to use for this step of the countdown. - * TODO: Make this less dumb. Unhardcode it? Use modules? Use notestyles? - * - * This is public so modules can do lol funny shit. */ - public static function playCountdownSound(index:CountdownStep, isPixelStyle:Bool):Void + public static function playCountdownSound(index:CountdownStep):Void { - var soundPath:String = null; + FunkinSound.playOnce(resolveSoundPath(soundSuffix, index), Constants.COUNTDOWN_VOLUME); + } - if (isPixelStyle) + static function resolveSoundPath(suffix:String, step:CountdownStep):Null + { + var basePath:String = 'gameplay/countdown/intro'; + if (step != CountdownStep.BEFORE || step != CountdownStep.AFTER) basePath += step; + + var soundPath:String = Paths.sound(basePath + suffix); + while (!Assets.exists(soundPath) && suffix.length > 0) { - switch (index) - { - case THREE: - soundPath = 'intro3-pixel'; - case TWO: - soundPath = 'intro2-pixel'; - case ONE: - soundPath = 'intro1-pixel'; - case GO: - soundPath = 'introGo-pixel'; - default: - // null - } + suffix = suffix.split('-').slice(0, -1).join('-'); + soundPath = Paths.sound(basePath + suffix); } - else - { - switch (index) - { - case THREE: - soundPath = 'intro3'; - case TWO: - soundPath = 'intro2'; - case ONE: - soundPath = 'intro1'; - case GO: - soundPath = 'introGo'; - default: - // null - } - } - - if (soundPath == null) return; - - FunkinSound.playOnce(Paths.sound(soundPath), Constants.COUNTDOWN_VOLUME); + if (!Assets.exists(soundPath)) return null; + trace('Resolved sound path: ' + soundPath); + return soundPath; } public static function decrement(step:CountdownStep):CountdownStep diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 32b6e7b62..384c28056 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -900,7 +900,7 @@ class PlayState extends MusicBeatSubState health = Constants.HEALTH_STARTING; songScore = 0; Highscore.tallies.combo = 0; - Countdown.performCountdown(currentStageId.startsWith('school')); + Countdown.performCountdown(); needsReset = false; } @@ -1857,7 +1857,7 @@ class PlayState extends MusicBeatSubState public function startCountdown():Void { // If Countdown.performCountdown returns false, then the countdown was canceled by a script. - var result:Bool = Countdown.performCountdown(currentStageId.startsWith('school')); + var result:Bool = Countdown.performCountdown(); if (!result) return; isInCutscene = false; @@ -3004,6 +3004,8 @@ class PlayState extends MusicBeatSubState GameOverSubState.reset(); PauseSubState.reset(); + Countdown.reset(); + PopUpStuff.reset(); // Clear the static reference to this state. instance = null; diff --git a/source/funkin/play/components/PopUpStuff.hx b/source/funkin/play/components/PopUpStuff.hx index 1bdfd98a8..4ae425cb6 100644 --- a/source/funkin/play/components/PopUpStuff.hx +++ b/source/funkin/play/components/PopUpStuff.hx @@ -8,25 +8,51 @@ import funkin.graphics.FunkinSprite; import funkin.play.PlayState; import funkin.util.TimerUtil; import funkin.util.EaseUtil; +import openfl.utils.Assets; class PopUpStuff extends FlxTypedGroup { public var offsets:Array = [0, 0]; + /** + * Which alternate graphic on popup to use. + * You can set this via script. + * For example, in Week 6 it is `-pixel`. + */ + public static var graphicSuffix:String = ''; + override public function new() { super(); } - public function displayRating(daRating:String):Void + static function resolveGraphicPath(suffix:String, index:String):Null + { + var folder:String; + if (suffix != '') folder = suffix.substring(0, suffix.indexOf("-")) + suffix.substring(suffix.indexOf("-") + 1); + else + folder = 'normal'; + var basePath:String = 'gameplay/popup/$folder/$index'; + var spritePath:String = basePath + suffix; + trace(spritePath); + while (!Assets.exists(Paths.image(spritePath)) && suffix.length > 0) + { + suffix = suffix.split('-').slice(0, -1).join('-'); + spritePath = basePath + suffix; + } + if (!Assets.exists(Paths.image(spritePath))) return null; + return spritePath; + } + + public function displayRating(daRating:String) { var perfStart:Float = TimerUtil.start(); if (daRating == null) daRating = "good"; - var ratingPath:String = daRating; + var ratingPath:String = resolveGraphicPath(graphicSuffix, daRating); - if (PlayState.instance.currentStageId.startsWith('school')) ratingPath = "weeb/pixelUI/" + ratingPath + "-pixel"; + // if (PlayState.instance.currentStageId.startsWith('school')) ratingPath = "weeb/pixelUI/" + ratingPath + "-pixel"; var rating:FunkinSprite = FunkinSprite.create(0, 0, ratingPath); rating.scrollFactor.set(0.2, 0.2); @@ -43,7 +69,7 @@ class PopUpStuff extends FlxTypedGroup var fadeEase = null; - if (PlayState.instance.currentStageId.startsWith('school')) + if (graphicSuffix.toLowerCase().contains('pixel')) { rating.setGraphicSize(Std.int(rating.width * Constants.PIXEL_ART_SCALE * 0.7)); rating.antialiasing = false; @@ -80,15 +106,8 @@ class PopUpStuff extends FlxTypedGroup if (combo == null) combo = 0; - var pixelShitPart1:String = ""; - var pixelShitPart2:String = ''; - - if (PlayState.instance.currentStageId.startsWith('school')) - { - pixelShitPart1 = 'weeb/pixelUI/'; - pixelShitPart2 = '-pixel'; - } - var comboSpr:FunkinSprite = FunkinSprite.create(pixelShitPart1 + 'combo' + pixelShitPart2); + var comboPath:String = resolveGraphicPath(graphicSuffix, Std.string(combo)); + var comboSpr:FunkinSprite = FunkinSprite.create(comboPath); comboSpr.y = (FlxG.camera.height * 0.44) + offsets[1]; comboSpr.x = (FlxG.width * 0.507) + offsets[0]; // comboSpr.x -= FlxG.camera.scroll.x * 0.2; @@ -101,7 +120,7 @@ class PopUpStuff extends FlxTypedGroup var fadeEase = null; - if (PlayState.instance.currentStageId.startsWith('school')) + if (graphicSuffix.toLowerCase().contains('pixel')) { comboSpr.setGraphicSize(Std.int(comboSpr.width * Constants.PIXEL_ART_SCALE * 1)); comboSpr.antialiasing = false; @@ -142,9 +161,9 @@ class PopUpStuff extends FlxTypedGroup var daLoop:Int = 1; for (i in seperatedScore) { - var numScore:FunkinSprite = FunkinSprite.create(0, comboSpr.y, pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2); + var numScore:FunkinSprite = FunkinSprite.create(0, comboSpr.y, resolveGraphicPath(graphicSuffix, 'num' + Std.int(i))); - if (PlayState.instance.currentStageId.startsWith('school')) + if (graphicSuffix.toLowerCase().contains('pixel')) { numScore.setGraphicSize(Std.int(numScore.width * Constants.PIXEL_ART_SCALE * 1)); numScore.antialiasing = false; @@ -182,4 +201,12 @@ class PopUpStuff extends FlxTypedGroup return combo; } + + /** + * Reset the popup configuration to the default. + */ + public static function reset() + { + graphicSuffix = ''; + } }