diff --git a/binaries/data/mods/public/gui/common/functions_utility.js b/binaries/data/mods/public/gui/common/functions_utility.js index fb6fd2a4ca..2da15e1cae 100644 --- a/binaries/data/mods/public/gui/common/functions_utility.js +++ b/binaries/data/mods/public/gui/common/functions_utility.js @@ -213,38 +213,70 @@ function clearChatMessages() /** * Returns a formatted string describing the player assignments. - * Including civs, teams, AI settings and player colors - * which are given in data (array of objects per player). + * Needs g_CivData to translate! * + * @param {object} playerDataArray - As known from gamesetup and simstate. + * @param {(string[]|false)} playerStates - One of "won", "defeated", "active" for each player. * @returns {string} */ -function formatPlayerInfo(data) +function formatPlayerInfo(playerDataArray, playerStates) { let playerDescriptions = {}; let playerIdx = 0; - for (let playerData of data) + + for (let playerData of playerDataArray) { + if (playerData == null || playerData.Civ == "gaia") + continue; + ++playerIdx; let teamIdx = playerData.Team; - let showDefeated = playerData.state && playerData.state == "defeated"; let isAI = playerData.AI && playerData.AI != ""; + let playerState = playerStates && playerStates[playerIdx]; + let isActive = !playerState || playerState == "active"; - let translated; - if (!isAI && !showDefeated) - translated = translateWithContext("replay", "%(playerName)s (%(civ)s)"); - else if (!isAI && showDefeated) - translated = translateWithContext("replay", "%(playerName)s (%(civ)s, defeated)"); - else if (isAI && !showDefeated) - translated = translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s)"); + let playerDescription; + if (isAI) + { + if (isActive) + // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu + playerDescription = translate("%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s)"); + else + // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu + playerDescription = translate("%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s, %(state)s)"); + } else - translated = translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s, defeated)"); + { + if (isActive) + // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu + playerDescription = translate("%(playerName)s (%(civ)s)"); + else + // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu + playerDescription = translate("%(playerName)s (%(civ)s, %(state)s)"); + } // Sort player descriptions by team if (!playerDescriptions[teamIdx]) playerDescriptions[teamIdx] = []; - playerDescriptions[teamIdx].push(sprintf(translated, { - "playerName": '[color="' + rgbToGuiColor(playerData.Color) + '"]' + escapeText(playerData.Name) + "[/color]", - "civ": playerData.Civ, + + playerDescriptions[teamIdx].push(sprintf(playerDescription, { + "playerName": + '[color="' + + rgbToGuiColor(playerData.Color || g_Settings.PlayerDefaults[playerIdx].Color) + + '"]' + escapeText(playerData.Name) + "[/color]", + + "civ": + !playerData.Civ ? + translate("Unknown Civilization") : + g_CivData && g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? + translate(g_CivData[playerData.Civ].Name) : + playerData.Civ, + + "state": + playerState == "defeated" ? + translateWithContext("playerstate", "defeated") : + translateWithContext("playerstate", "won"), + "AIname": isAI ? translateAIName(playerData.AI) : "", "AIdifficulty": isAI ? translateAIDifficulty(playerData.AIDiff) : "" })); @@ -258,7 +290,15 @@ function formatPlayerInfo(data) // If there are teams, merge "Team N:" + playerDescriptions return teams.map(team => { - let teamCaption = (team == -1) ? translate("No Team") : sprintf(translate("Team %(team)s"), { "team": +team + 1 }); - return '[font="sans-bold-14"]' + teamCaption + "[/font]:\n" + playerDescriptions[team].join("\n"); + + let teamCaption = team == -1 ? + translate("No Team") : + sprintf(translate("Team %(team)s"), { "team": +team + 1 }); + + // Translation: Describe players of one team in a selected game, f.e. in the replay- or savegame menu or lobby + return sprintf(translate("%(team)s:\n%(playerDescriptions)s"), { + "team": '[font="sans-bold-14"]' + teamCaption + "[/font]", + "playerDescriptions": playerDescriptions[team].join("\n") + }); }).join("\n\n"); } diff --git a/binaries/data/mods/public/gui/replaymenu/replay_actions.js b/binaries/data/mods/public/gui/replaymenu/replay_actions.js index a065c3cb58..6fe53be63c 100644 --- a/binaries/data/mods/public/gui/replaymenu/replay_actions.js +++ b/binaries/data/mods/public/gui/replaymenu/replay_actions.js @@ -109,20 +109,22 @@ function showReplaySummary() return; // Load summary screen data from the selected replay directory - var summary = Engine.GetReplayMetadata(g_ReplaysFiltered[selected].directory); + let simData = Engine.GetReplayMetadata(g_ReplaysFiltered[selected].directory); - if (!summary) + if (!simData) { messageBox(500, 200, translate("No summary data available."), translate("Error")); return; } - // Open summary screen - summary.isReplay = true; - summary.gameResult = translate("Scores at the end of the game."); - summary.replayDirectory = g_ReplaysFiltered[selected].directory; - summary.replaySelectionData = createReplaySelectionData(g_ReplaysFiltered[selected].directory); - Engine.SwitchGuiPage("page_summary.xml", summary); + Engine.SwitchGuiPage("page_summary.xml", { + "sim": simData, + "gui": { + "isReplay": true, + "replayDirectory": g_ReplaysFiltered[selected].directory, + "replaySelectionData": createReplaySelectionData(g_ReplaysFiltered[selected].directory) + } + }); } /** diff --git a/binaries/data/mods/public/gui/replaymenu/replay_menu.js b/binaries/data/mods/public/gui/replaymenu/replay_menu.js index fd5ab6a96c..faf0588290 100644 --- a/binaries/data/mods/public/gui/replaymenu/replay_menu.js +++ b/binaries/data/mods/public/gui/replaymenu/replay_menu.js @@ -4,7 +4,7 @@ const g_EngineInfo = Engine.GetEngineInfo(); /** - * To show the titles of the selected civs in the replay details. + * Needed for formatPlayerInfo to show the player civs in the details. */ const g_CivData = loadCivData(); @@ -190,7 +190,6 @@ function displayReplayList() filterReplays(); - // Create GUI list data var list = g_ReplaysFiltered.map(replay => { let works = replay.isCompatible; return { @@ -204,7 +203,6 @@ function displayReplayList() }; }); - // Extract arrays if (list.length) list = prepareForDropdown(list); @@ -221,7 +219,6 @@ function displayReplayList() replaySelection.list = list.directories || []; replaySelection.list_data = list.directories || []; - // Restore selection replaySelection.selected = replaySelection.list.findIndex(directory => directory == g_SelectedReplayDirectory); displayReplayDetails(); @@ -232,8 +229,8 @@ function displayReplayList() */ function displayReplayDetails() { - var selected = Engine.GetGUIObjectByName("replaySelection").selected; - var replaySelected = selected > -1; + let selected = Engine.GetGUIObjectByName("replaySelection").selected; + let replaySelected = selected > -1; Engine.GetGUIObjectByName("replayInfo").hidden = !replaySelected; Engine.GetGUIObjectByName("replayInfoEmpty").hidden = replaySelected; @@ -244,17 +241,27 @@ function displayReplayDetails() if (!replaySelected) return; - var replay = g_ReplaysFiltered[selected]; - var mapData = getMapDescriptionAndPreview(replay.attribs.settings.mapType, replay.attribs.map); + let replay = g_ReplaysFiltered[selected]; - // Update GUI Engine.GetGUIObjectByName("sgMapName").caption = translate(replay.attribs.settings.Name); Engine.GetGUIObjectByName("sgMapSize").caption = translateMapSize(replay.attribs.settings.Size); Engine.GetGUIObjectByName("sgMapType").caption = translateMapType(replay.attribs.settings.mapType); Engine.GetGUIObjectByName("sgVictory").caption = translateVictoryCondition(replay.attribs.settings.GameType); Engine.GetGUIObjectByName("sgNbPlayers").caption = replay.attribs.settings.PlayerData.length; - Engine.GetGUIObjectByName("sgPlayersNames").caption = getReplayTeamText(replay); + + let metadata = Engine.GetReplayMetadata(replay.directory); + Engine.GetGUIObjectByName("sgPlayersNames").caption = + formatPlayerInfo( + replay.attribs.settings.PlayerData, + Engine.GetGUIObjectByName("showSpoiler").checked && + metadata && + metadata.playerStates && + metadata.playerStates.map(pState => pState.state) + ); + + let mapData = getMapDescriptionAndPreview(replay.attribs.settings.mapType, replay.attribs.map); Engine.GetGUIObjectByName("sgMapDescription").caption = mapData.description; + Engine.GetGUIObjectByName("summaryButton").hidden = !Engine.HasReplayMetadata(replay.directory); setMapPreviewImage("sgMapPreview", mapData.preview); @@ -331,37 +338,3 @@ function replayHasSameEngineVersion(replay) { return replay.attribs.engine_version && replay.attribs.engine_version == g_EngineInfo.engine_version; } - -/** - * Returns a description of the player assignments. - * Including civs, teams, AI settings and player colors. - * - * If the spoiler-checkbox is checked, it also shows defeated players. - * - * @returns {string} - */ -function getReplayTeamText(replay) -{ - // Load replay metadata - const metadata = Engine.GetReplayMetadata(replay.directory); - const spoiler = Engine.GetGUIObjectByName("showSpoiler").checked; - - let data = []; - let playerIdx = 0; - for (let playerData of replay.attribs.settings.PlayerData) - { - ++playerIdx; - data.push({ - "Team": playerData.Team, - "Name": playerData.Name, - "Civ": !playerData.Civ ? translate("Unknown Civilization") : - (g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? translate(g_CivData[playerData.Civ].Name) : playerData.Civ), - "Color": playerData.Color ? playerData.Color : g_Settings.PlayerDefaults[playerIdx].Color, - "AI": playerData.AI, - "AIDiff": playerData.AIDiff, - "Defeated": spoiler && metadata && metadata.playerStates && metadata.playerStates[playerIdx].state == "defeated" - }); - } - - return formatPlayerInfo(data); -} diff --git a/binaries/data/mods/public/gui/savedgames/load.js b/binaries/data/mods/public/gui/savedgames/load.js index aa17934e3f..e70f0c5e09 100644 --- a/binaries/data/mods/public/gui/savedgames/load.js +++ b/binaries/data/mods/public/gui/savedgames/load.js @@ -1,5 +1,10 @@ var g_SavedGamesMetadata = []; +/** + * Needed for formatPlayerInfo to show the player civs in the details. + */ +const g_CivData = loadCivData(); + function init() { let gameSelection = Engine.GetGUIObjectByName("gameSelection"); @@ -58,25 +63,10 @@ function selectionChanged() caption = "[color=\"orange\"]" + caption + "[/color]"; Engine.GetGUIObjectByName("savedMods").caption = caption; - let data = []; - let playerIdx = 0; - for (let playerData of metadata.initAttributes.settings.PlayerData) - { - if (playerData == null || playerData.Civ == "gaia") - continue; - ++playerIdx; - data.push({ - "Team": playerData.Team, - "Name": playerData.Name, - "Civ": playerData.Civ, - "Color": playerData.Color, - "AI": playerData.AI, - "AIDiff": playerData.AIDiff, - "Defeated": metadata.gui.states && metadata.gui.states[playerIdx] == "defeated" - }); - } - - Engine.GetGUIObjectByName("savedPlayersNames").caption = formatPlayerInfo(data); + Engine.GetGUIObjectByName("savedPlayersNames").caption = formatPlayerInfo( + metadata.initAttributes.settings.PlayerData, + metadata.gui.states + ); } function loadGame() diff --git a/binaries/data/mods/public/gui/savedgames/load.xml b/binaries/data/mods/public/gui/savedgames/load.xml index 727ab306d5..9bbe75316c 100644 --- a/binaries/data/mods/public/gui/savedgames/load.xml +++ b/binaries/data/mods/public/gui/savedgames/load.xml @@ -3,6 +3,7 @@