diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 704407c14..2630a806a 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -189,10 +189,14 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound> */ override function onFocus():Void { - if (!_alreadyPaused && this._shouldPlay) + if (!_alreadyPaused) { resume(); } + else + { + trace('Not resuming audio on focus!'); + } } /** @@ -200,6 +204,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound> */ override function onFocusLost():Void { + trace('Focus lost, pausing audio!'); _alreadyPaused = _paused; pause(); } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index ca2344b0a..bb9e05638 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -770,8 +770,7 @@ class PlayState extends MusicBeatSubState inputSpitter = []; // Reset music properly. - - FlxG.sound.music.time = Math.max(0, startTimestamp - Conductor.instance.instrumentalOffset); + FlxG.sound.music.time = startTimestamp - Conductor.instance.instrumentalOffset; FlxG.sound.music.pause(); if (!overrideMusic) @@ -1054,7 +1053,10 @@ class PlayState extends MusicBeatSubState if (FlxG.sound.music != null) { musicPausedBySubState = FlxG.sound.music.playing; - FlxG.sound.music.pause(); + if (musicPausedBySubState) + { + FlxG.sound.music.pause(); + } if (vocals != null) vocals.pause(); } @@ -1082,7 +1084,7 @@ class PlayState extends MusicBeatSubState // Resume if (musicPausedBySubState) { - FlxG.sound.music.play(FlxG.sound.music.time); + FlxG.sound.music.play(); } if (FlxG.sound.music != null && !startingSong && !isInCutscene) resyncVocals(); @@ -1284,12 +1286,6 @@ class PlayState extends MusicBeatSubState public override function destroy():Void { - if (currentConversation != null) - { - remove(currentConversation); - currentConversation.kill(); - } - performCleanup(); super.destroy(); @@ -1708,6 +1704,7 @@ class PlayState extends MusicBeatSubState currentConversation = ConversationRegistry.instance.fetchEntry(conversationId); if (currentConversation == null) return; + if (!currentConversation.alive) currentConversation.revive(); currentConversation.completeCallback = onConversationComplete; currentConversation.cameras = [camCutscene]; @@ -1725,8 +1722,13 @@ class PlayState extends MusicBeatSubState function onConversationComplete():Void { isInCutscene = false; - remove(currentConversation); - currentConversation = null; + + if (currentConversation != null) + { + currentConversation.kill(); + remove(currentConversation); + currentConversation = null; + } if (startingSong && !isInCountdown) { @@ -1751,12 +1753,14 @@ class PlayState extends MusicBeatSubState FlxG.sound.music.onComplete = endSong; // A negative instrumental offset means the song skips the first few milliseconds of the track. // This just gets added into the startTimestamp behavior so we don't need to do anything extra. - FlxG.sound.music.time = startTimestamp - Conductor.instance.instrumentalOffset; + FlxG.sound.music.play(true, startTimestamp - Conductor.instance.instrumentalOffset); + + // I am going insane. + FlxG.sound.music.volume = 1.0; + FlxG.sound.music.fadeTween.cancel(); trace('Playing vocals...'); add(vocals); - - FlxG.sound.music.play(FlxG.sound.music.time); vocals.play(); resyncVocals(); @@ -2657,6 +2661,12 @@ class PlayState extends MusicBeatSubState */ function performCleanup():Void { + if (currentConversation != null) + { + remove(currentConversation); + currentConversation.kill(); + } + if (currentChart != null) { // TODO: Uncache the song. diff --git a/source/funkin/play/cutscene/dialogue/Conversation.hx b/source/funkin/play/cutscene/dialogue/Conversation.hx index 150f6bf6f..a85a47c49 100644 --- a/source/funkin/play/cutscene/dialogue/Conversation.hx +++ b/source/funkin/play/cutscene/dialogue/Conversation.hx @@ -150,6 +150,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl if (backdrop != null) { backdrop.destroy(); + remove(backdrop); backdrop = null; } @@ -193,7 +194,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl var nextSpeakerId:String = currentDialogueEntryData.speaker; // Skip the next steps if the current speaker is already displayed. - if (currentSpeaker != null && nextSpeakerId == currentSpeaker.id) return; + if ((currentSpeaker != null && currentSpeaker.alive) && nextSpeakerId == currentSpeaker.id) return; if (currentSpeaker != null) { @@ -244,8 +245,8 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl { var nextDialogueBoxId:String = currentDialogueEntryData?.box; - // Skip the next steps if the current speaker is already displayed. - if (currentDialogueBox != null && nextDialogueBoxId == currentDialogueBox.id) return; + // Skip the next steps if the current dialogue box is already displayed. + if ((currentDialogueBox != null && currentDialogueBox.alive) && nextDialogueBoxId == currentDialogueBox.id) return; if (currentDialogueBox != null) { @@ -343,18 +344,25 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl currentDialogueEntry = 0; this.state = ConversationState.Start; - if (outroTween != null) outroTween.cancel(); // Canc + if (outroTween != null) + { + outroTween.cancel(); + } outroTween = null; - this.alpha = 0.0; if (this.music != null) this.music.stop(); this.music = null; if (currentSpeaker != null) currentSpeaker.kill(); + remove(currentSpeaker); currentSpeaker = null; + if (currentDialogueBox != null) currentDialogueBox.kill(); + remove(currentDialogueBox); currentDialogueBox = null; - if (backdrop != null) backdrop.kill(); + + if (backdrop != null) backdrop.destroy(); + remove(backdrop); backdrop = null; startConversation(); @@ -371,7 +379,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl dispatchEvent(new DialogueScriptEvent(DIALOGUE_SKIP, this, true)); } - static var outroTween:FlxTween; + var outroTween:FlxTween; public function startOutro():Void { @@ -399,7 +407,6 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl public function endOutro():Void { - outroTween = null; ScriptEventDispatcher.callEvent(this, new ScriptEvent(DESTROY, false)); } @@ -534,10 +541,12 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl { propagateEvent(event); - if (outroTween != null) outroTween.cancel(); // Canc + if (outroTween != null) + { + outroTween.cancel(); + } outroTween = null; - this.alpha = 0.0; if (this.music != null) this.music.stop(); this.music = null; @@ -549,7 +558,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl remove(currentDialogueBox); currentDialogueBox = null; - if (backdrop != null) backdrop.kill(); + if (backdrop != null) backdrop.destroy(); remove(backdrop); backdrop = null; @@ -569,16 +578,27 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl */ function propagateEvent(event:ScriptEvent):Void { - if (this.currentDialogueBox != null) + if (this.currentDialogueBox != null && this.currentDialogueBox.exists) { ScriptEventDispatcher.callEvent(this.currentDialogueBox, event); } - if (this.currentSpeaker != null) + if (this.currentSpeaker != null && this.currentSpeaker.exists) { ScriptEventDispatcher.callEvent(this.currentSpeaker, event); } } + /** + * Calls `kill()` on the group's members and then on the group itself. + * You can revive this group later via `revive()` after this. + */ + public override function revive():Void + { + super.revive(); + this.alpha = 1; + this.visible = true; + } + /** * Calls `kill()` on the group's members and then on the group itself. * You can revive this group later via `revive()` after this. @@ -590,6 +610,12 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass impl exists = false; _skipTransformChildren = false; if (group != null) group.kill(); + + if (outroTween != null) + { + outroTween.cancel(); + outroTween = null; + } } public override function toString():String diff --git a/source/funkin/play/cutscene/dialogue/DialogueBox.hx b/source/funkin/play/cutscene/dialogue/DialogueBox.hx index eb603a352..fe4f13be0 100644 --- a/source/funkin/play/cutscene/dialogue/DialogueBox.hx +++ b/source/funkin/play/cutscene/dialogue/DialogueBox.hx @@ -4,7 +4,7 @@ import flixel.FlxSprite; import funkin.data.IRegistryEntry; import flixel.group.FlxSpriteGroup; import flixel.graphics.frames.FlxFramesCollection; -import flixel.text.FlxText; +import funkin.graphics.FunkinSprite; import flixel.addons.text.FlxTypeText; import funkin.util.assets.FlxAnimationUtil; import funkin.modding.events.ScriptEvent; @@ -126,8 +126,7 @@ class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass imple this.boxSprite = null; } - this.boxSprite = new FlxSprite(0, 0); - add(this.boxSprite); + this.boxSprite = new FunkinSprite(0, 0); trace('[DIALOGUE BOX] Loading spritesheet ${_data.assetPath} for ${id}'); @@ -153,6 +152,8 @@ class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass imple this.flipY = _data.flipY; this.globalOffsets = _data.offsets; this.setScale(_data.scale); + + add(this.boxSprite); } public function setText(newText:String):Void @@ -220,6 +221,9 @@ class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass imple public override function revive():Void { super.revive(); + + this.visible = true; + this.alpha = 1.0; } function loadAnimations():Void diff --git a/source/funkin/play/cutscene/dialogue/Speaker.hx b/source/funkin/play/cutscene/dialogue/Speaker.hx index 0d59854a7..f848d79c8 100644 --- a/source/funkin/play/cutscene/dialogue/Speaker.hx +++ b/source/funkin/play/cutscene/dialogue/Speaker.hx @@ -119,6 +119,9 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass implements IRe { super.revive(); + this.visible = true; + this.alpha = 1.0; + loadSpritesheet(); loadAnimations(); } diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 105e6db43..61f83d1ed 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -502,11 +502,11 @@ class SongDifficulty } } - public inline function playInst(volume:Float = 1.0, looped:Bool = false):Void + public function playInst(volume:Float = 1.0, looped:Bool = false):Void { var suffix:String = (variation != null && variation != '' && variation != 'default') ? '-$variation' : ''; - FlxG.sound.music = FunkinSound.load(Paths.inst(this.song.id, suffix), volume, looped); + FlxG.sound.music = FunkinSound.load(Paths.inst(this.song.id, suffix), volume, looped, false, true); // Workaround for a bug where FlxG.sound.music.update() was being called twice. FlxG.sound.list.remove(FlxG.sound.music); diff --git a/source/funkin/ui/debug/dialogue/ConversationDebugState.hx b/source/funkin/ui/debug/dialogue/ConversationDebugState.hx index abda3d3b1..f165865c4 100644 --- a/source/funkin/ui/debug/dialogue/ConversationDebugState.hx +++ b/source/funkin/ui/debug/dialogue/ConversationDebugState.hx @@ -36,11 +36,24 @@ class ConversationDebugState extends MusicBeatState public override function create():Void { - conversation = ConversationRegistry.instance.fetchEntry(conversationId); - conversation.completeCallback = onConversationComplete; - add(conversation); + super.create(); + startConversation(); + } - ScriptEventDispatcher.callEvent(conversation, new ScriptEvent(CREATE, false)); + function startConversation():Void + { + if (conversation != null) return; + + conversation = ConversationRegistry.instance.fetchEntry(conversationId); + if (conversation == null) return; + if (!conversation.alive) conversation.revive(); + + conversation.zIndex = 1000; + add(conversation); + refresh(); + + var event:ScriptEvent = new ScriptEvent(CREATE, false); + ScriptEventDispatcher.callEvent(conversation, event); } function onConversationComplete():Void @@ -61,7 +74,18 @@ class ConversationDebugState extends MusicBeatState if (conversation != null) { - if (controls.CUTSCENE_ADVANCE) conversation.advanceConversation(); + if (controls.CUTSCENE_ADVANCE) + { + conversation.advanceConversation(); + } + else if (controls.PAUSE) + { + conversation.kill(); + remove(conversation); + conversation = null; + + FlxG.switchState(() -> new ConversationDebugState()); + } } } } diff --git a/source/funkin/util/plugins/WatchPlugin.hx b/source/funkin/util/plugins/WatchPlugin.hx index defd9797d..a03115820 100644 --- a/source/funkin/util/plugins/WatchPlugin.hx +++ b/source/funkin/util/plugins/WatchPlugin.hx @@ -35,7 +35,10 @@ class WatchPlugin extends FlxBasic FlxG.watch.addQuick("songPosition", Conductor.instance.songPosition); FlxG.watch.addQuick("songPositionNoOffset", Conductor.instance.songPosition + Conductor.instance.instrumentalOffset); + + FlxG.watch.addQuick("musicLength", FlxG.sound?.music?.length ?? 0.0); FlxG.watch.addQuick("musicTime", FlxG.sound?.music?.time ?? 0.0); + FlxG.watch.addQuick("bpm", Conductor.instance.bpm); FlxG.watch.addQuick("currentMeasureTime", Conductor.instance.currentMeasureTime); FlxG.watch.addQuick("currentBeatTime", Conductor.instance.currentBeatTime);