diff --git a/assets b/assets index 8013845e3..92bd680af 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8013845e331015b40c4cc35230f6d02bd2148d52 +Subproject commit 92bd680af3c627211656205dac85f9de5ae5abee diff --git a/source/funkin/data/freeplay/AlbumData.hx b/source/funkin/data/freeplay/AlbumData.hx index 265a01fce..ca851376d 100644 --- a/source/funkin/data/freeplay/AlbumData.hx +++ b/source/funkin/data/freeplay/AlbumData.hx @@ -1,5 +1,7 @@ package funkin.data.freeplay; +import funkin.data.animation.AnimationData; + /** * A type definition for the data for an album of songs. * It includes things like what graphics to display in Freeplay. @@ -33,4 +35,11 @@ typedef AlbumData = * The album title will be displayed below the album art in Freeplay. */ public var albumTitleAsset:String; + + /** + * An optional array of animations for the album title. + */ + @:optional + @:default([]) + public var albumTitleAnimations:Array; } diff --git a/source/funkin/ui/freeplay/Album.hx b/source/funkin/ui/freeplay/Album.hx index 7291c7357..3060d3eb8 100644 --- a/source/funkin/ui/freeplay/Album.hx +++ b/source/funkin/ui/freeplay/Album.hx @@ -1,6 +1,7 @@ package funkin.ui.freeplay; import funkin.data.freeplay.AlbumData; +import funkin.data.animation.AnimationData; import funkin.data.freeplay.AlbumRegistry; import funkin.data.IRegistryEntry; import flixel.graphics.FlxGraphic; @@ -75,6 +76,16 @@ class Album implements IRegistryEntry return _data.albumTitleAsset; } + public function hasAlbumTitleAnimations() + { + return _data.albumTitleAnimations.length > 0; + } + + public function getAlbumTitleAnimations():Array + { + return _data.albumTitleAnimations; + } + public function toString():String { return 'Album($id)'; diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index a1e63c9a1..bde946e79 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -7,6 +7,7 @@ import flixel.tweens.FlxTween; import flixel.util.FlxTimer; import flixel.tweens.FlxEase; import funkin.data.freeplay.AlbumRegistry; +import funkin.util.assets.FlxAnimationUtil; import funkin.graphics.FunkinSprite; import funkin.util.SortUtil; import openfl.utils.Assets; @@ -21,9 +22,9 @@ class AlbumRoll extends FlxSpriteGroup * The ID of the album to display. * Modify this value to automatically update the album art and title. */ - public var albumId(default, set):String; + public var albumId(default, set):Null; - function set_albumId(value:String):String + function set_albumId(value:Null):Null { if (this.albumId != value) { @@ -65,6 +66,17 @@ class AlbumRoll extends FlxSpriteGroup */ function updateAlbum():Void { + if (albumId == null) + { + albumArt.visible = false; + albumTitle.visible = false; + if (titleTimer != null) + { + titleTimer.cancel(); + titleTimer = null; + } + } + albumData = AlbumRegistry.instance.fetchEntry(albumId); if (albumData == null) @@ -94,7 +106,15 @@ class AlbumRoll extends FlxSpriteGroup if (Assets.exists(Paths.image(albumData.getAlbumTitleAssetKey()))) { - albumTitle.loadGraphic(Paths.image(albumData.getAlbumTitleAssetKey())); + if (albumData.hasAlbumTitleAnimations()) + { + albumTitle.loadSparrow(albumData.getAlbumTitleAssetKey()); + FlxAnimationUtil.addAtlasAnimations(albumTitle, albumData.getAlbumTitleAnimations()); + } + else + { + albumTitle.loadGraphic(Paths.image(albumData.getAlbumTitleAssetKey())); + } } else { @@ -155,6 +175,8 @@ class AlbumRoll extends FlxSpriteGroup }); } + var titleTimer:Null = null; + /** * Play the intro animation on the album art. */ @@ -164,7 +186,14 @@ class AlbumRoll extends FlxSpriteGroup FlxTween.tween(albumArt, {x: 950, y: 320, angle: -340}, 0.5, {ease: FlxEase.elasticOut}); albumTitle.visible = false; - new FlxTimer().start(0.75, function(_) { + + if (titleTimer != null) + { + titleTimer.cancel(); + titleTimer = null; + } + + titleTimer = new FlxTimer().start(0.75, function(_) { showTitle(); }); } @@ -179,6 +208,8 @@ class AlbumRoll extends FlxSpriteGroup public function showTitle():Void { albumTitle.visible = true; + albumTitle.animation.play('active'); + albumTitle.animation.finishCallback = (_) -> albumTitle.animation.play('idle'); } /** diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index f7554197f..6dd96b36d 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -380,7 +380,7 @@ class FreeplayState extends MusicBeatSubState } albumRoll = new AlbumRoll(); - albumRoll.albumId = 'volume1'; + albumRoll.albumId = null; add(albumRoll); albumRoll.applyExitMovers(exitMovers); @@ -881,6 +881,8 @@ class FreeplayState extends MusicBeatSubState for (spr in grpSpr) { + if (spr == null) continue; + var funnyMoveShit:MoveData = moveData; if (moveData.x == null) funnyMoveShit.x = spr.x; @@ -1019,7 +1021,7 @@ class FreeplayState extends MusicBeatSubState albumRoll.setDifficultyStars(daSong?.songRating); // Set the album graphic and play the animation if relevant. - var newAlbumId:String = daSong?.albumId ?? Constants.DEFAULT_ALBUM_ID; + var newAlbumId:String = daSong?.albumId; if (albumRoll.albumId != newAlbumId) { albumRoll.albumId = newAlbumId; @@ -1162,6 +1164,7 @@ class FreeplayState extends MusicBeatSubState intendedCompletion = 0.0; rememberedSongId = null; rememberedDifficulty = null; + albumRoll.albumId = null; } for (index => capsule in grpCapsules.members) @@ -1311,7 +1314,7 @@ class FreeplaySongData public var songName(default, null):String = ''; public var songCharacter(default, null):String = ''; public var songRating(default, null):Int = 0; - public var albumId(default, null):String = ''; + public var albumId(default, null):Null = null; public var currentDifficulty(default, set):String = Constants.DEFAULT_DIFFICULTY; public var displayedVariations(default, null):Array = [Constants.DEFAULT_VARIATION]; @@ -1345,7 +1348,15 @@ class FreeplaySongData this.songName = songDifficulty.songName; this.songCharacter = songDifficulty.characters.opponent; this.songRating = songDifficulty.difficultyRating; - this.albumId = songDifficulty.album; + if (songDifficulty.album == null) + { + FlxG.log.warn('No album for: ${songDifficulty.songName}'); + this.albumId = Constants.DEFAULT_ALBUM_ID; + } + else + { + this.albumId = songDifficulty.album; + } } }