package funkin.ui.freeplay; import funkin.graphics.FunkinSprite; import flixel.group.FlxSpriteGroup; import flixel.util.FlxSort; import flixel.util.FlxTimer; import funkin.data.freeplay.album.AlbumRegistry; import funkin.graphics.FunkinSprite; import funkin.util.SortUtil; /** * The graphic for the album roll in the FreeplayState. * Simply set `albumID` to fetch the required data and update the textures. */ @:nullSafety 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):Null; function set_albumId(value:Null):Null { if (this.albumId != value || value == null) { this.albumId = value; updateAlbum(); } return value; } final ALBUM_ART_SYMBOL:String = "album art placeholder"; var newAlbumArt:FunkinSprite; var albumTitle:Null = null; var difficultyStars:DifficultyStars; var _exitMovers:Null; var _exitMoversCharSel:Null; var albumData:Null = null; public function new() { super(); newAlbumArt = FunkinSprite.createTextureAtlas((FlxG.width + -360) - FullScreenScaleMode.gameNotchSize.x, 220, "freeplay/albumRoll/freeplayAlbum"); newAlbumArt.visible = false; difficultyStars = new DifficultyStars((FlxG.width - 330) - FullScreenScaleMode.gameNotchSize.x, 209); difficultyStars.visible = false; add(newAlbumArt); add(difficultyStars); buildAlbumTitle("freeplay/albumRoll/volume1-text"); if (albumTitle != null) albumTitle.visible = false; newAlbumArt.anim.onFinish.add(onAlbumFinish); } function onAlbumFinish(animName:String):Void { // Play the idle animation for the current album. if (animName != "idle") { newAlbumArt.anim.play('idle', true); newAlbumArt.anim.curAnim.looped = true; } } /** * Load the album data by ID and update the textures. */ function updateAlbum():Void { if (albumId == null) { this.visible = false; return; } else this.visible = true; albumData = AlbumRegistry.instance.fetchEntry(albumId); if (albumData == null) { FlxG.log.warn('Could not find album data for album ID: ${albumId}'); return; }; // Update the album art. var albumGraphic = Paths.image(albumData.getAlbumArtAssetKey()); newAlbumArt.replaceSymbolGraphic(ALBUM_ART_SYMBOL, albumGraphic); buildAlbumTitle(albumData.getAlbumTitleAssetKey(), albumData.getAlbumTitleOffsets()); applyExitMovers(); refresh(); } public function refresh():Void { sort(SortUtil.byZIndex, FlxSort.ASCENDING); } /** * Apply exit movers for the album roll. * @param exitMovers The exit movers to apply. */ public function applyExitMovers(?exitMovers:FreeplayState.ExitMoverData, ?exitMoversCharSel:FreeplayState.ExitMoverData):Void { if (exitMovers == null) { exitMovers = _exitMovers; } else { _exitMovers = exitMovers; } if (exitMovers == null) return; if (exitMoversCharSel == null) { exitMoversCharSel = _exitMoversCharSel; } else { _exitMoversCharSel = exitMoversCharSel; } if (exitMoversCharSel == null) return; exitMovers.set([newAlbumArt, difficultyStars], { x: FlxG.width, speed: 0.4, wait: 0 }); exitMoversCharSel.set([newAlbumArt, difficultyStars], { y: -175, speed: 0.8, wait: 0.1 }); } var titleTimer:Null = null; /** * Play the intro animation on the album art. */ public function playIntro():Void { this.visible = true; if (albumTitle != null) albumTitle.visible = false; newAlbumArt.visible = true; newAlbumArt.anim.play('intro', true); difficultyStars.visible = false; difficultyStars.flameCheck(); new FlxTimer().start(0.75, function(_) { showTitle(); showStars(); if (albumTitle != null) albumTitle.animation.play('switch'); }); } public function skipIntro():Void { this.visible = true; // Weird workaround newAlbumArt.anim.play('switch', true); if (albumTitle != null) albumTitle.animation.play('switch'); } public function showTitle():Void { if (albumTitle != null) albumTitle.visible = true; } public function buildAlbumTitle(assetKey:String, ?titleOffsets:Null>):Void { if (albumTitle != null) { remove(albumTitle); albumTitle = null; } if (titleOffsets == null) { titleOffsets = [0, 0]; } albumTitle = FunkinSprite.createSparrow((FlxG.width - 355) - FullScreenScaleMode.gameNotchSize.x, 500, assetKey); albumTitle.visible = this.visible && (albumTitle.frames != null && newAlbumArt.visible) && difficultyStars.visible; albumTitle.animation.addByPrefix('idle', 'idle0', 24, true); albumTitle.animation.addByPrefix('switch', 'switch0', 24, false); add(albumTitle); albumTitle.animation.onFinish.add(function(name) { if (name == 'switch' && albumTitle != null) albumTitle.animation.play('idle'); }); albumTitle.animation.play('idle'); albumTitle.zIndex = 1000; albumTitle.x += titleOffsets[0]; albumTitle.y += titleOffsets[1]; if (_exitMovers != null) _exitMovers.set([albumTitle], { x: FlxG.width, speed: 0.4, wait: 0 }); if (_exitMoversCharSel != null) _exitMoversCharSel.set([albumTitle], { y: -190, speed: 0.8, wait: 0.1 }); } public function setDifficultyStars(?difficulty:Int):Void { if (difficulty == null) return; difficultyStars.difficulty = difficulty; } /** * Make the album stars visible. */ public function showStars():Void { difficultyStars.visible = true; // true; difficultyStars.flameCheck(); } }