/** * Controller to pause or resume the game and remember which players paused the game. * * If the current player ordered a pause manually, it is called explicit pause. * If the player opened a dialog in single-player mode, the game is paused implicitly. */ class PauseControl { constructor() { /** * This is true if the current player has paused the game using the pause button or hotkey. * The game may also be paused without this being true in single-player mode when opening a dialog. */ this.explicitPause = false; /** * List of GUIDs of players who have currently paused the game, if the game is networked. */ this.pausingClients = []; /** * Event handlers called when anyone paused. */ this.pauseHandlers = []; registerNetworkStatusChangeHandler(this.onNetworkStatusChangeHandler.bind(this)); } onNetworkStatusChangeHandler() { if (g_Disconnected) { Engine.SetPaused(true, false); this.callPauseHandlers(); } } registerPauseHandler(handler) { this.pauseHandlers.push(handler); } callPauseHandlers() { for (let handler of this.pauseHandlers) handler(); } /** * Called from UI dialogs, but only in single-player mode. */ implicitPause() { this.setPaused(true, false); } implicitResume() { this.setPaused(false, false); } /** * Returns true if the current player is allowed to pause the game currently. */ canPause(explicit) { // Don't pause the game in multiplayer mode when opening dialogs. // The NetServer only supports pausing after all clients finished loading the game. return !g_IsNetworked || explicit && g_IsNetworkedActive && (!g_IsObserver || g_IsController); } setPaused(pause, explicit) { if (!this.canPause(explicit)) return; if (explicit) this.explicitPause = pause; // If explicit, send network message informing other clients Engine.SetPaused(this.explicitPause || pause || g_Disconnected, explicit); if (g_IsNetworked) this.setClientPauseState(Engine.GetPlayerGUID(), this.explicitPause); else this.callPauseHandlers(); } /** * Called when a client pauses or resumes in a multiplayer game. */ setClientPauseState(guid, paused) { // Update the list of pausing clients. let index = this.pausingClients.indexOf(guid); if (paused && index == -1) this.pausingClients.push(guid); else if (!paused && index != -1) this.pausingClients.splice(index, 1); Engine.SetPaused(!!this.pausingClients.length, false); this.callPauseHandlers(); } }