Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/gui/session/menu.js
Show All 23 Lines | |||||
*/ | */ | ||||
var g_CivInfo = { | var g_CivInfo = { | ||||
"civ": "", | "civ": "", | ||||
"page": "page_structree.xml" | "page": "page_structree.xml" | ||||
}; | }; | ||||
var g_IsMenuOpen = false; | var g_IsMenuOpen = false; | ||||
var g_IsObjectivesOpen = false; | |||||
/** | /** | ||||
* Remember last viewed summary panel and charts. | * Remember last viewed summary panel and charts. | ||||
*/ | */ | ||||
var g_SummarySelectedData; | var g_SummarySelectedData; | ||||
function initMenu() | function initMenu(playerViewControl, pauseControl) | ||||
{ | { | ||||
Engine.GetGUIObjectByName("menu").size = "100%-164 " + MENU_TOP + " 100% " + MENU_BOTTOM; | Engine.GetGUIObjectByName("menu").size = "100%-164 " + MENU_TOP + " 100% " + MENU_BOTTOM; | ||||
Engine.GetGUIObjectByName("lobbyButton").enabled = Engine.HasXmppClient(); | |||||
playerViewControl.registerViewedPlayerChangeHandler(updateResignButton); | |||||
updatePauseButton(); | |||||
pauseControl.registerPauseHandler(updatePauseButton); | |||||
// TODO: Atlas should pass g_GameAttributes.settings | // TODO: Atlas should pass g_GameAttributes.settings | ||||
for (let button of ["menuExitButton", "summaryButton", "objectivesButton"]) | for (let button of ["menuExitButton", "summaryButton"]) | ||||
Engine.GetGUIObjectByName(button).enabled = !Engine.IsAtlasRunning(); | Engine.GetGUIObjectByName(button).enabled = !Engine.IsAtlasRunning(); | ||||
} | } | ||||
function updateMenuPosition(dt) | function updateMenuPosition(dt) | ||||
{ | { | ||||
let menu = Engine.GetGUIObjectByName("menu"); | let menu = Engine.GetGUIObjectByName("menu"); | ||||
let maxOffset = g_IsMenuOpen ? | let maxOffset = g_IsMenuOpen ? | ||||
Show All 23 Lines | function closeMenu() | ||||
g_IsMenuOpen = false; | g_IsMenuOpen = false; | ||||
} | } | ||||
function toggleMenu() | function toggleMenu() | ||||
{ | { | ||||
g_IsMenuOpen = !g_IsMenuOpen; | g_IsMenuOpen = !g_IsMenuOpen; | ||||
} | } | ||||
function updatePauseButton() | |||||
{ | |||||
let pauseButton = Engine.GetGUIObjectByName("pauseButton"); | |||||
pauseButton.caption = g_PauseControl.explicitPause ? translate("Resume") : translate("Pause"); | |||||
pauseButton.enabled = !g_IsObserver || !g_IsNetworked || g_IsController; | |||||
pauseButton.onPress = () => { | |||||
closeMenu(); | |||||
g_PauseControl.setPaused(!g_PauseControl.explicitPause, true); | |||||
}; | |||||
} | |||||
function updateResignButton() | |||||
{ | |||||
Engine.GetGUIObjectByName("menuResignButton").enabled = !g_IsObserver; | |||||
} | |||||
function optionsMenuButton() | function optionsMenuButton() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
openOptions(); | openOptions(); | ||||
} | } | ||||
function lobbyDialogButton() | function lobbyDialogButton() | ||||
{ | { | ||||
if (!Engine.HasXmppClient()) | if (!Engine.HasXmppClient()) | ||||
return; | return; | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
Engine.PushGuiPage("page_lobby.xml", { "dialog": true }); | Engine.PushGuiPage("page_lobby.xml", { "dialog": true }); | ||||
} | } | ||||
function chatMenuButton() | function chatMenuButton() | ||||
{ | { | ||||
g_Chat.openPage(); | g_Chat.openPage(); | ||||
} | } | ||||
function resignMenuButton() | function resignMenuButton() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
messageBox( | messageBox( | ||||
400, 200, | 400, 200, | ||||
translate("Are you sure you want to resign?"), | translate("Are you sure you want to resign?"), | ||||
translate("Confirmation"), | translate("Confirmation"), | ||||
[translate("No"), translate("Yes")], | [translate("No"), translate("Yes")], | ||||
[resumeGame, resignGame] | [resumeGame, resignGame]); | ||||
); | |||||
} | } | ||||
function exitMenuButton() | function exitMenuButton() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
let messageTypes = { | let messageTypes = { | ||||
"host": { | "host": { | ||||
"caption": translate("Are you sure you want to quit? Leaving will disconnect all other players."), | "caption": translate("Are you sure you want to quit? Leaving will disconnect all other players."), | ||||
"buttons": [resumeGame, leaveGame] | "buttons": [resumeGame, endGame] | ||||
}, | }, | ||||
"client": { | "client": { | ||||
"caption": translate("Are you sure you want to quit?"), | "caption": translate("Are you sure you want to quit?"), | ||||
"buttons": [resumeGame, resignQuestion] | "buttons": [resumeGame, resignQuestion] | ||||
}, | }, | ||||
"singleplayer": { | "singleplayer": { | ||||
"caption": translate("Are you sure you want to quit?"), | "caption": translate("Are you sure you want to quit?"), | ||||
"buttons": [resumeGame, leaveGame] | "buttons": [resumeGame, endGame] | ||||
} | } | ||||
}; | }; | ||||
let messageType = g_IsNetworked && g_IsController ? "host" : | let messageType = g_IsNetworked && g_IsController ? "host" : | ||||
(g_IsNetworked && !g_IsObserver ? "client" : "singleplayer"); | (g_IsNetworked && !g_IsObserver ? "client" : "singleplayer"); | ||||
messageBox( | messageBox( | ||||
400, 200, | 400, 200, | ||||
messageTypes[messageType].caption, | messageTypes[messageType].caption, | ||||
translate("Confirmation"), | translate("Confirmation"), | ||||
[translate("No"), translate("Yes")], | [translate("No"), translate("Yes")], | ||||
messageTypes[messageType].buttons | messageTypes[messageType].buttons | ||||
); | ); | ||||
} | } | ||||
function resignQuestion() | function resignQuestion() | ||||
{ | { | ||||
messageBox( | messageBox( | ||||
400, 200, | 400, 200, | ||||
translate("Do you want to resign or will you return soon?"), | translate("Do you want to resign or will you return soon?"), | ||||
translate("Confirmation"), | translate("Confirmation"), | ||||
[translate("I will return"), translate("I resign")], | [translate("I will return"), translate("I resign")], | ||||
[leaveGame, resignGame], | [endGame, resignGame]); | ||||
[true, false] | |||||
); | |||||
} | } | ||||
function openDeleteDialog(selection) | function openDeleteDialog(selection) | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
g_PauseControl.implicitPause(); | |||||
let deleteSelectedEntities = function(selectionArg) | let deleteSelectedEntities = function(selectionArg) | ||||
{ | { | ||||
Engine.PostNetworkCommand({ | Engine.PostNetworkCommand({ | ||||
"type": "delete-entities", | "type": "delete-entities", | ||||
"entities": selectionArg | "entities": selectionArg | ||||
}); | }); | ||||
resumeGame(); | |||||
}; | }; | ||||
messageBox( | messageBox( | ||||
400, 200, | 400, 200, | ||||
translate("Destroy everything currently selected?"), | translate("Destroy everything currently selected?"), | ||||
translate("Delete"), | translate("Delete"), | ||||
[translate("No"), translate("Yes")], | [translate("No"), translate("Yes")], | ||||
[resumeGame, deleteSelectedEntities], | [resumeGame, deleteSelectedEntities], | ||||
[null, selection] | [null, selection] | ||||
); | ); | ||||
} | } | ||||
function openSave() | function openSave() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
Engine.PushGuiPage( | Engine.PushGuiPage( | ||||
"page_loadgame.xml", | "page_loadgame.xml", | ||||
{ "savedGameData": getSavedGameData() }, | { "savedGameData": getSavedGameData() }, | ||||
resumeGame); | resumeGame); | ||||
} | } | ||||
function openOptions() | function openOptions() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
Engine.PushGuiPage( | Engine.PushGuiPage( | ||||
"page_options.xml", | "page_options.xml", | ||||
{}, | {}, | ||||
callbackFunctionNames => { | callbackFunctionNames => { | ||||
for (let functionName of callbackFunctionNames) | for (let functionName of callbackFunctionNames) | ||||
if (global[functionName]) | if (global[functionName]) | ||||
global[functionName](); | global[functionName](); | ||||
resumeGame(); | resumeGame(); | ||||
}); | }); | ||||
} | } | ||||
function toggleTutorial() | function toggleTutorial() | ||||
{ | { | ||||
let tutorialPanel = Engine.GetGUIObjectByName("tutorialPanel"); | let tutorialPanel = Engine.GetGUIObjectByName("tutorialPanel"); | ||||
tutorialPanel.hidden = !tutorialPanel.hidden || | tutorialPanel.hidden = !tutorialPanel.hidden || | ||||
!Engine.GetGUIObjectByName("tutorialText").caption; | !Engine.GetGUIObjectByName("tutorialText").caption; | ||||
} | } | ||||
function updateGameSpeedControl() | |||||
{ | |||||
Engine.GetGUIObjectByName("gameSpeedButton").hidden = g_IsNetworked; | |||||
let player = g_Players[Engine.GetPlayerID()]; | |||||
g_GameSpeeds = getGameSpeedChoices(!player || player.state != "active"); | |||||
let gameSpeed = Engine.GetGUIObjectByName("gameSpeed"); | |||||
gameSpeed.list = g_GameSpeeds.Title; | |||||
gameSpeed.list_data = g_GameSpeeds.Speed; | |||||
let simRate = Engine.GetSimRate(); | |||||
let gameSpeedIdx = g_GameSpeeds.Speed.indexOf(+simRate.toFixed(2)); | |||||
if (gameSpeedIdx == -1) | |||||
warn("Unknown gamespeed:" + simRate); | |||||
gameSpeed.selected = gameSpeedIdx != -1 ? gameSpeedIdx : g_GameSpeeds.Default; | |||||
gameSpeed.onSelectionChange = function() { | |||||
changeGameSpeed(+this.list_data[this.selected]); | |||||
}; | |||||
} | |||||
function toggleGameSpeed() | |||||
{ | |||||
let gameSpeed = Engine.GetGUIObjectByName("gameSpeed"); | |||||
gameSpeed.hidden = !gameSpeed.hidden; | |||||
} | |||||
function toggleObjectives() | |||||
{ | |||||
let open = g_IsObjectivesOpen; | |||||
closeOpenDialogs(); | |||||
if (!open) | |||||
openObjectives(); | |||||
} | |||||
function openObjectives() | |||||
{ | |||||
g_IsObjectivesOpen = true; | |||||
let player = g_Players[Engine.GetPlayerID()]; | |||||
let playerState = player && player.state; | |||||
let isActive = !playerState || playerState == "active"; | |||||
Engine.GetGUIObjectByName("gameDescriptionText").caption = getGameDescription(); | |||||
let objectivesPlayerstate = Engine.GetGUIObjectByName("objectivesPlayerstate"); | |||||
objectivesPlayerstate.hidden = isActive; | |||||
objectivesPlayerstate.caption = g_PlayerStateMessages[playerState] || ""; | |||||
let gameDescription = Engine.GetGUIObjectByName("gameDescription"); | |||||
let gameDescriptionSize = gameDescription.size; | |||||
gameDescriptionSize.top = Engine.GetGUIObjectByName( | |||||
isActive ? "objectivesTitle" : "objectivesPlayerstate").size.bottom; | |||||
gameDescription.size = gameDescriptionSize; | |||||
Engine.GetGUIObjectByName("objectivesPanel").hidden = false; | |||||
} | |||||
function closeObjectives() | |||||
{ | |||||
g_IsObjectivesOpen = false; | |||||
Engine.GetGUIObjectByName("objectivesPanel").hidden = true; | |||||
} | |||||
/** | /** | ||||
* Allows players to see their own summary. | * Allows players to see their own summary. | ||||
* If they have shared ally vision researched, they are able to see the summary of there allies too. | * If they have shared ally vision researched, they are able to see the summary of there allies too. | ||||
*/ | */ | ||||
function openGameSummary() | function openGameSummary() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState"); | let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState"); | ||||
Engine.PushGuiPage( | Engine.PushGuiPage( | ||||
"page_summary.xml", | "page_summary.xml", | ||||
{ | { | ||||
"sim": { | "sim": { | ||||
"mapSettings": g_GameAttributes.settings, | "mapSettings": g_GameAttributes.settings, | ||||
"playerStates": extendedSimState.players.filter((state, player) => | "playerStates": extendedSimState.players.filter((state, player) => | ||||
g_IsObserver || player == 0 || player == g_ViewedPlayer || | g_IsObserver || player == 0 || player == g_ViewedPlayer || | ||||
extendedSimState.players[g_ViewedPlayer].hasSharedLos && g_Players[player].isMutualAlly[g_ViewedPlayer]), | extendedSimState.players[g_ViewedPlayer].hasSharedLos && g_Players[player].isMutualAlly[g_ViewedPlayer]), | ||||
"timeElapsed": extendedSimState.timeElapsed | "timeElapsed": extendedSimState.timeElapsed | ||||
}, | }, | ||||
"gui": { | "gui": { | ||||
"dialog": true, | "dialog": true, | ||||
"isInGame": true | "isInGame": true | ||||
}, | }, | ||||
"selectedData": g_SummarySelectedData | "selectedData": g_SummarySelectedData | ||||
}, | }, | ||||
resumeGameAndSaveSummarySelectedData); | data => | ||||
{ | |||||
g_SummarySelectedData = data.summarySelectedData; | |||||
g_PauseControl.implicitResume(); | |||||
}); | |||||
} | } | ||||
function openStrucTree(page) | function openStrucTree(page) | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
Engine.PushGuiPage( | Engine.PushGuiPage( | ||||
page, | page, | ||||
{ | { | ||||
"civ": g_CivInfo.civ || g_Players[g_ViewedPlayer].civ | "civ": g_CivInfo.civ || g_Players[g_ViewedPlayer].civ | ||||
// TODO add info about researched techs and unlocked entities | // TODO add info about researched techs and unlocked entities | ||||
}, | }, | ||||
storeCivInfoPage); | storeCivInfoPage); | ||||
} | } | ||||
function storeCivInfoPage(data) | function storeCivInfoPage(data) | ||||
{ | { | ||||
if (data.nextPage) | if (data.nextPage) | ||||
Engine.PushGuiPage( | Engine.PushGuiPage( | ||||
data.nextPage, | data.nextPage, | ||||
{ "civ": data.civ }, | { "civ": data.civ }, | ||||
storeCivInfoPage); | storeCivInfoPage); | ||||
else | else | ||||
{ | { | ||||
g_CivInfo = data; | g_CivInfo = data; | ||||
resumeGame(); | resumeGame(); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Pause or resume the game. | |||||
* | |||||
* @param explicit - true if the player explicitly wants to pause or resume. | |||||
* If this argument isn't set, a multiplayer game won't be paused and the pause overlay | |||||
* won't be shown in single player. | |||||
*/ | |||||
function pauseGame(pause = true, explicit = false) | |||||
{ | |||||
// The NetServer only supports pausing after all clients finished loading the game. | |||||
if (g_IsNetworked && (!explicit || !g_IsNetworkedActive)) | |||||
return; | |||||
if (explicit) | |||||
g_Paused = pause; | |||||
Engine.SetPaused(g_Paused || pause, !!explicit); | |||||
if (g_IsNetworked) | |||||
{ | |||||
setClientPauseState(Engine.GetPlayerGUID(), g_Paused); | |||||
return; | |||||
} | |||||
updatePauseOverlay(); | |||||
} | |||||
function resumeGame(explicit = false) | |||||
{ | |||||
pauseGame(false, explicit); | |||||
} | |||||
function resumeGameAndSaveSummarySelectedData(data) | |||||
{ | |||||
g_SummarySelectedData = data.summarySelectedData; | |||||
resumeGame(data.explicitResume); | |||||
} | |||||
/** | |||||
* Called when the current player toggles a pause button. | |||||
*/ | |||||
function togglePause() | |||||
{ | |||||
if (!Engine.GetGUIObjectByName("pauseButton").enabled) | |||||
return; | |||||
closeOpenDialogs(); | |||||
pauseGame(!g_Paused, true); | |||||
} | |||||
/** | |||||
* Called when a client pauses or resumes in a multiplayer game. | |||||
*/ | |||||
function setClientPauseState(guid, paused) | |||||
{ | |||||
// Update the list of pausing clients. | |||||
let index = g_PausingClients.indexOf(guid); | |||||
if (paused && index == -1) | |||||
g_PausingClients.push(guid); | |||||
else if (!paused && index != -1) | |||||
g_PausingClients.splice(index, 1); | |||||
updatePauseOverlay(); | |||||
Engine.SetPaused(!!g_PausingClients.length, false); | |||||
} | |||||
/** | |||||
* Update the pause overlay. | |||||
*/ | |||||
function updatePauseOverlay() | |||||
{ | |||||
Engine.GetGUIObjectByName("pauseButton").caption = g_Paused ? translate("Resume") : translate("Pause"); | |||||
Engine.GetGUIObjectByName("resumeMessage").hidden = !g_Paused; | |||||
Engine.GetGUIObjectByName("pausedByText").hidden = !g_IsNetworked; | |||||
Engine.GetGUIObjectByName("pausedByText").caption = sprintf(translate("Paused by %(players)s"), | |||||
{ "players": g_PausingClients.map(guid => colorizePlayernameByGUID(guid)).join(translateWithContext("Separator for a list of players", ", ")) }); | |||||
Engine.GetGUIObjectByName("pauseOverlay").hidden = !(g_Paused || g_PausingClients.length); | |||||
Engine.GetGUIObjectByName("pauseOverlay").onPress = g_Paused ? togglePause : function() {}; | |||||
} | |||||
function openManual() | function openManual() | ||||
{ | { | ||||
closeOpenDialogs(); | closeOpenDialogs(); | ||||
pauseGame(); | g_PauseControl.implicitPause(); | ||||
Engine.PushGuiPage("page_manual.xml", {}, resumeGame); | Engine.PushGuiPage("page_manual.xml", {}, resumeGame); | ||||
} | } | ||||
function closeOpenDialogs() | function closeOpenDialogs() | ||||
{ | { | ||||
closeMenu(); | closeMenu(); | ||||
closeObjectives(); | |||||
g_Chat.closePage(); | g_Chat.closePage(); | ||||
g_DiplomacyDialog.close(); | g_DiplomacyDialog.close(); | ||||
g_ObjectivesDialog.close(); | |||||
g_TradeDialog.close(); | g_TradeDialog.close(); | ||||
} | } |
Wildfire Games · Phabricator