Skip to content
4 changes: 2 additions & 2 deletions source/funkin/backend/MusicBeatTransition.hx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MusicBeatTransition extends MusicBeatSubstate {

public override function create() {
if (newState != null)
add(new FunkinParentDisabler(true, false));
add(new FunkinParentDisabler([], true, false));

transitionCamera = new FlxCamera();
transitionCamera.bgColor = 0;
Expand Down Expand Up @@ -142,4 +142,4 @@ class MusicBeatTransition extends MusicBeatSubstate {
transitionScript.destroy();
super.destroy();
}
}
}
16 changes: 16 additions & 0 deletions source/funkin/backend/scripting/events/gameplay/PauseGameEvent.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package funkin.backend.scripting.events.gameplay;

import funkin.backend.utils.FunkinParentDisabler.ParentDisableable;

final class PauseGameEvent extends CancellableEvent {
/**
* List of ParentDisableable instances that FunkinParentDisabler will exclude from
* its disabling list on instanciation. Instances in the list will startDelay enabled.
*/
public var excludeList:Array<ParentDisableable>;

/**
* Whether the pause will be allowed to trigger the Gitaroo pause menu easter egg.
*/
public var allowGitaroo:Bool;
}
41 changes: 26 additions & 15 deletions source/funkin/backend/utils/FunkinParentDisabler.hx
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,31 @@ class FunkinParentDisabler extends FlxBasic {
var __cameras:Array<FlxCamera>;
var __timers:Array<FlxTimer>;
var __sounds:Array<FlxSound>;
var __excludeList:Array<ParentDisableable>;
var __replaceUponDestroy:Bool;
var __restoreUponDestroy:Bool;
public function new(replaceUponDestroy:Bool = false, restoreUponDestroy:Bool = true) {

public function new(?excludeList:Array<ParentDisableable>, replaceUponDestroy:Bool = false, restoreUponDestroy:Bool = true) {
super();
__replaceUponDestroy = replaceUponDestroy;
__restoreUponDestroy = restoreUponDestroy;
__excludeList = excludeList == null ? [] : excludeList;
@:privateAccess {
// tweens
__tweens = FlxTween.globalManager._tweens.copy();
FlxTween.globalManager._tweens = [];
__tweens = FlxTween.globalManager._tweens.copy().filter(t -> !excludeList.contains(t));
FlxTween.globalManager._tweens = [for (t in excludeList) if (t is FlxTween) cast t];

// timers
__timers = FlxTimer.globalManager._timers.copy();
FlxTimer.globalManager._timers = [];
__timers = FlxTimer.globalManager._timers.copy().filter(t -> !excludeList.contains(t));
FlxTimer.globalManager._timers = [for (t in excludeList) if (t is FlxTimer) cast t];

// cameras
__cameras = [for(c in FlxG.cameras.list) if (!c.paused) c];
for(c in __cameras) c.paused = true;
__cameras = [for (c in FlxG.cameras.list) if (!excludeList.contains(c) && !c.paused) c];
for (c in __cameras) c.paused = true;

// sounds
__sounds = [for(s in FlxG.sound.list) if (s.playing && !s.persist) s];
for(s in __sounds) s.pause();
__sounds = [for (s in FlxG.sound.list) if (!excludeList.contains(s) && s.playing && !s.persist) s];
for (s in __sounds) s.pause();
}
}

Expand All @@ -50,25 +53,33 @@ class FunkinParentDisabler extends FlxBasic {
__cameras = [];
__timers = [];
__sounds = [];
__excludeList = [];
}

public override function destroy() {
super.destroy();
@:privateAccess {
if (!__restoreUponDestroy) {
for(t in __tweens) { t.cancel(); t.destroy(); };
for(t in __timers) { t.cancel(); t.destroy(); };
for (t in __tweens) { t.cancel(); t.destroy(); };
for (t in __timers) { t.cancel(); t.destroy(); };
return;
}
if (__replaceUponDestroy) {
FlxTween.globalManager._tweens = __tweens;
FlxTimer.globalManager._timers = __timers;
} else {
for(t in __tweens) FlxTween.globalManager._tweens.push(t);
for(t in __timers) FlxTimer.globalManager._timers.push(t);
for (t in __tweens) FlxTween.globalManager._tweens.push(t);
for (t in __timers) FlxTimer.globalManager._timers.push(t);
}
for(c in __cameras) c.paused = false;
for(s in __sounds) s.play();
for (c in __cameras) c.paused = false;
for (s in __sounds) s.play();
}
}
}

abstract ParentDisableable(Any) {
@:from static inline function tween(t:FlxTween):ParentDisableable return cast t;
@:from static inline function timer(t:FlxTimer):ParentDisableable return cast t;
@:from static inline function camera(c:FlxCamera):ParentDisableable return cast c;
@:from static inline function sound(s:FlxSound):ParentDisableable return cast s;
}
6 changes: 3 additions & 3 deletions source/funkin/game/PlayState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1304,21 +1304,21 @@ class PlayState extends MusicBeatState
* Pauses the game.
*/
public function pauseGame() {
var e = gameAndCharsEvent("onGamePause", new CancellableEvent());
var e = gameAndCharsEvent("onGamePause", EventManager.get(PauseGameEvent).recycle([], allowGitaroo));
if (e.cancelled) return;

persistentUpdate = false;
persistentDraw = true;
paused = true;

// 1 / 1000 chance for Gitaroo Man easter egg
if (!chartingMode && allowGitaroo && FlxG.random.bool(Flags.GITAROO_CHANCE))
if (!chartingMode && e.allowGitaroo && FlxG.random.bool(Flags.GITAROO_CHANCE))
{
// gitaroo man easter egg
FlxG.switchState(new GitarooPause());
}
else {
openSubState(new PauseSubState());
openSubState(new PauseSubState(null, null, e.excludeList));
}

updateDiscordPresence();
Expand Down
8 changes: 6 additions & 2 deletions source/funkin/menus/PauseSubState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import funkin.backend.scripting.events.menu.MenuChangeEvent;
import funkin.backend.scripting.events.menu.pause.*;
import funkin.backend.system.Conductor;
import funkin.backend.utils.FunkinParentDisabler;
import funkin.backend.utils.FunkinParentDisabler.ParentDisableable;
import funkin.editors.charter.Charter;
import funkin.menus.StoryMenuState;
import funkin.options.OptionsMenu;
Expand All @@ -27,6 +28,7 @@ class PauseSubState extends MusicBeatSubstate
var deathCounter:FunkinText;
var multiplayerText:FunkinText;

var parentDisablerExcludeList:Array<ParentDisableable>;
var menuItems:Array<String>;

var curSelected:Int = 0;
Expand All @@ -40,8 +42,10 @@ class PauseSubState extends MusicBeatSubstate

private var __cancelDefault:Bool = false;

public function new(?items:Array<String>, ?selectCall:NameEvent->Void) {
public function new(?items:Array<String>, ?selectCall:NameEvent->Void, ?excludeList:Array<ParentDisableable>) {
super();

parentDisablerExcludeList = excludeList != null ? excludeList : [];
menuItems = items != null ? items : Flags.DEFAULT_PAUSE_ITEMS.copy();
this.selectCall = selectCall;
}
Expand All @@ -54,7 +58,7 @@ class PauseSubState extends MusicBeatSubstate
if (menuItems.contains("Exit to charter") && !PlayState.chartingMode)
menuItems.remove("Exit to charter");

add(parentDisabler = new FunkinParentDisabler());
add(parentDisabler = new FunkinParentDisabler(parentDisablerExcludeList));

pauseScript = Script.create(Paths.script(script));
pauseScript.setParent(this);
Expand Down