diff --git a/source/funkin/GitarooPause.hx b/source/funkin/GitarooPause.hx index 5747de5e5..a4dc766be 100644 --- a/source/funkin/GitarooPause.hx +++ b/source/funkin/GitarooPause.hx @@ -3,6 +3,7 @@ package funkin; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import funkin.play.PlayState; +import flixel.addons.transition.FlxTransitionableState; class GitarooPause extends MusicBeatState { @@ -61,6 +62,8 @@ class GitarooPause extends MusicBeatState { if (replaySelect) { + FlxTransitionableState.skipNextTransIn = false; + FlxTransitionableState.skipNextTransOut = false; FlxG.switchState(new PlayState(previousParams)); } else diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index 161da5191..6483ea9e5 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -124,8 +124,6 @@ class GameOverSubState extends MusicBeatSubState override function update(elapsed:Float) { - super.update(elapsed); - if (!hasStartedAnimation) { hasStartedAnimation = true; @@ -205,12 +203,13 @@ class GameOverSubState extends MusicBeatSubState if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished()) { startDeathMusic(1.0, false); + boyfriend.playAnimation('deathLoop' + animationSuffix); } } } - // Dispatch the onUpdate event. - dispatchEvent(new UpdateScriptEvent(elapsed)); + // Start death music before firstDeath gets replaced + super.update(elapsed); } /** diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 4d4cf3d40..5e8f964d1 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -488,8 +488,6 @@ class PlayState extends MusicBeatSubState */ public override function create():Void { - super.create(); - if (instance != null) { // TODO: Do something in this case? IDK. @@ -630,6 +628,9 @@ class PlayState extends MusicBeatSubState startCountdown(); } + // Do this last to prevent beatHit from being called before create() is done. + super.create(); + leftWatermarkText.cameras = [camHUD]; rightWatermarkText.cameras = [camHUD]; @@ -810,6 +811,16 @@ class PlayState extends MusicBeatSubState FlxG.watch.addQuick('bfAnim', currentStage.getBoyfriend().getCurrentAnimation()); } + if (currentStage.getBoyfriend() != null) + { + FlxG.watch.addQuick('bfCameraFocus', currentStage.getBoyfriend().cameraFocusPoint); + } + + if (currentStage.getDad() != null) + { + FlxG.watch.addQuick('dadCameraFocus', currentStage.getDad().cameraFocusPoint); + } + // TODO: Add a song event for Handle GF dance speed. // Handle player death. @@ -857,6 +868,8 @@ class PlayState extends MusicBeatSubState #end var gameOverSubState = new GameOverSubState(); + FlxTransitionableSubState.skipNextTransIn = true; + FlxTransitionableSubState.skipNextTransOut = true; openSubState(gameOverSubState); #if discord_rpc @@ -971,6 +984,9 @@ class PlayState extends MusicBeatSubState if (event.eventCanceled) return; + // Resume + FlxG.sound.music.play(); + if (FlxG.sound.music != null && !startingSong && !isInCutscene) resyncVocals(); // Resume the countdown. @@ -1669,6 +1685,9 @@ class PlayState extends MusicBeatSubState { if (_exiting || vocals == null) return; + // Skip this if the music is paused (GameOver, Pause menu, etc.) + if (!FlxG.sound.music.playing) return; + vocals.pause(); FlxG.sound.music.play(); @@ -1700,6 +1719,8 @@ class PlayState extends MusicBeatSubState */ function onKeyPress(event:PreciseInputEvent):Void { + if (isGamePaused) return; + // Do the minimal possible work here. inputPressQueue.push(event); } @@ -1709,6 +1730,8 @@ class PlayState extends MusicBeatSubState */ function onKeyRelease(event:PreciseInputEvent):Void { + if (isGamePaused) return; + // Do the minimal possible work here. inputReleaseQueue.push(event); } diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index bcb73d543..42dfd2da4 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -227,12 +227,15 @@ class BaseCharacter extends Bopper public function resetCharacter(resetCamera:Bool = true):Void { // Reset the animation offsets. This will modify x and y to be the absolute position of the character. - this.animOffsets = [0, 0]; + // this.animOffsets = [0, 0]; // Now we can set the x and y to be their original values without having to account for animOffsets. this.resetPosition(); - // Make sure we are playing the idle animation (to reapply animOffsets)... + // Then reapply animOffsets... + // applyAnimationOffsets(getCurrentAnimation()); + + // Make sure we are playing the idle animation this.dance(true); // Force to avoid the old animation playing with the wrong offset at the start of the song. // ...then update the hitbox so that this.width and this.height are correct. this.updateHitbox(); @@ -344,7 +347,7 @@ class BaseCharacter extends Bopper if (isDead) { - playDeathAnimation(); + // playDeathAnimation(); return; } @@ -392,20 +395,6 @@ class BaseCharacter extends Bopper FlxG.watch.addQuick('holdTimer-${characterId}', holdTimer); } - /** - * Since no `onBeatHit` or `dance` calls happen in GameOverSubState, - * this regularly gets called instead. - * - * @param force Force the deathLoop animation to play, even if `firstDeath` is still playing. - */ - public function playDeathAnimation(force:Bool = false):Void - { - if (force || (getCurrentAnimation().startsWith('firstDeath') && isAnimationFinished())) - { - playAnimation('deathLoop' + GameOverSubState.animationSuffix); - } - } - public function isSinging():Bool { return getCurrentAnimation().startsWith('sing'); diff --git a/source/funkin/play/stage/Bopper.hx b/source/funkin/play/stage/Bopper.hx index 5fb1022fe..d88618f8a 100644 --- a/source/funkin/play/stage/Bopper.hx +++ b/source/funkin/play/stage/Bopper.hx @@ -158,8 +158,11 @@ class Bopper extends StageProp implements IPlayStateScriptedClass */ public function resetPosition() { - this.x = originalPosition.x + animOffsets[0]; - this.y = originalPosition.y + animOffsets[1]; + var oldAnimOffsets = [animOffsets[0], animOffsets[1]]; + animOffsets = [0, 0]; + this.x = originalPosition.x; + this.y = originalPosition.y; + animOffsets = oldAnimOffsets; } function update_shouldAlternate():Void diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index ef2d28430..dafba1c06 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -78,6 +78,10 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass if (getBoyfriend() != null) { getBoyfriend().resetCharacter(true); + // Reapply the camera offsets. + var charData = _data.characters.bf; + getBoyfriend().cameraFocusPoint.x += charData.cameraOffsets[0]; + getBoyfriend().cameraFocusPoint.y += charData.cameraOffsets[1]; } else { @@ -86,10 +90,18 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass if (getGirlfriend() != null) { getGirlfriend().resetCharacter(true); + // Reapply the camera offsets. + var charData = _data.characters.gf; + getGirlfriend().cameraFocusPoint.x += charData.cameraOffsets[0]; + getGirlfriend().cameraFocusPoint.y += charData.cameraOffsets[1]; } if (getDad() != null) { getDad().resetCharacter(true); + // Reapply the camera offsets. + var charData = _data.characters.dad; + getDad().cameraFocusPoint.x += charData.cameraOffsets[0]; + getDad().cameraFocusPoint.y += charData.cameraOffsets[1]; } // Reset positions of named props. @@ -216,8 +228,12 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass { cast(propSprite, Bopper).setAnimationOffsets(propAnim.name, propAnim.offsets[0], propAnim.offsets[1]); } - cast(propSprite, Bopper).originalPosition.x = dataProp.position[0]; - cast(propSprite, Bopper).originalPosition.y = dataProp.position[1]; + + if (!Std.isOfType(propSprite, BaseCharacter)) + { + cast(propSprite, Bopper).originalPosition.x = dataProp.position[0]; + cast(propSprite, Bopper).originalPosition.y = dataProp.position[1]; + } } if (dataProp.startingAnimation != null) @@ -357,8 +373,12 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass character.x = charData.position[0] - character.characterOrigin.x + character.globalOffsets[0]; character.y = charData.position[1] - character.characterOrigin.y + character.globalOffsets[1]; - character.originalPosition.x = character.x; - character.originalPosition.y = character.y; + @:privateAccess(funkin.play.stage.Bopper) + { + // Undo animOffsets before saving original position. + character.originalPosition.x = character.x + character.animOffsets[0]; + character.originalPosition.y = character.y + character.animOffsets[1]; + } character.cameraFocusPoint.x += charData.cameraOffsets[0]; character.cameraFocusPoint.y += charData.cameraOffsets[1]; diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index ddd50073a..8e5a65c80 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -6,6 +6,7 @@ import flixel.FlxCamera; import flixel.FlxSprite; import flixel.FlxSubState; import flixel.group.FlxSpriteGroup; +import flixel.addons.transition.FlxTransitionableState; import flixel.input.keyboard.FlxKey; import flixel.math.FlxPoint; import flixel.math.FlxRect; @@ -3336,6 +3337,9 @@ class ChartEditorState extends HaxeUIState subStateClosed.add(fixCamera); subStateClosed.add(updateConductor); + FlxTransitionableState.skipNextTransIn = false; + FlxTransitionableState.skipNextTransOut = false; + openSubState(new PlayState( { targetSong: targetSong, diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 29bc4beca..8d2db0543 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -5,6 +5,7 @@ import flixel.addons.transition.FlxTransitionableState; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.text.FlxText; +import flixel.addons.transition.FlxTransitionableState; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxColor; @@ -521,6 +522,9 @@ class StoryMenuState extends MusicBeatState } new FlxTimer().start(1, function(tmr:FlxTimer) { + FlxTransitionableState.skipNextTransIn = false; + FlxTransitionableState.skipNextTransOut = false; + LoadingState.loadAndSwitchState(new PlayState( { targetSong: targetSong,