Ticket #1090: loadsave-v3.patch

File loadsave-v3.patch, 16.9 KB (added by mimo, 8 years ago)
  • binaries/data/mods/public/gui/common/common_styles.xml

     
    304304        tooltip_style="pgToolTip"
    305305    />
    306306
     307    <style name="MapPlayerList"
     308        buffer_zone="8"
     309        font="sans-14"
     310        scrollbar="true"
     311        scrollbar_style="ModernScrollBar"
     312        scroll_bottom="false"
     313        textcolor="white"
     314        text_align="left"
     315        text_valign="top"
     316    />
    307317        <!--
    308318    ==========================================
    309319    CIV ICON
  • binaries/data/mods/public/gui/common/functions_utility.js

     
    205205    } catch (e) {
    206206    }
    207207}
     208
     209/**
     210 * Returns a formatted string describing the player assignments.
     211 * Including civs, teams, AI settings and player colors
     212 * which are given in data (array of objects per player).
     213 *
     214 * @returns {string}
     215 */
     216function formatPlayerInfo(data)
     217{
     218    let playerDescriptions = {};
     219    let playerIdx = 0;
     220    for (let playerData of data)
     221    {
     222        ++playerIdx;
     223        let teamIdx = playerData.Team;
     224        let showDefeated = playerData.state && playerData.state == "defeated";
     225        let isAI = playerData.AI && playerData.AI != "";
     226
     227        // Create human-readable player description
     228        let playerDetails = {
     229            "playerName": '[color="' + rgbToGuiColor(playerData.Color) + '"]' + escapeText(playerData.Name) + "[/color]",
     230            "civ": playerData.Civ,
     231            "AIname": isAI ? translateAIName(playerData.AI) : "",
     232            "AIdifficulty": isAI ? translateAIDifficulty(playerData.AIDiff) : ""
     233        };
     234
     235        if (!isAI && !showDefeated)
     236            playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s)"), playerDetails);
     237        else if (!isAI && showDefeated)
     238            playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s, defeated)"), playerDetails);
     239        else if (isAI && !showDefeated)
     240            playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s)"), playerDetails);
     241        else
     242            playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s, defeated)"), playerDetails);
     243
     244        // Sort player descriptions by team
     245        if (!playerDescriptions[teamIdx])
     246            playerDescriptions[teamIdx] = [];
     247        playerDescriptions[teamIdx].push(playerDetails);
     248    }
     249
     250    let teams = Object.keys(playerDescriptions);
     251
     252    // If there are no teams, merge all playersDescriptions
     253    if (teams.length == 1)
     254        return playerDescriptions[teams[0]].join("\n") + "\n";
     255
     256    // If there are teams, merge "Team N:" + playerDescriptions
     257    return teams.map(team => {
     258        let teamCaption = (team == -1) ? translate("No Team") : sprintf(translate("Team %(team)s"), { "team": +team + 1 });
     259        return '[font="sans-bold-14"]' + teamCaption + "[/font]:\n" + playerDescriptions[team].join("\n");
     260    }).join("\n\n");
     261}
  • binaries/data/mods/public/gui/page_replaymenu.xml

     
    1010    <include>common/common_sprites.xml</include>
    1111    <include>common/common_styles.xml</include>
    1212
    13     <include>replaymenu/styles.xml</include>
    1413    <include>replaymenu/replay_menu.xml</include>
    1514</page>
  • binaries/data/mods/public/gui/replaymenu/replay_menu.js

     
    346346    const metadata = Engine.GetReplayMetadata(replay.directory);
    347347    const spoiler = Engine.GetGUIObjectByName("showSpoiler").checked;
    348348
    349     var playerDescriptions = {};
    350     var playerIdx = 0;
     349    let data = [];
     350    let playerIdx = 0;
    351351    for (let playerData of replay.attribs.settings.PlayerData)
    352352    {
    353353        // Get player info
    354354        ++playerIdx;
    355         let teamIdx = playerData.Team;
    356         let playerColor = playerData.Color ? playerData.Color : g_Settings.PlayerDefaults[playerIdx].Color;
    357         let playerCiv = !playerData.Civ ? translate("Unknown Civilization") : (g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? translate(g_CivData[playerData.Civ].Name) : playerData.Civ);
    358         let showDefeated = spoiler && metadata && metadata.playerStates && metadata.playerStates[playerIdx].state == "defeated";
    359         let isAI = playerData.AI;
    360 
    361         // Create human-readable player description
    362         let playerDetails = {
    363             "playerName": '[color="' + rgbToGuiColor(playerColor) + '"]' + escapeText(playerData.Name) + "[/color]",
    364             "civ": playerCiv,
    365             "AIname": isAI ? translateAIName(playerData.AI) : "",
    366             "AIdifficulty": isAI ? translateAIDifficulty(playerData.AIDiff) : ""
     355        let player = {
     356            "Team": playerData.Team,
     357            "Name": playerData.Name,
     358            "Civ": !playerData.Civ ? translate("Unknown Civilization") : (g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? translate(g_CivData[playerData.Civ].Name) : playerData.Civ),
     359            "Color": playerData.Color ? playerData.Color : g_Settings.PlayerDefaults[playerIdx].Color,
     360            "AI": playerData.AI,
     361            "AIDiff": playerData.AIDiff,
     362            "Defeated": spoiler && metadata && metadata.playerStates && metadata.playerStates[playerIdx].state == "defeated"
    367363        };
    368 
    369         if (!isAI && !showDefeated)
    370             playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s)"), playerDetails);
    371         else if (!isAI && showDefeated)
    372             playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s, defeated)"), playerDetails);
    373         else if (isAI && !showDefeated)
    374             playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s)"), playerDetails);
    375         else
    376             playerDetails = sprintf(translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s, defeated)"), playerDetails);
    377 
    378         // Sort player descriptions by team
    379         if (!playerDescriptions[teamIdx])
    380             playerDescriptions[teamIdx] = [];
    381         playerDescriptions[teamIdx].push(playerDetails);
     364        data.push(player);
    382365    }
    383366
    384     var teams = Object.keys(playerDescriptions);
    385 
    386     // If there are no teams, merge all playersDescriptions
    387     if (teams.length == 1)
    388         return playerDescriptions[teams[0]].join("\n") + "\n";
    389 
    390     // If there are teams, merge "Team N:" + playerDescriptions
    391     return teams.map(team => {
    392         let teamCaption = (team == -1) ? translate("No Team") : sprintf(translate("Team %(team)s"), { "team": +team + 1 });
    393         return '[font="sans-bold-14"]' + teamCaption + "[/font]:\n" + playerDescriptions[team].join("\n");
    394     }).join("\n");
     367    return formatPlayerInfo(data);
    395368}
  • binaries/data/mods/public/gui/replaymenu/styles.xml

     
    1 <?xml version="1.0" encoding="utf-8"?>
    2 
    3 <styles>
    4     <style name="MapPlayerList"
    5         buffer_zone="8"
    6         font="sans-14"
    7         scrollbar="true"
    8         scrollbar_style="ModernScrollBar"
    9         scroll_bottom="true"
    10         textcolor="white"
    11         text_align="left"
    12         text_valign="top"
    13     />
    14 </styles>
  • binaries/data/mods/public/gui/savedgames/load.js

     
    88    if (!savedGames.length)
    99    {
    1010        gameSelection.list = [translate("No saved games found")];
    11         gameSelection.selected = 0;
     11        gameSelection.selected = -1;
     12        selectionChanged();
    1213        Engine.GetGUIObjectByName("loadGameButton").enabled = false;
    1314        Engine.GetGUIObjectByName("deleteGameButton").enabled = false;
    1415        return;
     
    2627        gameSelection.selected = 0;
    2728    else if (gameSelection.selected >= savedGames.length) // happens when deleting the last saved game
    2829        gameSelection.selected = savedGames.length - 1;
     30    else
     31        selectionChanged();
    2932}
    3033
     34function selectionChanged()
     35{
     36    let gameSelection = Engine.GetGUIObjectByName("gameSelection");
     37    let selectionEmpty = gameSelection.selected == -1;
     38    Engine.GetGUIObjectByName("gameInfoLogo").hidden = !selectionEmpty;
     39    Engine.GetGUIObjectByName("gameInfoText").hidden = selectionEmpty;
     40    Engine.GetGUIObjectByName("gameInfoPreview").hidden = selectionEmpty;
     41    Engine.GetGUIObjectByName("gamePlayersNames").hidden = selectionEmpty;
     42
     43    if (selectionEmpty)
     44        return;
     45
     46    let metadata = g_SavedGamesMetadata[gameSelection.selected];
     47    let gameInfoText = Engine.GetGUIObjectByName("gameInfoText");
     48    gameInfoText.caption = sprintf(translate(" %(players)s \n %(playedTime)s \n %(mapType)s \n %(victory)s \n %(mods)s"), {
     49        "players": translate("Players: ") + (metadata.initAttributes.settings.PlayerData.length - 1),
     50        "playedTime": translate("Played time: ") + timeToString(metadata.gui.timeElapsed ? metadata.gui.timeElapsed : 0),
     51        "mapType": translate("Map type: ") + translateMapType(metadata.initAttributes.mapType),
     52        "victory": translate("Victory: ") + translateVictoryCondition(metadata.initAttributes.settings.GameType),
     53        "mods": sprintf(translate("Mods: %(mods)s"), { "mods": metadata.mods.join(translate(", ")) })
     54    });
     55
     56    let mapData = getMapDescriptionAndPreview(metadata.initAttributes.mapType, metadata.initAttributes.map);
     57    setMapPreviewImage("gameInfoPreview", mapData.preview);
     58    Engine.GetGUIObjectByName("gamePlayersNames").caption = getPlayerInfoText(metadata);
     59}
     60
    3161function loadGame()
    3262{
    3363    var gameSelection = Engine.GetGUIObjectByName("gameSelection");
     
    151181    // Run init again to refresh saved game list
    152182    init();
    153183}
     184
     185function getPlayerInfoText(metadata)
     186{
     187    let data = [];
     188    let playerIdx = 0;
     189    for (let playerData of metadata.initAttributes.settings.PlayerData)
     190    {
     191        if (playerData == null || playerData.Name == "gaia")
     192            continue;
     193        // Get player info
     194        ++playerIdx;
     195        let player = {
     196            "Team": playerData.Team,
     197            "Name": playerData.Name,
     198            "Civ": playerData.Civ,
     199            "Color": playerData.Color,
     200            "AI": playerData.AI,
     201            "AIDiff": playerData.AIDiff,
     202            "Defeated": metadata.gui.states && metadata.gui.states[playerIdx] == "defeated"
     203        };
     204        data.push(player);
     205    }
     206
     207    return formatPlayerInfo(data);
     208}
  • binaries/data/mods/public/gui/savedgames/load.xml

     
    44
    55    <script file="gui/common/functions_global_object.js" />
    66    <script file="gui/common/functions_utility.js" />
     7    <script file="gui/common/settings.js" />
     8
     9    <script file="gui/common/color.js" />
     10
    711    <script file="gui/common/functions_utility_loadsave.js" />
    812    <script file="gui/savedgames/load.js" />
    913
     
    1014    <!-- Add a translucent black background to fade out the menu page -->
    1115    <object type="image" z="0" sprite="BackgroundTranslucent"/>
    1216
    13     <object type="image" style="ModernDialog" size="50%-300 50%-200 50%+300 50%+200">
     17    <object type="image" style="ModernDialog" size="50%-400 50%-300 50%+400 50%+300">
    1418
    1519        <object type="text" style="TitleText" size="50%-128 -18 50%+128 14">
    1620            <translatableAttribute id="caption">Load Game</translatableAttribute>
    1721        </object>
    1822
    19         <object name="gameSelection"
    20             style="ModernList"
    21             type="list"
    22             size="24 24 100%-24 100%-100">
    23         </object>
     23        <object type="image" size="0 20 550 100%">
     24            <object name="gameSelection"
     25                style="ModernList"
     26                type="list"
     27                size="24 12 100%-24 100%-90">
     28                <action on="SelectionChange">selectionChanged();</action>
     29            </object>
    2430
    25         <object type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton" hotkey="cancel">
    26             <translatableAttribute id="caption">Cancel</translatableAttribute>
    27             <action on="Press">Engine.PopGuiPage();</action>
    28         </object>
     31            <object type="button" size="0%+25 100%-60 33%+10 100%-32" style="StoneButton" hotkey="cancel">
     32                <translatableAttribute id="caption">Cancel</translatableAttribute>
     33                <action on="Press">Engine.PopGuiPage();</action>
     34            </object>
    2935
    30         <object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton" hotkey="session.savedgames.delete">
    31             <translatableAttribute id="caption">Delete</translatableAttribute>
    32             <action on="Press">
    33                 if (!this.enabled)
    34                     return;
    35                 if (Engine.HotkeyIsPressed("session.savedgames.noconfirmation"))
    36                     deleteGameWithoutConfirmation();
    37                 else
    38                     deleteGame();
    39             </action>
     36            <object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton" hotkey="session.savedgames.delete">
     37                <translatableAttribute id="caption">Delete</translatableAttribute>
     38                <action on="Press">
     39                    if (!this.enabled)
     40                        return;
     41                    if (Engine.HotkeyIsPressed("session.savedgames.noconfirmation"))
     42                        deleteGameWithoutConfirmation();
     43                    else
     44                        deleteGame();
     45                </action>
     46            </object>
     47
     48            <object name="loadGameButton" type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
     49                <translatableAttribute id="caption">Load</translatableAttribute>
     50                <action on="Press">loadGame();</action>
     51            </object>
     52
    4053        </object>
    4154
    42         <object name="loadGameButton" type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32">
    43             <translatableAttribute id="caption">Load</translatableAttribute>
    44             <action on="Press">loadGame();</action>
     55        <object type="image" size="550 20 100%-20 100%">
     56            <object name="gameInfoLogo" size="0 55 220 155" type="image" sprite="logo" />
     57            <object name="gameInfoPreview" size="0 12 220 232"  type="image" sprite="" />
     58            <object name="gameInfoText" type="text" style="ModernLeftLabelText" text_valign="top" size="0 244 100%-15 344" />
     59            <object size="0 344 100%-15 345" type="image" sprite="ModernWhiteLine" z="25"/>
     60            <object name="gamePlayersNames" size="0 345 100%-10 100%-32" type="text" style="MapPlayerList" />
    4561        </object>
    46 
    4762    </object>
    4863
    49     </objects>
     64</objects>
  • binaries/data/mods/public/gui/savedgames/save.js

     
    33
    44function selectDescription()
    55{
    6     var gameSelection = Engine.GetGUIObjectByName("gameSelection");
     6    let gameSelection = Engine.GetGUIObjectByName("gameSelection");
    77    if (gameSelection.selected == -1)
    88        return;
    99
    10     var gameID = gameSelection.list_data[gameSelection.selected];
     10    let gameID = gameSelection.list_data[gameSelection.selected];
    1111    Engine.GetGUIObjectByName("deleteGameButton").enabled = true;
    1212    Engine.GetGUIObjectByName("saveGameDesc").caption = g_Descriptions[gameID];
    1313}
     
    1414
    1515function init(data)
    1616{
    17     g_SavedGameData = data && data.savedGameData || undefined;
     17    g_SavedGameData = data && data.savedGameData || {};
     18    let simulationState = Engine.GuiInterfaceCall("GetSimulationState");
     19    g_SavedGameData.timeElapsed = simulationState.timeElapsed;
     20    g_SavedGameData.states = [];
     21    for (let player of simulationState.players)
     22        g_SavedGameData.states.push(player.state);
    1823
    19     var gameSelection = Engine.GetGUIObjectByName("gameSelection");
     24    let gameSelection = Engine.GetGUIObjectByName("gameSelection");
    2025    Engine.GetGUIObjectByName("deleteGameButton").enabled = false;
    2126
    22     var savedGames = Engine.GetSavedGames().sort(sortDecreasingDate);
     27    let savedGames = Engine.GetSavedGames().sort(sortDecreasingDate);
    2328    if (!savedGames.length)
    2429    {
    2530        gameSelection.list = [translate("No saved games found")];
     
    3843
    3944function saveGame()
    4045{
    41     var gameSelection = Engine.GetGUIObjectByName("gameSelection");
    42     var gameLabel = gameSelection.list[gameSelection.selected];
    43     var gameID = gameSelection.list_data[gameSelection.selected];
    44     var desc = Engine.GetGUIObjectByName("saveGameDesc").caption;
    45     var name = gameID || "savegame";
     46    let gameSelection = Engine.GetGUIObjectByName("gameSelection");
     47    let gameLabel = gameSelection.list[gameSelection.selected];
     48    let gameID = gameSelection.list_data[gameSelection.selected];
     49    let desc = Engine.GetGUIObjectByName("saveGameDesc").caption;
     50    let name = gameID || "savegame";
    4651
    4752    if (gameSelection.selected == -1)
    4853    {
     
    7883
    7984function deleteGame()
    8085{
    81     var gameSelection = Engine.GetGUIObjectByName("gameSelection");
    82     var gameLabel = gameSelection.list[gameSelection.selected];
    83     var gameID = gameSelection.list_data[gameSelection.selected];
     86    let gameSelection = Engine.GetGUIObjectByName("gameSelection");
     87    let gameLabel = gameSelection.list[gameSelection.selected];
     88    let gameID = gameSelection.list_data[gameSelection.selected];
    8489
    8590    // Ask for confirmation
    8691    messageBox(