Files
FNF-i486-Engine/source/GameOverSubstate.hx
JordanSantiagoYT 58eceba068 a big commit Number 2
The functionality of the "JS Engine Recharts" option was refactored
Fixed a random Week 4 crash (hopefully, closing #721)
Added a 5 second wait for update.bat. Hopefully fixes the problem with JSE not updating!
The engine can now originally tell if you played a song in Freeplay and had the "Always Play Cutscenes" option enabled!
The Rating Popup spawning was reworked a bit, and now no longer causes lag when too many popups are spawned at once
WEEKEND 1 IS HERE.

Current issues with Weekend 1:
The camera isn't positioned correctly in the Darnell cutscene
If playing in Story Mode, the game crashes after completing 2hot. I've found that the issue occurs when loading the post-cutscene video, but have no idea how to fix it.
The same thing occurs if you turn on "Always Play Cutscenes" and complete either 2hot or Blazin'.
2024-11-03 17:50:45 -05:00

250 lines
7.1 KiB
Haxe

package;
import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSubState;
import flixel.math.FlxMath;
import flixel.math.FlxPoint;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import Character.Boyfriend;
using StringTools;
class GameOverSubstate extends MusicBeatSubstate
{
public var boyfriend:Character;
var camFollow:FlxObject;
var stagePostfix:String = "";
public static var characterName:String = 'bf-dead';
public static var deathSoundName:String = 'fnf_loss_sfx';
public static var loopSoundName:String = 'gameOver';
public static var endSoundName:String = 'gameOverEnd';
public static var deathDelay:Float = 0;
public static var instance:GameOverSubstate;
public function new(?playStateBoyfriend:Character = null)
{
if(playStateBoyfriend != null && playStateBoyfriend.curCharacter == characterName) //Avoids spawning a second boyfriend cuz animate atlas is laggy
{
this.boyfriend = playStateBoyfriend;
}
super();
}
public static function resetVariables() {
characterName = 'bf-dead';
deathSoundName = 'fnf_loss_sfx';
loopSoundName = 'gameOver';
endSoundName = 'gameOverEnd';
deathDelay = 0;
var _song = PlayState.SONG;
if(_song != null)
{
if(_song.gameOverChar != null && _song.gameOverChar.trim().length > 0) characterName = _song.gameOverChar;
if(_song.gameOverSound != null && _song.gameOverSound.trim().length > 0) deathSoundName = _song.gameOverSound;
if(_song.gameOverLoop != null && _song.gameOverLoop.trim().length > 0) loopSoundName = _song.gameOverLoop;
if(_song.gameOverEnd != null && _song.gameOverEnd.trim().length > 0) endSoundName = _song.gameOverEnd;
}
}
var charX:Float = 0;
var charY:Float = 0;
var overlay:FlxSprite;
var overlayConfirmOffsets:FlxPoint = FlxPoint.get();
override function create()
{
instance = this;
Conductor.songPosition = 0;
if(boyfriend == null)
{
boyfriend = new Character(PlayState.instance.boyfriend.getScreenPosition().x, PlayState.instance.boyfriend.getScreenPosition().y, characterName, true);
boyfriend.x += boyfriend.positionArray[0] - PlayState.instance.boyfriend.positionArray[0];
boyfriend.y += boyfriend.positionArray[1] - PlayState.instance.boyfriend.positionArray[1];
}
boyfriend.skipDance = true;
add(boyfriend);
FlxG.sound.play(Paths.sound(deathSoundName));
FlxG.camera.scroll.set();
FlxG.camera.target = null;
boyfriend.playAnim('firstDeath');
camFollow = new FlxObject(0, 0, 1, 1);
camFollow.setPosition(boyfriend.getGraphicMidpoint().x + boyfriend.cameraPosition[0], boyfriend.getGraphicMidpoint().y + boyfriend.cameraPosition[1]);
FlxG.camera.focusOn(new FlxPoint(FlxG.camera.scroll.x + (FlxG.camera.width / 2), FlxG.camera.scroll.y + (FlxG.camera.height / 2)));
FlxG.camera.follow(camFollow, LOCKON, 0.01);
add(camFollow);
PlayState.instance.setOnLuas('inGameOver', true);
PlayState.instance.callOnLuas('onGameOverStart', []);
FlxG.sound.music.loadEmbedded(Paths.music(loopSoundName), true);
if(characterName == 'pico-dead')
{
overlay = new FlxSprite(boyfriend.x + 205, boyfriend.y - 80);
overlay.frames = Paths.getSparrowAtlas('Pico_Death_Retry');
overlay.animation.addByPrefix('deathLoop', 'Retry Text Loop', 24, true);
overlay.animation.addByPrefix('deathConfirm', 'Retry Text Confirm', 24, false);
overlay.antialiasing = ClientPrefs.globalAntialiasing;
overlayConfirmOffsets.set(250, 200);
overlay.visible = false;
add(overlay);
boyfriend.animation.callback = function(name:String, frameNumber:Int, frameIndex:Int)
{
switch(name)
{
case 'firstDeath':
if(frameNumber >= 36 - 1)
{
overlay.visible = true;
overlay.animation.play('deathLoop');
boyfriend.animation.callback = null;
}
default:
boyfriend.animation.callback = null;
}
}
if(PlayState.instance.gf != null && PlayState.instance.gf.curCharacter == 'nene')
{
var neneKnife:FlxSprite = new FlxSprite(boyfriend.x - 450, boyfriend.y - 250);
neneKnife.frames = Paths.getSparrowAtlas('NeneKnifeToss');
neneKnife.animation.addByPrefix('anim', 'knife toss', 24, false);
neneKnife.antialiasing = ClientPrefs.globalAntialiasing;
neneKnife.animation.finishCallback = function(_)
{
remove(neneKnife);
neneKnife.destroy();
}
insert(0, neneKnife);
neneKnife.animation.play('anim', true);
}
}
super.create();
}
override function update(elapsed:Float)
{
super.update(elapsed);
PlayState.instance.callOnLuas('onUpdate', [elapsed]);
var justPlayedLoop:Bool = false;
if (!boyfriend.isAnimationNull() && boyfriend.getAnimationName() == 'firstDeath' && boyfriend.isAnimationFinished())
{
boyfriend.playAnim('deathLoop');
if(overlay != null && overlay.animation.exists('deathLoop'))
{
overlay.visible = true;
overlay.animation.play('deathLoop');
}
justPlayedLoop = true;
}
if(!isEnding)
{
if (controls.ACCEPT)
{
endBullshit();
}
else if (controls.BACK)
{
#if DISCORD_ALLOWED DiscordClient.resetClientID(); #end
FlxG.camera.visible = false;
FlxG.sound.music.stop();
PlayState.deathCounter = 0;
PlayState.seenCutscene = false;
PlayState.chartingMode = false;
WeekData.loadTheFirstEnabledMod();
if (PlayState.isStoryMode)
FlxG.switchState(new StoryMenuState());
else
FlxG.switchState(new FreeplayState());
FlxG.sound.playMusic(Paths.music('freakyMenu-' + ClientPrefs.daMenuMusic));
PlayState.instance.callOnLuas('onGameOverConfirm', [false]);
}
else if (justPlayedLoop)
{
switch(PlayState.SONG.stage)
{
case 'tank':
coolStartDeath(0.2);
var exclude:Array<Int> = [];
FlxG.sound.play(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, exclude)), 1, false, null, true, function() {
if(!isEnding)
{
FlxG.sound.music.fadeIn(0.2, 1, 4);
}
});
default:
coolStartDeath();
}
}
if (FlxG.sound.music.playing)
{
Conductor.songPosition = FlxG.sound.music.time;
}
}
PlayState.instance.callOnLuas('onUpdatePost', [elapsed]);
}
var isEnding:Bool = false;
function coolStartDeath(?volume:Float = 1):Void
{
FlxG.sound.music.play(true);
FlxG.sound.music.volume = volume;
}
function endBullshit():Void
{
if (!isEnding)
{
isEnding = true;
if(boyfriend.hasAnimation('deathConfirm'))
boyfriend.playAnim('deathConfirm', true);
else if(boyfriend.hasAnimation('deathLoop'))
boyfriend.playAnim('deathLoop', true);
if(overlay != null && overlay.animation.exists('deathConfirm'))
{
overlay.visible = true;
overlay.animation.play('deathConfirm');
overlay.offset.set(overlayConfirmOffsets.x, overlayConfirmOffsets.y);
}
FlxG.sound.music.stop();
FlxG.sound.play(Paths.music(endSoundName));
new FlxTimer().start(0.7, function(tmr:FlxTimer)
{
FlxG.camera.fade(FlxColor.BLACK, 2, false, function()
{
FlxG.resetState();
});
});
PlayState.instance.callOnLuas('onGameOverConfirm', [true]);
}
}
override function destroy()
{
instance = null;
super.destroy();
}
}