diff --git a/source/funkin/ui/freeplay/Album.hx b/source/funkin/ui/freeplay/Album.hx index 264094d6e..c226e49ad 100644 --- a/source/funkin/ui/freeplay/Album.hx +++ b/source/funkin/ui/freeplay/Album.hx @@ -9,6 +9,7 @@ import flixel.graphics.FlxGraphic; /** * A class representing the data for an album as displayed in Freeplay. */ +@:nullSafety class Album implements IRegistryEntry { public function new(id:String) @@ -28,7 +29,7 @@ class Album implements IRegistryEntry */ public function getAlbumName():String { - return _data.name; + return _data?.name ?? "Unknown"; } /** @@ -37,7 +38,7 @@ class Album implements IRegistryEntry */ public function getAlbumArtists():Array { - return _data.artists; + return _data?.artists ?? ["None"]; } /** @@ -46,7 +47,7 @@ class Album implements IRegistryEntry */ public function getAlbumArtAssetKey():String { - return _data.albumArtAsset; + return _data?.albumArtAsset ?? 'freeplay/albumRoll/volume1"'; } /** @@ -63,7 +64,7 @@ class Album implements IRegistryEntry */ public function getAlbumTitleAssetKey():String { - return _data.albumTitleAsset; + return _data?.albumTitleAsset ?? "freeplay/albumRoll/volume1-text"; } /** @@ -71,16 +72,17 @@ class Album implements IRegistryEntry */ public function getAlbumTitleOffsets():Null> { - return _data.albumTitleOffsets; + return _data?.albumTitleOffsets ?? [0, 0]; } - public function hasAlbumTitleAnimations() + public function hasAlbumTitleAnimations():Bool { + if (_data == null || _data.albumTitleAnimations == null) return false; return _data.albumTitleAnimations.length > 0; } public function getAlbumTitleAnimations():Array { - return _data.albumTitleAnimations; + return _data?.albumTitleAnimations ?? []; } } diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index bf06305a3..5c53c68a3 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -12,6 +12,7 @@ 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 { /** @@ -32,13 +33,13 @@ class AlbumRoll extends FlxSpriteGroup } var newAlbumArt:FlxAtlasSprite; - var albumTitle:FunkinSprite; + var albumTitle:Null = null; var difficultyStars:DifficultyStars; var _exitMovers:Null; var _exitMoversCharSel:Null; - var albumData:Album; + var albumData:Null = null; final animNames:Map = [ "volume1-active" => "ENTRANCE", @@ -58,16 +59,17 @@ class AlbumRoll extends FlxSpriteGroup newAlbumArt = new FlxAtlasSprite((FlxG.width - 640) - FullScreenScaleMode.gameNotchSize.x, 360, Paths.animateAtlas("freeplay/albumRoll/freeplayAlbum")); newAlbumArt.visible = false; - newAlbumArt.onAnimationComplete.add(onAlbumFinish); - - add(newAlbumArt); difficultyStars = new DifficultyStars((FlxG.width - 1140) - FullScreenScaleMode.gameNotchSize.x, 39); difficultyStars.visible = false; + + add(newAlbumArt); add(difficultyStars); buildAlbumTitle("freeplay/albumRoll/volume1-text"); - albumTitle.visible = false; + if (albumTitle != null) albumTitle.visible = false; + + newAlbumArt.onAnimationComplete.add(onAlbumFinish); } function onAlbumFinish(animName:String):Void @@ -168,7 +170,7 @@ class AlbumRoll extends FlxSpriteGroup */ public function playIntro():Void { - albumTitle.visible = false; + if (albumTitle != null) albumTitle.visible = false; newAlbumArt.visible = true; newAlbumArt.playAnimation('intro', true); @@ -176,7 +178,7 @@ class AlbumRoll extends FlxSpriteGroup new FlxTimer().start(0.75, function(_) { showTitle(); showStars(); - albumTitle.animation.play('switch'); + if (albumTitle != null) albumTitle.animation.play('switch'); }); } @@ -184,12 +186,12 @@ class AlbumRoll extends FlxSpriteGroup { // Weird workaround newAlbumArt.playAnimation('switch', true); - albumTitle.animation.play('switch'); + if (albumTitle != null) albumTitle.animation.play('switch'); } public function showTitle():Void { - albumTitle.visible = true; + if (albumTitle != null) albumTitle.visible = true; } public function buildAlbumTitle(assetKey:String, ?titleOffsets:Null>):Void @@ -212,7 +214,7 @@ class AlbumRoll extends FlxSpriteGroup add(albumTitle); albumTitle.animation.onFinish.add(function(name) { - if (name == 'switch') albumTitle.animation.play('idle'); + if (name == 'switch' && albumTitle != null) albumTitle.animation.play('idle'); }); albumTitle.animation.play('idle'); diff --git a/source/funkin/ui/freeplay/BGScrollingText.hx b/source/funkin/ui/freeplay/BGScrollingText.hx index cfcdd39ac..24b0bdd98 100644 --- a/source/funkin/ui/freeplay/BGScrollingText.hx +++ b/source/funkin/ui/freeplay/BGScrollingText.hx @@ -6,6 +6,7 @@ import flixel.text.FlxText; import flixel.util.FlxSort; // its kinda like marqeee html lol! +@:nullSafety class BGScrollingText extends FlxSpriteGroup { var grpTexts:FlxTypedSpriteGroup; @@ -21,15 +22,15 @@ class BGScrollingText extends FlxSpriteGroup { super(x, y); - this.widthShit = widthShit; - if (size != null) this.size = size; - grpTexts = new FlxTypedSpriteGroup(); add(grpTexts); + this.widthShit = widthShit; + if (size != null) this.size = size; + var testText:FlxText = new FlxText(0, 0, 0, text, this.size); testText.font = "5by7"; - testText.bold = bold; + testText.bold = bold ?? false; testText.updateHitbox(); grpTexts.add(testText); @@ -42,7 +43,7 @@ class BGScrollingText extends FlxSpriteGroup var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, this.size); coolText.font = "5by7"; - coolText.bold = bold; + coolText.bold = bold ?? false; coolText.updateHitbox(); grpTexts.add(coolText); } @@ -73,6 +74,7 @@ class BGScrollingText extends FlxSpriteGroup { for (txt in grpTexts.group) { + if (txt == null) continue; txt.x -= 1 * (speed * (elapsed / (1 / 60))); if (speed > 0) diff --git a/source/funkin/ui/freeplay/CapsuleOptionsMenu.hx b/source/funkin/ui/freeplay/CapsuleOptionsMenu.hx index 831456eb7..554138a65 100644 --- a/source/funkin/ui/freeplay/CapsuleOptionsMenu.hx +++ b/source/funkin/ui/freeplay/CapsuleOptionsMenu.hx @@ -137,6 +137,7 @@ class CapsuleOptionsMenu extends FlxSpriteGroup /** * The difficulty selector arrows to the left and right of the difficulty. */ +@:nullSafety class InstrumentalSelector extends FunkinSprite { var controls:Controls; @@ -146,22 +147,21 @@ class InstrumentalSelector extends FunkinSprite var baseScale:Float = 0.6; - public var moveShitDownTimer:FlxTimer; + public var moveShitDownTimer:Null = null; public function new(parent:FreeplayState, x:Float, y:Float, flipped:Bool, controls:Controls) { super(x, y); this.parent = parent; - this.controls = controls; + whiteShader = new PureColor(FlxColor.WHITE); + frames = Paths.getSparrowAtlas('freeplay/freeplaySelector'); animation.addByPrefix('shine', 'arrow pointer loop', 24); animation.play('shine'); - whiteShader = new PureColor(FlxColor.WHITE); - shader = whiteShader; flipX = flipped; diff --git a/source/funkin/ui/freeplay/CapsuleText.hx b/source/funkin/ui/freeplay/CapsuleText.hx index 1c96dbc1e..4ac32445a 100644 --- a/source/funkin/ui/freeplay/CapsuleText.hx +++ b/source/funkin/ui/freeplay/CapsuleText.hx @@ -12,13 +12,14 @@ import flixel.tweens.FlxTween; import openfl.display.BlendMode; import flixel.util.FlxColor; +@:nullSafety class CapsuleText extends FlxSpriteGroup { public var blurredText:FlxText; var whiteText:FlxText; - public var text(default, set):String; + public var text(default, set):Null; var maskShaderSongName:LeftMaskShader = new LeftMaskShader(); @@ -35,9 +36,9 @@ class CapsuleText extends FlxSpriteGroup { super(x, y); - blurredText = initText(songTitle, size); + blurredText = CapsuleText.initText(songTitle, size); blurredText.shader = new GaussianBlurShader(1); - whiteText = initText(songTitle, size); + whiteText = CapsuleText.initText(songTitle, size); // whiteText.shader = new GaussianBlurShader(0.3); text = songTitle; @@ -47,7 +48,7 @@ class CapsuleText extends FlxSpriteGroup add(whiteText); } - function initText(songTitle, size:Float):FlxText + static function initText(songTitle:String, size:Float):FlxText { var text:FlxText = new FlxText(0, 0, 0, songTitle, Std.int(size)); text.font = "5by7"; @@ -82,6 +83,7 @@ class CapsuleText extends FlxSpriteGroup function checkClipWidth(?wid:Int):Void { if (wid == null) wid = clipWidth; + if (whiteText == null || blurredText == null) return; if (whiteText.width > wid) { @@ -94,7 +96,9 @@ class CapsuleText extends FlxSpriteGroup { tooLong = false; + @:nullSafety(Off) blurredText.clipRect = null; + @:nullSafety(Off) whiteText.clipRect = null; } } @@ -120,7 +124,7 @@ class CapsuleText extends FlxSpriteGroup } var moveTimer:FlxTimer = new FlxTimer(); - var moveTween:FlxTween; + var moveTween:Null; public function initMove():Void { @@ -178,7 +182,7 @@ class CapsuleText extends FlxSpriteGroup } var flickerState:Bool = false; - var flickerTimer:FlxTimer; + var flickerTimer:Null; public function flickerText():Void { diff --git a/source/funkin/ui/freeplay/DifficultyStars.hx b/source/funkin/ui/freeplay/DifficultyStars.hx index e7a2b8888..c232034b7 100644 --- a/source/funkin/ui/freeplay/DifficultyStars.hx +++ b/source/funkin/ui/freeplay/DifficultyStars.hx @@ -4,6 +4,7 @@ import flixel.group.FlxSpriteGroup; import funkin.graphics.adobeanimate.FlxAtlasSprite; import funkin.graphics.shaders.HSVShader; +@:nullSafety class DifficultyStars extends FlxSpriteGroup { /** @@ -30,10 +31,11 @@ class DifficultyStars extends FlxSpriteGroup hsvShader = new HSVShader(); flames = new FreeplayFlames(0, 0); - add(flames); stars = new FlxAtlasSprite(0, 0, Paths.animateAtlas("freeplay/freeplayStars")); stars.anim.play("diff stars"); + + add(flames); add(stars); stars.shader = hsvShader; diff --git a/source/funkin/ui/freeplay/FreeplayDJ.hx b/source/funkin/ui/freeplay/FreeplayDJ.hx index be7e332cf..c91bf991b 100644 --- a/source/funkin/ui/freeplay/FreeplayDJ.hx +++ b/source/funkin/ui/freeplay/FreeplayDJ.hx @@ -6,6 +6,7 @@ import funkin.audio.FunkinSound; import funkin.data.freeplay.player.PlayerRegistry; import funkin.data.freeplay.player.PlayerData.PlayerFreeplayDJData; +@:nullSafety class FreeplayDJ extends FlxAtlasSprite { // Represents the sprite's current status. @@ -29,25 +30,25 @@ class FreeplayDJ extends FlxAtlasSprite var timeIdling:Float = 0; final characterId:String = Constants.DEFAULT_CHARACTER; - final playableCharData:PlayerFreeplayDJData; + final playableCharData:Null; public function new(x:Float, y:Float, characterId:String) { this.characterId = characterId; var playableChar = PlayerRegistry.instance.fetchEntry(characterId); - playableCharData = playableChar.getFreeplayDJData(); + playableCharData = playableChar?.getFreeplayDJData(); - super(x, y, playableCharData.getAtlasPath()); + super(x, y, playableCharData?.getAtlasPath()); onAnimationFrame.add(function(name, number) { - if (name == playableCharData.getAnimationPrefix('cartoon')) + if (name == playableCharData?.getAnimationPrefix('cartoon')) { - if (number == playableCharData.getCartoonSoundClickFrame()) + if (number == playableCharData?.getCartoonSoundClickFrame()) { FunkinSound.playOnce(Paths.sound('remote_click')); } - if (number == playableCharData.getCartoonSoundCartoonFrame()) + if (number == playableCharData?.getCartoonSoundCartoonFrame()) { runTvLogic(); } @@ -86,49 +87,49 @@ class FreeplayDJ extends FlxAtlasSprite { case Intro: // Play the intro animation then leave this state immediately. - var animPrefix = playableCharData.getAnimationPrefix('intro'); - if (getCurrentAnimation() != animPrefix || !this.anim.isPlaying) playFlashAnimation(animPrefix, true); + var animPrefix = playableCharData?.getAnimationPrefix('intro'); + if (animPrefix != null && (getCurrentAnimation() != animPrefix || !this.anim.isPlaying)) playFlashAnimation(animPrefix, true); timeIdling = 0; case Idle: // We are in this state the majority of the time. - var animPrefix = playableCharData.getAnimationPrefix('idle'); - if (getCurrentAnimation() != animPrefix) + var animPrefix = playableCharData?.getAnimationPrefix('idle'); + if (animPrefix != null && getCurrentAnimation() != animPrefix) { playFlashAnimation(animPrefix, true, false, true); } timeIdling += elapsed; case NewUnlock: - var animPrefix = playableCharData.getAnimationPrefix('newUnlock'); - if (!hasAnimation(animPrefix)) + var animPrefix = playableCharData?.getAnimationPrefix('newUnlock'); + if (animPrefix != null && !hasAnimation(animPrefix)) { currentState = Idle; } - if (getCurrentAnimation() != animPrefix) + if (animPrefix != null && getCurrentAnimation() != animPrefix) { playFlashAnimation(animPrefix, true, false, true); } case Confirm: - var animPrefix = playableCharData.getAnimationPrefix('confirm'); - if (getCurrentAnimation() != animPrefix) playFlashAnimation(animPrefix, false); + var animPrefix = playableCharData?.getAnimationPrefix('confirm'); + if (animPrefix != null && getCurrentAnimation() != animPrefix) playFlashAnimation(animPrefix, false); timeIdling = 0; case FistPumpIntro: - var animPrefixA = playableCharData.getAnimationPrefix('fistPump'); - var animPrefixB = playableCharData.getAnimationPrefix('loss'); + var animPrefixA = playableCharData?.getAnimationPrefix('fistPump'); + var animPrefixB = playableCharData?.getAnimationPrefix('loss'); if (getCurrentAnimation() == animPrefixA) { - var endFrame = playableCharData.getFistPumpIntroEndFrame(); + var endFrame = playableCharData?.getFistPumpIntroEndFrame() ?? 0; if (endFrame > -1 && anim.curFrame >= endFrame) { - playFlashAnimation(animPrefixA, true, false, false, playableCharData.getFistPumpIntroStartFrame()); + playFlashAnimation(animPrefixA, true, false, false, playableCharData?.getFistPumpIntroStartFrame()); } } else if (getCurrentAnimation() == animPrefixB) { - var endFrame = playableCharData.getFistPumpIntroBadEndFrame(); + var endFrame = playableCharData?.getFistPumpIntroBadEndFrame() ?? 0; if (endFrame > -1 && anim.curFrame >= endFrame) { - playFlashAnimation(animPrefixB, true, false, false, playableCharData.getFistPumpIntroBadStartFrame()); + playFlashAnimation(animPrefixB, true, false, false, playableCharData?.getFistPumpIntroBadStartFrame()); } } else @@ -137,23 +138,23 @@ class FreeplayDJ extends FlxAtlasSprite } case FistPump: - var animPrefixA = playableCharData.getAnimationPrefix('fistPump'); - var animPrefixB = playableCharData.getAnimationPrefix('loss'); + var animPrefixA = playableCharData?.getAnimationPrefix('fistPump'); + var animPrefixB = playableCharData?.getAnimationPrefix('loss'); if (getCurrentAnimation() == animPrefixA) { - var endFrame = playableCharData.getFistPumpLoopEndFrame(); + var endFrame = playableCharData?.getFistPumpLoopEndFrame() ?? 0; if (endFrame > -1 && anim.curFrame >= endFrame) { - playFlashAnimation(animPrefixA, true, false, false, playableCharData.getFistPumpLoopStartFrame()); + playFlashAnimation(animPrefixA, true, false, false, playableCharData?.getFistPumpLoopStartFrame()); } } else if (getCurrentAnimation() == animPrefixB) { - var endFrame = playableCharData.getFistPumpLoopBadEndFrame(); + var endFrame = playableCharData?.getFistPumpLoopBadEndFrame() ?? 0; if (endFrame > -1 && anim.curFrame >= endFrame) { - playFlashAnimation(animPrefixB, true, false, false, playableCharData.getFistPumpLoopBadStartFrame()); + playFlashAnimation(animPrefixB, true, false, false, playableCharData?.getFistPumpLoopBadStartFrame()); } } else @@ -162,8 +163,8 @@ class FreeplayDJ extends FlxAtlasSprite } case IdleEasterEgg: - var animPrefix = playableCharData.getAnimationPrefix('idleEasterEgg'); - if (getCurrentAnimation() != animPrefix) + var animPrefix = playableCharData?.getAnimationPrefix('idleEasterEgg'); + if (animPrefix != null && getCurrentAnimation() != animPrefix) { onIdleEasterEgg.dispatch(); playFlashAnimation(animPrefix, false); @@ -171,7 +172,7 @@ class FreeplayDJ extends FlxAtlasSprite } timeIdling = 0; case Cartoon: - var animPrefix = playableCharData.getAnimationPrefix('cartoon'); + var animPrefix = playableCharData?.getAnimationPrefix('cartoon'); if (animPrefix == null) { currentState = IdleEasterEgg; @@ -190,7 +191,7 @@ class FreeplayDJ extends FlxAtlasSprite { // var name = anim.curSymbol.name; - if (name == playableCharData.getAnimationPrefix('intro')) + if (name == playableCharData?.getAnimationPrefix('intro')) { if (PlayerRegistry.instance.hasNewCharacter()) { @@ -202,7 +203,7 @@ class FreeplayDJ extends FlxAtlasSprite } onIntroDone.dispatch(); } - else if (name == playableCharData.getAnimationPrefix('idle')) + else if (name == playableCharData?.getAnimationPrefix('idle')) { // trace('Finished idle'); @@ -215,47 +216,48 @@ class FreeplayDJ extends FlxAtlasSprite currentState = Cartoon; } } - else if (name == playableCharData.getAnimationPrefix('confirm')) + else if (name == playableCharData?.getAnimationPrefix('confirm')) { // trace('Finished confirm'); } - else if (name == playableCharData.getAnimationPrefix('fistPump')) + else if (name == playableCharData?.getAnimationPrefix('fistPump')) { // trace('Finished fist pump'); currentState = Idle; } - else if (name == playableCharData.getAnimationPrefix('idleEasterEgg')) + else if (name == playableCharData?.getAnimationPrefix('idleEasterEgg')) { // trace('Finished spook'); currentState = Idle; } - else if (name == playableCharData.getAnimationPrefix('loss')) + else if (name == playableCharData?.getAnimationPrefix('loss')) { // trace('Finished loss reaction'); currentState = Idle; } - else if (name == playableCharData.getAnimationPrefix('cartoon')) + else if (name == playableCharData?.getAnimationPrefix('cartoon')) { // trace('Finished cartoon'); - var frame:Int = FlxG.random.bool(33) ? playableCharData.getCartoonLoopBlinkFrame() : playableCharData.getCartoonLoopFrame(); + var frame:Int = FlxG.random.bool(33) ? (playableCharData?.getCartoonLoopBlinkFrame() ?? 0) : (playableCharData?.getCartoonLoopFrame() ?? 0); // Character switches channels when the video ends, or at a 10% chance each time his idle loops. if (FlxG.random.bool(5)) { - frame = playableCharData.getCartoonChannelChangeFrame(); + frame = playableCharData?.getCartoonChannelChangeFrame() ?? 0; // boyfriend switches channel code? // runTvLogic(); } trace('Replay idle: ${frame}'); - playFlashAnimation(playableCharData.getAnimationPrefix('cartoon'), true, false, false, frame); + var animPrefix = playableCharData?.getAnimationPrefix('cartoon'); + if (animPrefix != null) playFlashAnimation(animPrefix, true, false, false, frame); // trace('Finished confirm'); } - else if (name == playableCharData.getAnimationPrefix('newUnlock')) + else if (name == playableCharData?.getAnimationPrefix('newUnlock')) { // Animation should loop. } - else if (name == playableCharData.getAnimationPrefix('charSelect')) + else if (name == playableCharData?.getAnimationPrefix('charSelect')) { onCharSelectComplete(); } @@ -300,7 +302,7 @@ class FreeplayDJ extends FlxAtlasSprite { // plays it smidge after the click FunkinSound.playOnce(Paths.sound('channel_switch'), 1.0, function() { - cartoonSnd.destroy(); + if (cartoonSnd != null) cartoonSnd.destroy(); loadCartoon(); }); } @@ -311,7 +313,8 @@ class FreeplayDJ extends FlxAtlasSprite function loadCartoon() { cartoonSnd = FunkinSound.load(Paths.sound(getRandomFlashToon()), 1.0, false, true, true, function() { - playFlashAnimation(playableCharData.getAnimationPrefix('cartoon'), true, false, false, 60); + var animPrefix = playableCharData?.getAnimationPrefix('cartoon'); + if (animPrefix != null) playFlashAnimation(animPrefix, true, false, false, 60); }); // Fade out music to 40% volume over 1 second. @@ -319,7 +322,7 @@ class FreeplayDJ extends FlxAtlasSprite FlxG.sound.music.fadeOut(1.0, 0.1); // Play the cartoon at a random time between the start and 5 seconds from the end. - cartoonSnd.time = FlxG.random.float(0, Math.max(cartoonSnd.length - (5 * Constants.MS_PER_SEC), 0.0)); + if (cartoonSnd != null) cartoonSnd.time = FlxG.random.float(0, Math.max(cartoonSnd.length - (5 * Constants.MS_PER_SEC), 0.0)); } final cartoonList:Array = openfl.utils.Assets.list().filter(function(path) return path.startsWith("assets/sounds/cartoons/")); @@ -350,10 +353,10 @@ class FreeplayDJ extends FlxAtlasSprite public function toCharSelect():Void { - if (hasAnimation(playableCharData.getAnimationPrefix('charSelect'))) + var animPrefix = playableCharData?.getAnimationPrefix('charSelect'); + if (animPrefix != null && hasAnimation(animPrefix)) { currentState = CharSelect; - var animPrefix = playableCharData.getAnimationPrefix('charSelect'); playFlashAnimation(animPrefix, true, false, false, 0); } else @@ -375,8 +378,8 @@ class FreeplayDJ extends FlxAtlasSprite } currentState = FistPumpIntro; - var animPrefix = playableCharData.getAnimationPrefix('fistPump'); - playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpIntroStartFrame()); + var animPrefix = playableCharData?.getAnimationPrefix('fistPump'); + if (animPrefix != null) playFlashAnimation(animPrefix, true, false, false, playableCharData?.getFistPumpIntroStartFrame()); } public function fistPump():Void @@ -389,8 +392,8 @@ class FreeplayDJ extends FlxAtlasSprite } currentState = FistPump; - var animPrefix = playableCharData.getAnimationPrefix('fistPump'); - playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpLoopStartFrame()); + var animPrefix = playableCharData?.getAnimationPrefix('fistPump'); + if (animPrefix != null) playFlashAnimation(animPrefix, true, false, false, playableCharData?.getFistPumpLoopStartFrame()); } public function fistPumpLossIntro():Void @@ -403,8 +406,8 @@ class FreeplayDJ extends FlxAtlasSprite } currentState = FistPumpIntro; - var animPrefix = playableCharData.getAnimationPrefix('loss'); - playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpIntroBadStartFrame()); + var animPrefix = playableCharData?.getAnimationPrefix('loss'); + if (animPrefix != null) playFlashAnimation(animPrefix, true, false, false, playableCharData?.getFistPumpIntroBadStartFrame()); } public function fistPumpLoss():Void @@ -417,8 +420,8 @@ class FreeplayDJ extends FlxAtlasSprite } currentState = FistPump; - var animPrefix = playableCharData.getAnimationPrefix('loss'); - playFlashAnimation(animPrefix, true, false, false, playableCharData.getFistPumpLoopBadStartFrame()); + var animPrefix = playableCharData?.getAnimationPrefix('loss'); + if (animPrefix != null) playFlashAnimation(animPrefix, true, false, false, playableCharData?.getFistPumpLoopBadStartFrame()); } override public function getCurrentAnimation():String @@ -436,7 +439,7 @@ class FreeplayDJ extends FlxAtlasSprite function applyAnimOffset() { var AnimName = getCurrentAnimation(); - var daOffset = playableCharData.getAnimationOffsetsByPrefix(AnimName); + var daOffset = playableCharData?.getAnimationOffsetsByPrefix(AnimName); if (daOffset != null) { var xValue = daOffset[0]; diff --git a/source/funkin/ui/freeplay/FreeplayFlames.hx b/source/funkin/ui/freeplay/FreeplayFlames.hx index e2e1b74d5..fa0f16168 100644 --- a/source/funkin/ui/freeplay/FreeplayFlames.hx +++ b/source/funkin/ui/freeplay/FreeplayFlames.hx @@ -4,6 +4,7 @@ import flixel.group.FlxSpriteGroup; import flixel.FlxSprite; import flixel.util.FlxTimer; +@:nullSafety class FreeplayFlames extends FlxSpriteGroup { var flameX(default, set):Float = (FlxG.width - 363) - funkin.ui.FullScreenScaleMode.gameNotchSize.x; diff --git a/source/funkin/ui/freeplay/FreeplayScore.hx b/source/funkin/ui/freeplay/FreeplayScore.hx index 7744d67eb..d50119c88 100644 --- a/source/funkin/ui/freeplay/FreeplayScore.hx +++ b/source/funkin/ui/freeplay/FreeplayScore.hx @@ -3,6 +3,7 @@ package funkin.ui.freeplay; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +@:nullSafety class FreeplayScore extends FlxTypedSpriteGroup { public var scoreShit(default, set):Int = 0; @@ -12,6 +13,7 @@ class FreeplayScore extends FlxTypedSpriteGroup if (group == null || group.members == null) return val; var loopNum:Int = group.members.length - 1; var dumbNumb = Std.parseInt(Std.string(val)); + if (dumbNumb == null) dumbNumb = 0; var prevNum:ScoreNum; dumbNumb = Std.int(Math.min(dumbNumb, Math.pow(10, group.members.length) - 1)); @@ -69,6 +71,7 @@ class FreeplayScore extends FlxTypedSpriteGroup } } +@:nullSafety class ScoreNum extends FlxSprite { public var digit(default, set):Int = 0; @@ -130,7 +133,7 @@ class ScoreNum extends FlxSprite animation.addByPrefix(stringNum, '$stringNum DIGITAL', 24, false); } - this.digit = initDigit; + this.digit = initDigit ?? 0; animation.play(numToString[digit], true); diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 7c73c7b09..85cc8f6de 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -2779,6 +2779,7 @@ class FreeplayState extends MusicBeatSubState /** * The difficulty selector arrows to the left and right of the difficulty. */ +@:nullSafety class DifficultySelector extends FlxSprite { var controls:Controls; @@ -2796,16 +2797,15 @@ class DifficultySelector extends FlxSprite this.parent = parent; this.controls = controls; + whiteShader = new PureColor(FlxColor.WHITE); - frames = Paths.getSparrowAtlas(styleData == null ? 'freeplay/freeplaySelector' : styleData.getSelectorAssetKey()); + this.frames = Paths.getSparrowAtlas(styleData?.getSelectorAssetKey() ?? "freeplay/freeplaySelector"); animation.addByPrefix('shine', 'arrow pointer loop', 24); animation.play('shine'); - whiteShader = new PureColor(FlxColor.WHITE); + this.shader = whiteShader; - shader = whiteShader; - - flipX = flipped; + this.flipX = flipped; } override function update(elapsed:Float):Void @@ -2897,6 +2897,7 @@ enum abstract FilterType(String) /** * Data about a specific song in the freeplay menu. */ +@:nullSafety class FreeplaySongData { /** @@ -2993,7 +2994,8 @@ class FreeplaySongData // and is only accessible with the correct valid variation inputs var variations:Array = data.getVariationsByCharacterId(FreeplayState.rememberedCharacterId); - var variation:String = data.getFirstValidVariation(FreeplayState.rememberedDifficulty, null, variations); + var variation:Null = data.getFirstValidVariation(FreeplayState.rememberedDifficulty, null, variations); + if (variation == null) variation = Constants.DEFAULT_VARIATION; return data.isSongNew(FreeplayState.rememberedDifficulty, variation); } @@ -3026,7 +3028,7 @@ class FreeplaySongData function get_scoringRank():Null { var variations:Array = data.getVariationsByCharacterId(FreeplayState.rememberedCharacterId); - var variation:String = data.getFirstValidVariation(FreeplayState.rememberedDifficulty, null, variations); + var variation:Null = data.getFirstValidVariation(FreeplayState.rememberedDifficulty, null, variations); return Save.instance.getSongRank(data.id, FreeplayState.rememberedDifficulty, variation); } @@ -3092,6 +3094,7 @@ typedef MoveData = /** * The sprite for the difficulty */ +@:nullSafety class DifficultySprite extends FlxSprite { /** diff --git a/source/funkin/ui/freeplay/FreeplayStyle.hx b/source/funkin/ui/freeplay/FreeplayStyle.hx index aabefa642..f2fb8b7fa 100644 --- a/source/funkin/ui/freeplay/FreeplayStyle.hx +++ b/source/funkin/ui/freeplay/FreeplayStyle.hx @@ -9,17 +9,18 @@ import flixel.util.FlxColor; /** * A class representing the data for a style of the Freeplay menu. */ +@:nullSafety class FreeplayStyle implements IRegistryEntry { /** * The internal ID for this freeplay style. */ - public final id:String; + // public final id:String; /** * The full data for a freeplay style. */ - public final _data:FreeplayStyleData; + // public final _data:FreeplayStyleData; public function new(id:String) { @@ -47,7 +48,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getBgAssetKey():String { - return _data.bgAsset; + return _data?.bgAsset ?? "freeplay/freeplayBGweek1-bf"; } /** @@ -56,7 +57,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getSelectorAssetKey():String { - return _data.selectorAsset; + return _data?.selectorAsset ?? "freeplay/freeplaySelector/freeplaySelector"; } /** @@ -65,7 +66,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getCapsuleAssetKey():String { - return _data.capsuleAsset; + return _data?.capsuleAsset ?? "freeplay/freeplayCapsule/capsule/freeplayCapsule"; } /** @@ -74,7 +75,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getNumbersAssetKey():String { - return _data.numbersAsset; + return _data?.numbersAsset ?? "digital_numbers"; } /** @@ -84,7 +85,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getCapsuleDeselCol():FlxColor { - return FlxColor.fromString(_data.capsuleTextColors[0]); + return FlxColor.fromString(_data?.capsuleTextColors[0] ?? "#00ccff") ?? 0x00CCFF; } /** @@ -93,7 +94,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getStartDelay():Float { - return _data.startDelay; + return _data?.startDelay ?? 0.0; } public function toString():String @@ -108,7 +109,7 @@ class FreeplayStyle implements IRegistryEntry */ public function getCapsuleSelCol():FlxColor { - return FlxColor.fromString(_data.capsuleTextColors[1]); + return FlxColor.fromString(_data?.capsuleTextColors[1] ?? "#00ccff") ?? 0x00CCFF; } public function destroy():Void {}