Ticket #3355: t3355_move_gamesetup_strings_v1.patch

File t3355_move_gamesetup_strings_v1.patch, 81.7 KB (added by elexis, 9 years ago)
  • binaries/data/mods/public/gui/aiconfig/aiconfig.js

     
    33
    44function init(settings)
    55{
    66    g_PlayerSlot = settings.playerSlot;
    77
    8     translateObjectKeys(settings.ais, ["name", "description"]);
    98    g_AIs = [
    109        {id: "", data: {name: translateWithContext("ai", "None"), description: translate("AI will be disabled for this player.")}}
    11     ].concat(settings.ais);
     10    ].concat(settings.AIs);
    1211
    1312    var aiSelection = Engine.GetGUIObjectByName("aiSelection");
    14     aiSelection.list = [ translate(ai.data.name) for each (ai in g_AIs) ];
     13    aiSelection.list = g_AIs.map(ai => translate(ai.data.name));
    1514
    1615    var selected = 0;
    1716    for (var i = 0; i < g_AIs.length; ++i)
    1817    {
    1918        if (g_AIs[i].id == settings.id)
     
    2322        }
    2423    }
    2524    aiSelection.selected = selected;
    2625
    2726    var aiDiff = Engine.GetGUIObjectByName("aiDifficulty");
    28     // Translation: AI difficulty level.
    29     aiDiff.list = [translateWithContext("aiDiff", "Sandbox"), translateWithContext("aiDiff", "Very Easy"), translateWithContext("aiDiff", "Easy"), translateWithContext("aiDiff", "Medium"), translateWithContext("aiDiff", "Hard"), translateWithContext("aiDiff", "Very Hard")];
     27    aiDiff.list = settings.difficulties.Title;
    3028    aiDiff.selected = settings.difficulty;
    3129}
    3230
    3331function selectAI(idx)
    3432{
  • binaries/data/mods/public/gui/common/functions_utility.js

     
    8383    return text.substr(0, 255).replace(/\\/g, "\\\\").replace(/\[/g, "\\[");
    8484}
    8585
    8686// ====================================================================
    8787
    88 // Load default player data, for when it's not otherwise specified
    89 function initPlayerDefaults()
    90 {
    91     var data = Engine.ReadJSONFile("simulation/data/player_defaults.json");
    92     if (!data || !data.PlayerData)
    93     {
    94         error("Failed to parse player defaults in player_defaults.json (check for valid JSON data)");
    95         return [];
    96     }
    97 
    98     return data.PlayerData;
    99 }
    100 
    101 // ====================================================================
    102 
    103 // Load map size data
    104 function initMapSizes()
    105 {
    106     var sizes = {
    107         "shortNames":[],
    108         "names":[],
    109         "tiles": [],
    110         "default": 0
    111     };
    11288
    113     var data = Engine.ReadJSONFile("simulation/data/map_sizes.json");
    114     if (!data || !data.Sizes)
    115     {
    116         error("Failed to parse map sizes in map_sizes.json (check for valid JSON data)");
    117         return sizes;
    118     }
    119 
    120     translateObjectKeys(data, ["Name", "LongName"]);
    121     for (var i = 0; i < data.Sizes.length; ++i)
    122     {
    123         sizes.shortNames.push(data.Sizes[i].Name);
    124         sizes.names.push(data.Sizes[i].LongName);
    125         sizes.tiles.push(data.Sizes[i].Tiles);
    126 
    127         if (data.Sizes[i].Default)
    128             sizes["default"] = i;
    129     }
    130 
    131     return sizes;
    132 }
    133 
    134 // ====================================================================
    135 
    136 // Load game speed data
    137 function initGameSpeeds()
     89// Loads the translated description and filename of the preview image of the map (or a placeholder for random map).
     90function getMapDescriptionAndPreview(mapType, mapName)
    13891{
    139     var gameSpeeds = {
    140         "names": [],
    141         "speeds": [],
    142         "default": 0
     92    let mapData;
     93    if (mapType == "random" && mapName == "random")
     94        mapData = {"settings": {"Description": translate("A randomly selected map.")}};
     95    else if (mapType == "random" && Engine.FileExists(mapName + ".json"))
     96        mapData = Engine.ReadJSONFile(mapName + ".json");
     97    else if (Engine.FileExists(mapName + ".xml"))
     98        mapData = Engine.LoadMapSettings(mapName + ".xml");
     99    else
     100        // Warn the player if we can't find the map.
     101        warn(sprintf("Map '%(mapName)s' not found locally.", { mapName: mapName }));
     102
     103    return {
     104        "description": translate(mapData && mapData.settings.Description ? mapData.settings.Description : "Sorry, no description available."),
     105        "preview": mapData && mapData.settings.Preview ? mapData.settings.Preview : "nopreview.png"
    143106    };
    144 
    145     var data = Engine.ReadJSONFile("simulation/data/game_speeds.json");
    146     if (!data || !data.Speeds)
    147     {
    148         error("Failed to parse game speeds in game_speeds.json (check for valid JSON data)");
    149         return gameSpeeds;
    150     }
    151 
    152     translateObjectKeys(data, ["Name"]);
    153     for (var i = 0; i < data.Speeds.length; ++i)
    154     {
    155         gameSpeeds.names.push(data.Speeds[i].Name);
    156         gameSpeeds.speeds.push(data.Speeds[i].Speed);
    157 
    158         if (data.Speeds[i].Default)
    159             gameSpeeds["default"] = i;
    160     }
    161 
    162     return gameSpeeds;
    163107}
    164108
    165 
    166109// ====================================================================
    167110
    168111// Convert integer color values to string (for use in GUI objects)
    169112function rgbToGuiColor(color, alpha)
    170113{
  • binaries/data/mods/public/gui/common/settings.js

     
     1// Used by lobby, gamesetup, session, and replay GUI
     2const g_Settings = loadAvailableSettings();
     3
     4function loadAvailableSettings()
     5{
     6    let settings = Engine.ReadJSONFile("simulation/data/settings/PlayerLimit.json");
     7    if (!settings)
     8        return false;
     9
     10    const settingNames = ["AI_Difficulties", "Ceasefire", "GameSpeeds", "GameTypes", "MapTypes",
     11                          "MapSizes", "PlayerDefaults", "PopulationCapacity", "StartingResources"];
     12
     13    for (let settingName of settingNames)
     14    {
     15        // Read json file
     16        let file = "simulation/data/settings/" + settingName + ".json";
     17        let json = Engine.ReadJSONFile(file);
     18        if (!json || !json[settingName])
     19        {
     20            error("Couldn't load " + settingName + " settings!");
     21            return false;
     22        }
     23
     24        // Translate setting values
     25        let settingValues = json[settingName];
     26        if (json.TranslatedKeys)
     27            translateObjectKeys(settingValues, json.TranslatedKeys);
     28
     29        settings[settingName] = settingValues;
     30    }
     31    return settings;
     32}
     33
     34function initAIDescription()
     35{
     36    let AIs = Engine.GetAIs();
     37    translateObjectKeys(AIs, ["name", "description"]);
     38    // Sort AIs by displayed name
     39    AIs.sort((a, b) => a.data.name < b.data.name ? -1 : b.data.name < a.data.name ? +1 : 0);
     40    return AIs;
     41}
     42
     43// Shows a message box and calls a function if the setting files couldn't be parsed
     44function validSettings(callback)
     45{
     46    if (!g_Settings)
     47        messageBox(400, 200, translate("Can't load game settings!"), translate("ERROR!"), 0, [translate("OK")], [callback]);
     48    return g_Settings;
     49}
     50
     51// Transforms array to easily copy values to the dropdownlist.
     52function prepareForDropdown(settingsName)
     53{
     54    let settings = {};
     55    let settingValues = g_Settings[settingsName];
     56    for (let index in settingValues)
     57    {
     58        for (let property in settingValues[index])
     59        {
     60            if (property == "Default")
     61                continue;
     62
     63            if (index == 0)
     64                settings[property] = [];
     65
     66            // Switch property and index
     67            settings[property][index] = settingValues[index][property];
     68        }
     69
     70        if (settingValues[index].Default)
     71            settings.default = +index;
     72    }
     73    return settings;
     74}
     75
     76//Returns the translation of the given AI difficulty. Requires g_Settings.
     77function translateAIDifficulty(index)
     78{
     79    let difficuly = g_Settings.AI_Difficulties[index];
     80    return difficuly ? difficuly[0].Title : translateWithContext("AI difficulty", "Unknown");
     81}
     82
     83//Returns the translation of the given AI name (like "petra"). Requires g_AIs to be present.
     84function translateAIName(aiName)
     85{
     86    let AI_description = g_AIs.filter(ai => ai.id == aiName);
     87    return AI_description.length > 0 ? translate(AI_description[0].data.name) : translateWithContext("AI name", "Unknown");
     88}
     89
     90//Returns the translation of the given map type. Requires g_Settings.
     91function translateCeasefire(duration)
     92{
     93    let ceasefire = g_Settings.Ceasefire.filter(c => c.Duration == duration);
     94    return ceasefire.length > 0 ? ceasefire[0].Title : translateWithContext("ceasefire duration", "Unknown");
     95}
     96// translateGameSpeeds not needed for now
     97
     98//Returns the translation of the given map type. Requires g_Settings.
     99function translateGameType(gameType)
     100{
     101    let type = g_Settings.GameTypes.filter(t => t.Name == gameType);
     102    return type.length > 0 ? type[0].Title : translateWithContext("game type", "Unknown");
     103}
     104
     105//Returns the translation of the given map type. Requires g_Settings.
     106function translateMapType(mapType)
     107{
     108    let type = g_Settings.MapTypes.filter(t => t.Name == mapType);
     109    return type.length > 0 ? type[0].Title : translateWithContext("map type", "Unknown");
     110}
     111
     112// Returns translated map size for a given a numeric size. Requires g_Settings.
     113function translateMapSize(tiles)
     114{
     115    let size = g_Settings.MapSizes.filter(s => s.Tiles == tiles);
     116    return size.length > 0 ? size[0].Name : translateWithContext("map size", "Default");
     117}
     118
     119// Returns the translation for a given numeric value. Requires g_Settings.
     120function translatePopulationCapacity(population)
     121{
     122    let popCap = g_Settings.PopulationCapacity.filter(p => p.Population == population);
     123    return popCap.length > 0 ? popCap[0].Title : translateWithContext("population capacity", "Unknown");
     124}
  • binaries/data/mods/public/gui/gamesetup/gamesetup.js

     
    1 ////////////////////////////////////////////////////////////////////////////////////////////////
    21// Constants
    32const DEFAULT_NETWORKED_MAP = "Acropolis 01";
    43const DEFAULT_OFFLINE_MAP = "Acropolis 01";
    54
    6 const VICTORY_DEFAULTIDX = 1;
    7 
    8 // TODO: Move these somewhere like simulation\data\game_types.json, Atlas needs them too
    9 // Translation: Type of victory condition.
    10 const POPULATION_CAP = ["50", "100", "150", "200", "250", "300", translate("Unlimited")];
    11 const POPULATION_CAP_DATA = [50, 100, 150, 200, 250, 300, 10000];
    12 const POPULATION_CAP_DEFAULTIDX = 5;
    13 // Translation: Amount of starting resources.
    14 const STARTING_RESOURCES = [translateWithContext("startingResources", "Very Low"), translateWithContext("startingResources", "Low"), translateWithContext("startingResources", "Medium"), translateWithContext("startingResources", "High"), translateWithContext("startingResources", "Very High"), translateWithContext("startingResources", "Deathmatch")];
    15 const STARTING_RESOURCES_DATA = [100, 300, 500, 1000, 3000, 50000];
    16 const STARTING_RESOURCES_DEFAULTIDX = 1;
    17 // Translation: Ceasefire.
    18 const CEASEFIRE = [translateWithContext("ceasefire", "No ceasefire"), translateWithContext("ceasefire", "5 minutes"), translateWithContext("ceasefire", "10 minutes"), translateWithContext("ceasefire", "15 minutes"), translateWithContext("ceasefire", "20 minutes"), translateWithContext("ceasefire", "30 minutes"), translateWithContext("ceasefire", "45 minutes"), translateWithContext("ceasefire", "60 minutes")];
    19 const CEASEFIRE_DATA = [0, 5, 10, 15, 20, 30, 45, 60];
    20 const CEASEFIRE_DEFAULTIDX = 0;
    21 // Max number of players for any map
    22 const MAX_PLAYERS = 8;
    23 
    24 ////////////////////////////////////////////////////////////////////////////////////////////////
     5// Contains settings transformed for the dropdown lists
     6var g_PlayerDefaults = [], g_AIDiffs = {}, g_Ceasefire = {}, g_GameSpeeds = {};
     7var g_GameTypes = {}, g_MapTypes = {}, g_MapSizes = {};
     8var g_PopulationCapacity = {}, g_StartingResources = {};
    259
    2610// Is this is a networked game, or offline
    2711var g_IsNetworked;
    2812
    2913// Is this user in control of game settings (i.e. is a network server, or offline player)
     
    5034var g_GameStarted = false;
    5135
    5236var g_PlayerAssignments = {};
    5337
    5438// Default game setup attributes
    55 var g_DefaultPlayerData = [];
    5639var g_GameAttributes = {
    5740    settings: {}
    5841};
    5942
    60 var g_GameSpeeds = {};
    61 var g_MapSizes = {};
    62 
    63 var g_AIs = [];
    64 
    6543var g_ChatMessages = [];
    6644
    6745// Data caches
    6846var g_MapData = {};
    6947var g_CivData = {};
     
    7654// To prevent the display locking up while we load the map metadata,
    7755// we'll start with a 'loading' message and switch to the main screen in the
    7856// tick handler
    7957var g_LoadingState = 0; // 0 = not started, 1 = loading, 2 = loaded
    8058
    81 // Filled by scripts in victory_conditions/
    82 var g_VictoryConditions = {};
    83 
    8459////////////////////////////////////////////////////////////////////////////////////////////////
    8560
    8661function init(attribs)
    8762{
    8863    switch (attribs.type)
     
    11590}
    11691
    11792// Called after the map data is loaded and cached
    11893function initMain()
    11994{
    120     // Load AI list
    121     g_AIs = Engine.GetAIs();
    122 
    123     // Sort AIs by displayed name
    124     g_AIs.sort(function (a, b) {
    125         return a.data.name < b.data.name ? -1 : b.data.name < a.data.name ? +1 : 0;
    126     });
    127 
    128     // Get default player data - remove gaia
    129     g_DefaultPlayerData = initPlayerDefaults();
    130     g_DefaultPlayerData.shift();
    131     for (var i = 0; i < g_DefaultPlayerData.length; ++i)
    132         g_DefaultPlayerData[i].Civ = "random";
     95    if (!validSettings(cancelAndReturn))
     96        return;
    13397
    134     g_GameSpeeds = initGameSpeeds();
    135     g_MapSizes = initMapSizes();
     98    // Transform setting arrays for usage in dropdown lists
     99    g_AIDiffs = prepareForDropdown("AI_Difficulties");
     100    g_Ceasefire = prepareForDropdown("Ceasefire");
     101    g_GameSpeeds = prepareForDropdown("GameSpeeds");
     102    g_GameTypes = prepareForDropdown("GameTypes");
     103    g_MapSizes = prepareForDropdown("MapSizes");
     104    g_MapTypes = prepareForDropdown("MapTypes");
     105    g_PopulationCapacity = prepareForDropdown("PopulationCapacity");
     106    g_StartingResources = prepareForDropdown("StartingResources");
     107
     108    // Modify player defaults for later usage
     109    g_PlayerDefaults = g_Settings.PlayerDefaults.map(player => { player.Civ = "random"; return player; });
     110    g_PlayerDefaults.shift()
    136111
    137112    // Init civs
    138113    initCivNameList();
    139114
    140115    // Init map types
    141116    var mapTypes = Engine.GetGUIObjectByName("mapTypeSelection");
    142     mapTypes.list = [translateWithContext("map", "Skirmish"), translateWithContext("map", "Random"), translate("Scenario")];
    143     mapTypes.list_data = ["skirmish","random","scenario"];
     117    mapTypes.list = g_MapTypes.Title;
     118    mapTypes.list_data = g_MapTypes.Name;
    144119
    145120    // Setup map filters - will appear in order they are added
    146121    addFilter("default", translate("Default"), function(settings) { return settings && (settings.Keywords === undefined || !keywordTestOR(settings.Keywords, ["naval", "demo", "hidden"])); });
    147122    addFilter("naval", translate("Naval Maps"), function(settings) { return settings && settings.Keywords !== undefined && keywordTestAND(settings.Keywords, ["naval"]); });
    148123    addFilter("demo", translate("Demo Maps"), function(settings) { return settings && settings.Keywords !== undefined && keywordTestAND(settings.Keywords, ["demo"]); });
     
    165140        g_GameAttributes.matchID = Engine.GetMatchID();
    166141
    167142        initMapNameList();
    168143
    169144        var numPlayersSelection = Engine.GetGUIObjectByName("numPlayersSelection");
    170         var players = [];
    171         for (var i = 1; i <= MAX_PLAYERS; ++i)
    172             players.push(i);
    173         numPlayersSelection.list = players;
    174         numPlayersSelection.list_data = players;
    175         numPlayersSelection.selected = MAX_PLAYERS - 1;
     145        let playersArray = Array(g_Settings.MaxPlayers).fill(0).map((value, index) => index + 1);
     146        numPlayersSelection.list = playersArray;
     147        numPlayersSelection.list_data = playersArray;
     148        numPlayersSelection.selected = g_Settings.MaxPlayers - 1;
    176149
    177150        var gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
    178151        gameSpeed.hidden = false;
    179152        Engine.GetGUIObjectByName("gameSpeedText").hidden = true;
    180         gameSpeed.list = g_GameSpeeds.names;
    181         gameSpeed.list_data = g_GameSpeeds.speeds;
     153        gameSpeed.list = g_GameSpeeds.Title;
     154        gameSpeed.list_data = g_GameSpeeds.Speed;
    182155        gameSpeed.onSelectionChange = function() {
    183156            if (this.selected != -1)
    184                 g_GameAttributes.gameSpeed = g_GameSpeeds.speeds[this.selected];
     157                g_GameAttributes.gameSpeed = g_GameSpeeds.Speed[this.selected];
    185158
    186159            updateGameAttributes();
    187160        }
    188         gameSpeed.selected = g_GameSpeeds["default"];
     161        gameSpeed.selected = g_GameSpeeds.default;
    189162
    190163        var populationCaps = Engine.GetGUIObjectByName("populationCap");
    191         populationCaps.list = POPULATION_CAP;
    192         populationCaps.list_data = POPULATION_CAP_DATA;
    193         populationCaps.selected = POPULATION_CAP_DEFAULTIDX;
     164        populationCaps.list = g_PopulationCapacity.Title;
     165        populationCaps.list_data = g_PopulationCapacity.Population;
     166        populationCaps.selected = g_PopulationCapacity.default;
    194167        populationCaps.onSelectionChange = function() {
    195168            if (this.selected != -1)
    196                 g_GameAttributes.settings.PopulationCap = POPULATION_CAP_DATA[this.selected];
     169                g_GameAttributes.settings.PopulationCap = g_PopulationCapacity.Population[this.selected];
    197170
    198171            updateGameAttributes();
    199172        }
    200173
    201174        var startingResourcesL = Engine.GetGUIObjectByName("startingResources");
    202         startingResourcesL.list = STARTING_RESOURCES;
    203         startingResourcesL.list_data = STARTING_RESOURCES_DATA;
    204         startingResourcesL.selected = STARTING_RESOURCES_DEFAULTIDX;
     175        startingResourcesL.list = g_StartingResources.Title;
     176        startingResourcesL.list_data = g_StartingResources.Resources;
     177        startingResourcesL.selected = g_StartingResources.default;
    205178        startingResourcesL.onSelectionChange = function() {
    206179            if (this.selected != -1)
    207                 g_GameAttributes.settings.StartingResources = STARTING_RESOURCES_DATA[this.selected];
     180                g_GameAttributes.settings.StartingResources = g_StartingResources.Resources[this.selected];
    208181
    209182            updateGameAttributes();
    210183        }
    211184
    212185        var ceasefireL = Engine.GetGUIObjectByName("ceasefire");
    213         ceasefireL.list = CEASEFIRE;
    214         ceasefireL.list_data = CEASEFIRE_DATA;
    215         ceasefireL.selected = CEASEFIRE_DEFAULTIDX;
     186        ceasefireL.list = g_Ceasefire.Title;
     187        ceasefireL.list_data = g_Ceasefire.Duration;
     188        ceasefireL.selected = g_Ceasefire.default;
    216189        ceasefireL.onSelectionChange = function() {
    217190            if (this.selected != -1)
    218                 g_GameAttributes.settings.Ceasefire = CEASEFIRE_DATA[this.selected];
     191                g_GameAttributes.settings.Ceasefire = g_Ceasefire.Duration[this.selected];
    219192
    220193            updateGameAttributes();
    221194        }
    222195
    223196        var victoryConditions = Engine.GetGUIObjectByName("victoryCondition");
    224         var victories = getVictoryConditions();
    225         victoryConditions.list = victories.text;
    226         victoryConditions.list_data = victories.data;
     197        victoryConditions.list = g_GameTypes.Title;
     198        victoryConditions.list_data = g_GameTypes.Name;
    227199        victoryConditions.onSelectionChange = function() {
    228200            if (this.selected != -1)
    229201            {
    230                 g_GameAttributes.settings.GameType = victories.data[this.selected];
    231                 g_GameAttributes.settings.VictoryScripts = victories.scripts[this.selected];
     202                g_GameAttributes.settings.GameType = g_GameTypes.Name[this.selected];
     203                g_GameAttributes.settings.VictoryScripts = g_GameTypes.Scripts[this.selected];
    232204            }
    233205
    234206            updateGameAttributes();
    235207        };
    236         victoryConditions.selected = VICTORY_DEFAULTIDX;
     208        victoryConditions.selected = g_GameTypes.default;
    237209
    238210        var mapSize = Engine.GetGUIObjectByName("mapSize");
    239         mapSize.list = g_MapSizes.names;
    240         mapSize.list_data = g_MapSizes.tiles;
     211        mapSize.list = g_MapSizes.LongName;
     212        mapSize.list_data = g_MapSizes.Tiles;
    241213        mapSize.onSelectionChange = function() {
    242214            if (this.selected != -1)
    243                 g_GameAttributes.settings.Size = g_MapSizes.tiles[this.selected];
     215                g_GameAttributes.settings.Size = g_MapSizes.Tiles[this.selected];
    244216            updateGameAttributes();
    245217        };
    246218        mapSize.selected = 0;
    247219
    248220        Engine.GetGUIObjectByName("revealMap").onPress = function() {
     
    292264        Engine.GetGUIObjectByName("gameSpeedText").hidden = false;
    293265        Engine.GetGUIObjectByName("gameSpeed").hidden = true;
    294266
    295267        // Disable player and game options controls
    296268        // TODO: Shouldn't players be able to choose their own assignment?
    297         for (var i = 0; i < MAX_PLAYERS; ++i)
     269        for (let i = 0; i < g_Settings.MaxPlayers; ++i)
    298270        {
    299271            Engine.GetGUIObjectByName("playerAssignment["+i+"]").hidden = true;
    300272            Engine.GetGUIObjectByName("playerCiv["+i+"]").hidden = true;
    301273            Engine.GetGUIObjectByName("playerTeam["+i+"]").hidden = true;
    302274        }
     
    339311        }
    340312    }
    341313
    342314    // Settings for all possible player slots
    343315    var boxSpacing = 32;
    344     for (var i = 0; i < MAX_PLAYERS; ++i)
     316    for (let i = 0; i < g_Settings.MaxPlayers; ++i)
    345317    {
    346318        // Space player boxes
    347319        var box = Engine.GetGUIObjectByName("playerBox["+i+"]");
    348320        var boxSize = box.size;
    349321        var h = boxSize.bottom - boxSize.top;
    350322        boxSize.top = i * boxSpacing;
    351323        boxSize.bottom = i * boxSpacing + h;
    352324        box.size = boxSize;
    353325
    354326        // Populate team dropdowns
    355         var team = Engine.GetGUIObjectByName("playerTeam["+i+"]");
    356         team.list = [translateWithContext("team", "None"), "1", "2", "3", "4"];
    357         team.list_data = [-1, 0, 1, 2, 3];
     327        let team = Engine.GetGUIObjectByName("playerTeam["+i+"]");
     328        let teamsArray = Array(g_Settings.MaxTeams).fill(0).map((v, i) => i + 1); // 1, 2, ... MaxTeams
     329        team.list = [translateWithContext("team", "None")].concat(teamsArray); // "None", 1, 2, ..., maxTeams
     330        team.list_data = [-1].concat(teamsArray.map(player => player - 1)); // -1, 0, ..., (maxTeams-1)
    358331        team.selected = 0;
    359332
    360333        let playerSlot = i; // declare for inner function use
    361334        team.onSelectionChange = function() {
    362335            if (this.selected != -1)
     
    398371    }
    399372}
    400373
    401374function handleNetMessage(message)
    402375{
     376    if (!g_Settings)
     377        return;
     378
    403379    log("Net message: "+uneval(message));
    404380
    405381    switch (message.type)
    406382    {
    407383    case "netstatus":
     
    571547    //  Add random civ to beginning of list
    572548    civListNames.unshift('[color="orange"]' + translateWithContext("civilization", "Random") + '[/color]');
    573549    civListCodes.unshift("random");
    574550
    575551    // Update the dropdowns
    576     for (var i = 0; i < MAX_PLAYERS; ++i)
     552    for (let i = 0; i < g_Settings.MaxPlayers; ++i)
    577553    {
    578554        var civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
    579555        civ.list = civListNames;
    580556        civ.list_data = civListCodes;
    581557        civ.selected = 0;
     
    703679
    704680    // Ensure that cheats are enabled in singleplayer
    705681    if (!g_IsNetworked)
    706682        mapSettings.CheatsEnabled = true;
    707683
    708     var aiCodes = [ ai.id for each (ai in g_AIs) ];
    709684    var civListCodes = [ civ.Code for each (civ in g_CivData) if (civ.SelectableInGameSetup !== false) ];
    710685    civListCodes.push("random");
    711686
    712687    var playerData = mapSettings.PlayerData;
    713688
     
    762737    }
    763738
    764739    if (attrs.gameSpeed)
    765740    {
    766741        var gameSpeedBox = Engine.GetGUIObjectByName("gameSpeed");
    767         gameSpeedBox.selected = g_GameSpeeds.speeds.indexOf(attrs.gameSpeed);
     742        gameSpeedBox.selected = g_GameSpeeds.Speed.indexOf(attrs.gameSpeed);
    768743    }
    769744
    770745    if (!Engine.HasXmppClient())
    771746    {
    772747        g_GameAttributes.settings.RatingEnabled = false;
     
    787762    Engine.WriteJSONFile(g_IsNetworked ? FILEPATH_MATCHSETTINGS_MP : FILEPATH_MATCHSETTINGS_SP, attributes);
    788763}
    789764////////////////////////////////////////////////////////////////////////////////////////////////
    790765// GUI event handlers
    791766
     767function cancelAndReturn()
     768{
     769    cancelSetup();
     770    if(Engine.HasXmppClient())
     771        Engine.SwitchGuiPage("page_lobby.xml");
     772    else
     773        Engine.SwitchGuiPage("page_pregame.xml");
     774}
     775
    792776function cancelSetup()
    793777{
    794778    if (g_IsController)
    795779        saveGameAttributes();
    796780
     
    858842    }
    859843    else
    860844    {
    861845        // Add player data from defaults
    862846        for (var i = pData.length; i < num; ++i)
    863             g_GameAttributes.settings.PlayerData.push(g_DefaultPlayerData[i]);
     847            g_GameAttributes.settings.PlayerData.push(g_PlayerDefaults[i]);
    864848    }
    865849
    866850    // Some players may have lost their assigned slot
    867851    for (var guid in g_PlayerAssignments)
    868852    {
     
    908892        break;
    909893
    910894    case "skirmish":
    911895        g_GameAttributes.mapPath = "maps/skirmishes/";
    912896        g_GameAttributes.settings = {
    913             PlayerData: g_DefaultPlayerData.slice(0, 4),
     897            PlayerData: g_PlayerDefaults.slice(0, 4),
    914898            Seed: Math.floor(Math.random() * 65536),
    915899            AISeed: Math.floor(Math.random() * 65536),
    916900            CheatsEnabled: g_GameAttributes.settings.CheatsEnabled
    917901        };
    918902        break;
    919903
    920904    case "random":
    921905        g_GameAttributes.mapPath = "maps/random/";
    922906        g_GameAttributes.settings = {
    923             PlayerData: g_DefaultPlayerData.slice(0, 4),
     907            PlayerData: g_PlayerDefaults.slice(0, 4),
    924908            Seed: Math.floor(Math.random() * 65536),
    925909            AISeed: Math.floor(Math.random() * 65536),
    926910            CheatsEnabled: g_GameAttributes.settings.CheatsEnabled
    927911        };
    928912        break;
     
    975959            g_GameAttributes.settings[prop] = undefined;
    976960
    977961    var mapData = loadMapData(name);
    978962    var mapSettings = (mapData && mapData.settings ? deepcopy(mapData.settings) : {});
    979963
     964    // Reset victory conditions
     965    if (g_GameAttributes.mapType != "random")
     966    {
     967        let victoryIdx = mapSettings.GameType && g_GameTypes.Name.indexOf(mapSettings.GameType) != -1 ? g_GameTypes.Name.indexOf(mapSettings.GameType) : g_GameTypes.default;
     968        g_GameAttributes.settings.GameType = g_GameTypes.Name[victoryIdx];
     969        g_GameAttributes.settings.VictoryScripts = g_GameTypes.Scripts[victoryIdx];
     970    }
     971
    980972    // Copy any new settings
    981973    g_GameAttributes.map = name;
    982974    g_GameAttributes.script = mapSettings.Script;
    983975    if (g_GameAttributes.map !== "random")
    984976        for (var prop in mapSettings)
     
    990982
    991983    // Use default AI if the map doesn't specify any explicitly
    992984    for (var i = 0; i < g_GameAttributes.settings.PlayerData.length; ++i)
    993985    {
    994986        if (!('AI' in g_GameAttributes.settings.PlayerData[i]))
    995             g_GameAttributes.settings.PlayerData[i].AI = g_DefaultPlayerData[i].AI;
     987            g_GameAttributes.settings.PlayerData[i].AI = g_PlayerDefaults[i].AI;
    996988        if (!('AIDiff' in g_GameAttributes.settings.PlayerData[i]))
    997             g_GameAttributes.settings.PlayerData[i].AIDiff = g_DefaultPlayerData[i].AIDiff;
     989            g_GameAttributes.settings.PlayerData[i].AIDiff = g_PlayerDefaults[i].AIDiff;
    998990    }
    999991
    1000992    // Reset player assignments on map change
    1001993    if (!g_IsNetworked)
    1002994    {   // Slot 1
     
    10081000
    10091001        for (var guid in g_PlayerAssignments)
    10101002        {   // Unassign extra players
    10111003            var player = g_PlayerAssignments[guid].player;
    10121004
    1013             if (player <= MAX_PLAYERS && player > numPlayers)
     1005            if (player <= g_Settings.MaxPlayers && player > numPlayers)
    10141006                Engine.AssignNetworkPlayer(player, "");
    10151007        }
    10161008    }
    10171009
    10181010    updateGameAttributes();
     
    11331125
    11341126////////////////////////////////////////////////////////////////////////////////////////////////
    11351127
    11361128function onGameAttributesChange()
    11371129{
     1130    if (!g_Settings)
     1131        return;
     1132
    11381133    g_IsInGuiUpdate = true;
    11391134
    11401135    // Don't set any attributes here, just show the changes in GUI
    11411136
    11421137    var mapName = g_GameAttributes.map || "";
    11431138    var mapSettings = g_GameAttributes.settings;
    1144     var numPlayers = (mapSettings.PlayerData ? mapSettings.PlayerData.length : MAX_PLAYERS);
     1139    var numPlayers = mapSettings.PlayerData ? mapSettings.PlayerData.length : g_Settings.MaxPlayers;
    11451140
    11461141    // Update some controls for clients
    11471142    if (!g_IsController)
    11481143    {
    11491144        var mapFilterSelection = Engine.GetGUIObjectByName("mapFilterSelection");
     
    11571152        Engine.GetGUIObjectByName("mapSelectionText").caption = translate(getMapDisplayName(mapName));
    11581153        if (mapSettings.PopulationCap)
    11591154        {
    11601155            var populationCapBox = Engine.GetGUIObjectByName("populationCap");
    11611156            populationCapBox.selected = populationCapBox.list_data.indexOf(mapSettings.PopulationCap);
    1162         }       
     1157        }
    11631158        if (mapSettings.StartingResources)
    11641159        {
    11651160            var startingResourcesBox = Engine.GetGUIObjectByName("startingResources");
    11661161            startingResourcesBox.selected = startingResourcesBox.list_data.indexOf(mapSettings.StartingResources);
    11671162        }
     
    12041199    var ceasefireText = Engine.GetGUIObjectByName("ceasefireText");
    12051200    var gameSpeedText = Engine.GetGUIObjectByName("gameSpeedText");
    12061201    var gameSpeedBox = Engine.GetGUIObjectByName("gameSpeed");
    12071202
    12081203    // We have to check for undefined on these properties as not all maps define them.
    1209     var sizeIdx = (mapSettings.Size !== undefined && g_MapSizes.tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.tiles.indexOf(mapSettings.Size) : g_MapSizes["default"]);
    1210     var speedIdx = (g_GameAttributes.gameSpeed !== undefined && g_GameSpeeds.speeds.indexOf(g_GameAttributes.gameSpeed) != -1) ? g_GameSpeeds.speeds.indexOf(g_GameAttributes.gameSpeed) : g_GameSpeeds["default"];
    1211     var victories = getVictoryConditions();
    1212     var victoryIdx = (mapSettings.GameType !== undefined && victories.data.indexOf(mapSettings.GameType) != -1 ? victories.data.indexOf(mapSettings.GameType) : VICTORY_DEFAULTIDX);
    1213     enableCheats.checked = (mapSettings.CheatsEnabled === undefined || !mapSettings.CheatsEnabled ? false : true)
     1204    var sizeIdx = mapSettings.Size && g_MapSizes.Tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.Tiles.indexOf(mapSettings.Size) : g_MapSizes.default;
     1205    var speedIdx = g_GameAttributes.gameSpeed && g_GameSpeeds.Speed.indexOf(g_GameAttributes.gameSpeed) != -1 ? g_GameSpeeds.Speed.indexOf(g_GameAttributes.gameSpeed) : g_GameSpeeds.default;
     1206    var victoryIdx = mapSettings.GameType && g_GameTypes.Name.indexOf(mapSettings.GameType) != -1 ? g_GameTypes.Name.indexOf(mapSettings.GameType) : g_GameTypes.default;
     1207    enableCheats.checked = mapSettings.CheatsEnabled == true;
    12141208    enableCheatsText.caption = (enableCheats.checked ? translate("Yes") : translate("No"));
    1215     if (mapSettings.RatingEnabled !== undefined)
     1209    if (mapSettings.RatingEnabled)
    12161210    {
    12171211        enableRating.checked = mapSettings.RatingEnabled;
    12181212        Engine.SetRankedGame(enableRating.checked);
    12191213        enableRatingText.caption = (enableRating.checked ? translate("Yes") : translate("No"));
    12201214        enableCheats.enabled = !enableRating.checked;
    12211215        lockTeams.enabled = !enableRating.checked;
    12221216    }
    12231217    else
    12241218        enableRatingText.caption = "Unknown";
    1225     gameSpeedText.caption = g_GameSpeeds.names[speedIdx];
     1219    gameSpeedText.caption = g_GameSpeeds.Title[speedIdx];
    12261220    gameSpeedBox.selected = speedIdx;
    1227     populationCap.selected = (mapSettings.PopulationCap !== undefined && POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) != -1 ? POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) : POPULATION_CAP_DEFAULTIDX);
    1228     populationCapText.caption = POPULATION_CAP[populationCap.selected];
    1229     startingResources.selected = (mapSettings.StartingResources !== undefined && STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) != -1 ? STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) : STARTING_RESOURCES_DEFAULTIDX);
    1230     startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];
    1231     ceasefire.selected = (mapSettings.Ceasefire !== undefined && CEASEFIRE_DATA.indexOf(mapSettings.Ceasefire) != -1 ? CEASEFIRE_DATA.indexOf(mapSettings.Ceasefire) : CEASEFIRE_DEFAULTIDX);
    1232     ceasefireText.caption = CEASEFIRE[ceasefire.selected];
     1221    populationCap.selected = mapSettings.PopulationCap && g_PopulationCapacity.Population.indexOf(mapSettings.PopulationCap) != -1 ? g_PopulationCapacity.Population.indexOf(mapSettings.PopulationCap) : g_PopulationCapacity.default;
     1222    populationCapText.caption = g_PopulationCapacity.Title[populationCap.selected];
     1223    startingResources.selected = mapSettings.StartingResources && g_StartingResources.Resources.indexOf(mapSettings.StartingResources) != -1 ? g_StartingResources.Resources.indexOf(mapSettings.StartingResources) : g_StartingResources.default;
     1224    startingResourcesText.caption = g_StartingResources.Title[startingResources.selected];
     1225    ceasefire.selected = mapSettings.hasOwnProperty("Ceasefire") && g_Ceasefire.Duration.indexOf(mapSettings.Ceasefire) != -1 ? g_Ceasefire.Duration.indexOf(mapSettings.Ceasefire) : g_Ceasefire.default;
     1226    ceasefireText.caption = g_Ceasefire.Title[ceasefire.selected];
    12331227
    12341228    // Update map preview
    12351229    Engine.GetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
    12361230
    12371231    // Hide/show settings depending on whether we can change them or not
     
    12701264        }
    12711265        else
    12721266        {
    12731267            // Client
    12741268            numPlayersText.caption = numPlayers;
    1275             mapSizeText.caption = g_MapSizes.names[sizeIdx];
     1269            mapSizeText.caption = g_MapSizes.LongName[sizeIdx];
    12761270            revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
    12771271            exploreMapText.caption = (mapSettings.ExporeMap ? translate("Yes") : translate("No"));
    12781272            disableTreasuresText.caption = (mapSettings.DisableTreasures ? translate("Yes") : translate("No"));
    1279             victoryConditionText.caption = victories.text[victoryIdx];
     1273            victoryConditionText.caption = g_GameTypes.Title[victoryIdx];
    12801274            lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
    12811275        }
    12821276
    12831277        break;
    12841278
     
    13131307        {
    13141308            // Client
    13151309            revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
    13161310            exploreMapText.caption = (mapSettings.ExploreMap ? translate("Yes") : translate("No"));
    13171311            disableTreasuresText.caption = (mapSettings.DisableTreasures ? translate("Yes") : translate("No"));
    1318             victoryConditionText.caption = victories.text[victoryIdx];
     1312            victoryConditionText.caption = g_GameTypes.Title[victoryIdx];
    13191313            lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
    13201314        }
    13211315
    13221316        break;
    13231317
     
    13431337        startingResourcesText.hidden = false;
    13441338        populationCap.hidden = true;
    13451339        populationCapText.hidden = false;
    13461340        ceasefire.hidden = true;
    13471341        ceasefireText.hidden = false;
    1348        
     1342
    13491343        numPlayersText.caption = numPlayers;
    13501344        mapSizeText.caption = translate("Default");
    13511345        revealMapText.caption = (mapSettings.RevealMap ? translate("Yes") : translate("No"));
    13521346        exploreMapText.caption = (mapSettings.ExploreMap ? translate("Yes") : translate("No"));
    13531347        disableTreasuresText.caption = translate("No");
    1354         victoryConditionText.caption = victories.text[victoryIdx];
     1348        victoryConditionText.caption = g_GameTypes.Title[victoryIdx];
    13551349        lockTeamsText.caption = (mapSettings.LockTeams ? translate("Yes") : translate("No"));
    13561350
    13571351        startingResourcesText.caption = translate("Determined by scenario");
    13581352        populationCapText.caption = translate("Determined by scenario");
    13591353        ceasefireText.caption = translate("Determined by scenario");
     
    13771371    // Load the description from the map file, if there is one
    13781372    var description = mapSettings.Description ? translate(mapSettings.Description) : translate("Sorry, no description available.");
    13791373
    13801374    // Describe the number of players and the victory conditions
    13811375    var playerString = sprintf(translatePlural("%(number)s player. ", "%(number)s players. ", numPlayers), { number: numPlayers });
    1382     let victory = translate(victories.text[victoryIdx]);
    1383     if (victoryIdx != VICTORY_DEFAULTIDX)
     1376    let victory = translate(g_GameTypes.Title[victoryIdx]);
     1377    if (victoryIdx != g_GameTypes.default)
    13841378        victory = "[color=\"orange\"]" + victory + "[/color]";
    13851379    playerString += translate("Victory Condition:") + " " + victory + ".\n\n" + description;
    13861380
    1387     for (var i = 0; i < MAX_PLAYERS; ++i)
     1381    for (let i = 0; i < g_Settings.MaxPlayers; ++i)
    13881382    {
    13891383        // Show only needed player slots
    13901384        Engine.GetGUIObjectByName("playerBox["+i+"]").hidden = (i >= numPlayers);
    13911385
    13921386        // Show player data or defaults as necessary
     
    14021396        var pTeamText = Engine.GetGUIObjectByName("playerTeamText["+i+"]");
    14031397        var pColor = Engine.GetGUIObjectByName("playerColor["+i+"]");
    14041398
    14051399        // Player data / defaults
    14061400        var pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};
    1407         var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[i] : {};
     1401        var pDefs = g_PlayerDefaults[i];;
    14081402
    14091403        // Common to all game types
    14101404        var color = rgbToGuiColor(getSetting(pData, pDefs, "Color"));
    14111405        pColor.sprite = "color:" + color + " 100";
    14121406        pName.caption = translate(getSetting(pData, pDefs, "Name"));
     
    15131507
    15141508    // Only enable start button if we have enough assigned players
    15151509    if (g_IsController)
    15161510        Engine.GetGUIObjectByName("startGame").enabled = (g_AssignedCount > 0);
    15171511
    1518     for each (var ai in g_AIs)
     1512    var AIs = initAIDescription();
     1513    for (let ai of AIs)
    15191514    {
    15201515        if (ai.data.hidden)
    15211516        {
    15221517            // If the map uses a hidden AI then don't hide it
    15231518            var usedByMap = false;
    1524             for (var i = 0; i < MAX_PLAYERS; ++i)
     1519            for (let i = 0; i < g_Settings.MaxPlayers; ++i)
    15251520                if (i < g_GameAttributes.settings.PlayerData.length &&
    15261521                    g_GameAttributes.settings.PlayerData[i].AI == ai.id)
    15271522                {
    15281523                    usedByMap = true;
    15291524                    break;
     
    15401535
    15411536    noAssignment = hostNameList.length;
    15421537    hostNameList.push("[color=\"140 140 140 255\"]" + translate("Unassigned"));
    15431538    hostGuidList.push("");
    15441539
    1545     for (var i = 0; i < MAX_PLAYERS; ++i)
     1540    for (let i = 0; i < g_Settings.MaxPlayers; ++i)
    15461541    {
    15471542        let playerSlot = i;
    15481543        let playerID = i+1; // we don't show Gaia, so first slot is ID 1
    15491544
    15501545        var selection = assignments[playerID];
     
    15791574            if (g_IsController)
    15801575            {
    15811576                configButton.hidden = false;
    15821577                configButton.onpress = function() {
    15831578                    Engine.PushGuiPage("page_aiconfig.xml", {
    1584                         ais: g_AIs,
    1585                         id: g_GameAttributes.settings.PlayerData[playerSlot].AI,
    1586                         difficulty: g_GameAttributes.settings.PlayerData[playerSlot].AIDiff,
    1587                         callback: "AIConfigCallback",
    1588                         playerSlot: playerSlot // required by the callback function
     1579                        "AIs": AIs,
     1580                        "id": g_GameAttributes.settings.PlayerData[playerSlot].AI,
     1581                        "difficulty": g_GameAttributes.settings.PlayerData[playerSlot].AIDiff,
     1582                        "difficulties" : g_AIDiffs,
     1583                        "callback": "AIConfigCallback",
     1584                        "playerSlot": playerSlot // required by the callback function
    15891585                    });
    15901586                };
    15911587            }
    15921588        }
    15931589        // There was a human, so make sure we don't have any AI left
     
    17111707        var player = g_PlayerAssignments[msg.guid].player - 1;
    17121708        var mapName = g_GameAttributes.map;
    17131709        var mapData = loadMapData(mapName);
    17141710        var mapSettings = (mapData && mapData.settings ? mapData.settings : {});
    17151711        var pData = mapSettings.PlayerData ? mapSettings.PlayerData[player] : {};
    1716         var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[player] : {};
     1712        var pDefs = g_PlayerDefaults[player];
    17171713
    17181714        color = rgbToGuiColor(getSetting(pData, pDefs, "Color"));
    17191715    }
    17201716
    17211717    var formatted;
     
    17841780
    17851781function updateReadyUI()
    17861782{
    17871783    if (!g_IsNetworked)
    17881784        return; // Disabled for single-player games.
    1789     var isAI = new Array(MAX_PLAYERS + 1);
     1785    var isAI = new Array(g_Settings.MaxPlayers + 1);
    17901786    for (var i = 0; i < isAI.length; ++i)
    17911787        isAI[i] = true;
    17921788    var allReady = true;
    17931789    for (var guid in g_PlayerAssignments)
    17941790    {
    17951791        // We don't really care whether observers are ready.
    17961792        if (g_PlayerAssignments[guid].player == -1 || !g_GameAttributes.settings.PlayerData[g_PlayerAssignments[guid].player - 1])
    17971793            continue;
    17981794        var pData = g_GameAttributes.settings.PlayerData ? g_GameAttributes.settings.PlayerData[g_PlayerAssignments[guid].player - 1] : {};
    1799         var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[g_PlayerAssignments[guid].player - 1] : {};
     1795        var pDefs = g_PlayerDefaults[g_PlayerAssignments[guid].player - 1];
    18001796        isAI[g_PlayerAssignments[guid].player] = false;
    18011797        if (g_PlayerAssignments[guid].status || !g_IsNetworked)
    18021798            Engine.GetGUIObjectByName("playerName[" + (g_PlayerAssignments[guid].player - 1) + "]").caption = '[color="0 255 0"]' + translate(getSetting(pData, pDefs, "Name")) + '[/color]';
    18031799        else
    18041800        {
    18051801            Engine.GetGUIObjectByName("playerName[" + (g_PlayerAssignments[guid].player - 1) + "]").caption = translate(getSetting(pData, pDefs, "Name"));
    18061802            allReady = false;
    18071803        }
    18081804    }
    18091805    // AIs are always ready.
    1810     for (var playerid = 0; playerid < MAX_PLAYERS; ++playerid)
    1811     {       
     1806    for (let playerid = 0; playerid < g_Settings.MaxPlayers; ++playerid)
     1807    {
    18121808        if (!g_GameAttributes.settings.PlayerData[playerid])
    18131809            continue;
    18141810        var pData = g_GameAttributes.settings.PlayerData ? g_GameAttributes.settings.PlayerData[playerid] : {};
    1815         var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[playerid] : {};
     1811        var pDefs = g_PlayerDefaults[playerid];
    18161812        if (isAI[playerid + 1])
    18171813            Engine.GetGUIObjectByName("playerName[" + playerid + "]").caption = '[color="0 255 0"]' + translate(getSetting(pData, pDefs, "Name")) + '[/color]';
    18181814    }
    18191815
    18201816    // The host is not allowed to start until everyone is ready.
     
    19671963        "nbp":nbp,
    19681964        "tnbp":tnbp,
    19691965        "players":players
    19701966    };
    19711967    Engine.SendRegisterGame(gameData);
    1972 }
    1973 
    1974 function getVictoryConditions()
    1975 {
    1976     var r = {};
    1977     r.text = [translate("None")];
    1978     r.data = ["endless"];
    1979     r.scripts = [[]];
    1980     for (var vc in g_VictoryConditions)
    1981     {
    1982         r.data.push(vc);
    1983         r.text.push(g_VictoryConditions[vc].name);
    1984         r.scripts.push(g_VictoryConditions[vc].scripts);
    1985     }
    1986     return r;
    1987 }
     1968}
     1969 No newline at end of file
  • binaries/data/mods/public/gui/gamesetup/gamesetup.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22
    33<objects>
    44
    5     <script file="gui/common/network.js"/>
    65    <script file="gui/common/functions_civinfo.js"/>
    76    <script file="gui/common/functions_global_object.js"/>
    87    <script file="gui/common/functions_utility.js"/>
     8    <script file="gui/common/network.js"/>
     9    <script file="gui/common/settings.js"/>
    910    <script file="gui/gamesetup/gamesetup.js"/>
    10     <!-- After gamesetup.js which defines g_VictoryConditions -->
    11     <script directory="gui/gamesetup/victory_conditions/"/>
    1211
    1312    <!-- Add a translucent black background to fade out the menu page -->
    1413    <object type="image" style="ModernWindow" size="0 0 100% 100%">
    1514
    1615        <object style="TitleText" type="text" size="50%-128 4 50%+128 36">
     
    237236                style="StoneButton"
    238237                size="100%-308 100%-52 100%-168 100%-24"
    239238                tooltip_style="onscreenToolTip"
    240239            >
    241240                <translatableAttribute id="caption">Back</translatableAttribute>
    242                 <action on="Press">
    243                     <![CDATA[
    244                         cancelSetup();
    245                         if(!Engine.HasXmppClient())
    246                             Engine.SwitchGuiPage("page_pregame.xml");
    247                         else
    248                             Engine.SwitchGuiPage("page_lobby.xml");
    249                     ]]>
    250                 </action>
     241                <action on="Press">cancelAndReturn();</action>
    251242            </object>
    252243
    253244            <!-- Options -->
    254245            <object name="gameOptionsBox" size="100%-425 529 100%-25 525">
    255246                <!-- More Options Button -->
  • binaries/data/mods/public/gui/gamesetup/victory_conditions/conquest.js

     
    1 g_VictoryConditions.conquest = {
    2     "name" : translate("Conquest"),
    3     "description" : translate("Defeat all opponents"),
    4     "scripts" : ["scripts/ConquestCommon.js", "scripts/TriggerHelper.js", "scripts/Conquest.js"]
    5 };
  • binaries/data/mods/public/gui/gamesetup/victory_conditions/conquestStructures.js

     
    1 g_VictoryConditions.conquestStructure = {
    2     "name" : translate("Conquest Structures"),
    3     "description" : translate("Destroy all structures of enemies"),
    4     "scripts" : ["scripts/ConquestCommon.js", "scripts/TriggerHelper.js", "scripts/ConquestStructures.js"]
    5 };
  • binaries/data/mods/public/gui/gamesetup/victory_conditions/conquestUnits.js

     
    1 g_VictoryConditions.conquestUnits = {
    2     "name" : translate("Conquest Units"),
    3     "description" : translate("Destroy all units of enemies"),
    4     "scripts" : ["scripts/ConquestCommon.js", "scripts/TriggerHelper.js", "scripts/ConquestUnits.js"]
    5 };
  • binaries/data/mods/public/gui/gamesetup/victory_conditions/wonder.js

     
    1 g_VictoryConditions.wonder = {
    2     "name" : translate("Wonder"),
    3     "description" : translate("Build a wonder to win"),
    4     "scripts" : ["scripts/ConquestCommon.js", "scripts/TriggerHelper.js", "scripts/Conquest.js", "scripts/WonderVictory.js"]
    5 };
  • binaries/data/mods/public/gui/lobby/lobby.js

     
     1const g_specialKey = Math.random();
     2const g_timestamp = Engine.ConfigDB_GetValue("user", "lobby.chattimestamp") == "true";
     3const g_modPrefix = "@";
     4const SPAM_BLOCK_LENGTH = 30;
     5
    16var g_ChatMessages = [];
    27var g_Name = "unknown";
    38var g_GameList = {}
    49var g_GameListSortBy = "name";
    510var g_PlayerListSortBy = "name";
    611var g_GameListOrder = 1; // 1 for ascending sort, and -1 for descending
    712var g_PlayerListOrder = 1;
    8 var g_specialKey = Math.random();
    913// This object looks like {"name":[numMessagesSinceReset, lastReset, timeBlocked]} when in use.
    1014var g_spamMonitor = {};
    11 var g_timestamp = Engine.ConfigDB_GetValue("user", "lobby.chattimestamp") == "true";
    12 var g_mapSizes = {};
    13 const g_mapTypesText = [translateWithContext("map", "Skirmish"), translateWithContext("map", "Random"), translate("Scenario")];
    14 const g_mapTypes = ["skirmish", "random", "scenario"];
    1515var g_userRating = ""; // Rating of user, defaults to Unrated
    16 var g_modPrefix = "@";
    1716var g_joined = false;
    18 // Block spammers for 30 seconds.
    19 var SPAM_BLOCK_LENGTH = 30;
    2017
    2118////////////////////////////////////////////////////////////////////////////////////////////////
    2219
    2320function init(attribs)
    2421{
     22    if (!validSettings(returnToMainMenu))
     23        return;
     24
    2525    // Play menu music
    2626    initMusic();
    2727    global.music.setState(global.music.states.MENU);
    2828
    29     g_Name = Engine.LobbyGetNick();
    30 
    31     g_mapSizes = initMapSizes();
    32     g_mapSizes.shortNames.splice(0, 0, translateWithContext("map size", "Any"));
    33     g_mapSizes.tiles.splice(0, 0, "");
    34 
     29    // Setup mapsize filter
    3530    var mapSizeFilter = Engine.GetGUIObjectByName("mapSizeFilter");
    36     mapSizeFilter.list = g_mapSizes.shortNames;
    37     mapSizeFilter.list_data = g_mapSizes.tiles;
     31    var mapSizes = prepareForDropdown("MapSizes");
     32    mapSizeFilter.list = [translateWithContext("map size", "Any")].concat(mapSizes.Name);
     33    mapSizeFilter.list_data = [""].concat(mapSizes.Tiles);
    3834
     35    // Setup playercount filter
     36    var playersArray = Array(g_Settings.MaxPlayers - 1).fill(0).map((value, index) => index + 2); // 2, 3, ... MaxPlayers
    3937    var playersNumberFilter = Engine.GetGUIObjectByName("playersNumberFilter");
    40     playersNumberFilter.list = [translateWithContext("player number", "Any"),2,3,4,5,6,7,8];
    41     playersNumberFilter.list_data = ["",2,3,4,5,6,7,8];
     38    playersNumberFilter.list = [translateWithContext("player number", "Any")].concat(playersArray);
     39    playersNumberFilter.list_data = [""].concat(playersArray);
    4240
     41    // Setup maptype filter
    4342    var mapTypeFilter = Engine.GetGUIObjectByName("mapTypeFilter");
    44     mapTypeFilter.list = [translateWithContext("map", "Any")].concat(g_mapTypesText);
    45     mapTypeFilter.list_data = [""].concat(g_mapTypes);
     43    var mapTypes = prepareForDropdown("MapTypes");
     44    mapTypeFilter.list = [translateWithContext("map type", "Any")].concat(mapTypes.Title);
     45    mapTypeFilter.list_data = [""].concat(mapTypes.Name);
    4646
     47    // Init GUI elements
     48    g_Name = Engine.LobbyGetNick();
    4749    Engine.LobbySetPlayerPresence("available");
    4850    Engine.SendGetGameList();
    4951    Engine.SendGetBoardList();
    5052    Engine.SendGetRatingList();
    5153    updatePlayerList();
     
    468470            else
    469471                name = '[color="255 0 0"]' + name + '[/color]';
    470472            list_name.push(name);
    471473            list_ip.push(g.ip);
    472474            list_mapName.push(translate(g.niceMapName));
    473             list_mapSize.push(translatedMapSize(g.mapSize));
    474             let idx = g_mapTypes.indexOf(g.mapType);
    475             list_mapType.push(idx != -1 ? g_mapTypesText[idx] : "");
     475            list_mapSize.push(translateMapSize(g.mapSize));
     476            list_mapType.push(translateMapType(g.mapType));
    476477            list_nPlayers.push(g.nbp + "/" +g.tnbp);
    477478            list.push(name);
    478479            list_data.push(c);
    479480        }
    480481        c++;
     
    546547    // Push this player's name and status onto the list
    547548    return [formattedName, formattedStatus, formattedRating];
    548549}
    549550
    550551/**
    551  * Given a map size, returns that map size translated into the current
    552  * language.
    553  */
    554 function translatedMapSize(mapSize)
    555 {
    556     if (+mapSize !== +mapSize) // NaN
    557         return translate(mapSize);
    558     else
    559         return g_mapSizes.shortNames[g_mapSizes.tiles.indexOf(+mapSize)];
    560 }
    561 
    562 /**
    563552 * Populate the game info area with information on the current game selection.
    564553 */
    565554function updateGameSelection()
    566555{
    567556    var selected = Engine.GetGUIObjectByName("gamesBox").selected;
     
    572561        Engine.GetGUIObjectByName("joinGameButton").hidden = true;
    573562        Engine.GetGUIObjectByName("gameInfoEmpty").hidden = false;
    574563        return;
    575564    }
    576565
    577     var mapData;
    578566    var g = Engine.GetGUIObjectByName("gamesBox").list_data[selected];
    579567
    580     // Load map data
    581     if (g_GameList[g].mapType == "random" && g_GameList[g].mapName == "random")
    582         mapData = {"settings": {"Description": translate("A randomly selected map.")}};
    583     else if (g_GameList[g].mapType == "random" && Engine.FileExists(g_GameList[g].mapName + ".json"))
    584         mapData = Engine.ReadJSONFile(g_GameList[g].mapName + ".json");
    585     else if (Engine.FileExists(g_GameList[g].mapName + ".xml"))
    586         mapData = Engine.LoadMapSettings(g_GameList[g].mapName + ".xml");
    587     else
    588         // Warn the player if we can't find the map.
    589         warn(sprintf("Map '%(mapName)s' not found locally.", { mapName: g_GameList[g].mapName }));
    590 
    591568    // Show the game info panel and join button.
    592569    Engine.GetGUIObjectByName("gameInfo").hidden = false;
    593570    Engine.GetGUIObjectByName("joinGameButton").hidden = false;
    594571    Engine.GetGUIObjectByName("gameInfoEmpty").hidden = true;
    595572
    596573    // Display the map name, number of players, the names of the players, the map size and the map type.
    597574    Engine.GetGUIObjectByName("sgMapName").caption = translate(g_GameList[g].niceMapName);
    598575    Engine.GetGUIObjectByName("sgNbPlayers").caption = g_GameList[g].nbp + "/" + g_GameList[g].tnbp;
    599576    Engine.GetGUIObjectByName("sgPlayersNames").caption = g_GameList[g].players;
    600     Engine.GetGUIObjectByName("sgMapSize").caption = translatedMapSize(g_GameList[g].mapSize);
    601     let idx = g_mapTypes.indexOf(g_GameList[g].mapType);
    602     Engine.GetGUIObjectByName("sgMapType").caption = idx != -1 ? g_mapTypesText[idx] : "";
    603 
    604     // Display map description if it exists, otherwise display a placeholder.
    605     if (mapData && mapData.settings.Description)
    606         var mapDescription = translate(mapData.settings.Description);
    607     else
    608         var mapDescription = translate("Sorry, no description available.");
     577    Engine.GetGUIObjectByName("sgMapSize").caption = translateMapSize(g_GameList[g].mapSize);
     578    Engine.GetGUIObjectByName("sgMapType").caption = translateMapType(g_GameList[g].mapType);
    609579
    610     // Display map preview if it exists, otherwise display a placeholder.
    611     if (mapData && mapData.settings.Preview)
    612         var mapPreview = mapData.settings.Preview;
    613     else
    614         var mapPreview = "nopreview.png";
    615 
    616     Engine.GetGUIObjectByName("sgMapDescription").caption = mapDescription;
    617     Engine.GetGUIObjectByName("sgMapPreview").sprite = "cropped:(0.7812,0.5859)session/icons/mappreview/" + mapPreview;
     580    // Display map description & preview (or placeholder)
     581    let mapData = getMapDescriptionAndPreview(g_GameList[g].mapType, g_GameList[g].mapName);
     582    Engine.GetGUIObjectByName("sgMapDescription").caption = mapData.description;
     583    Engine.GetGUIObjectByName("sgMapPreview").sprite = "cropped:(0.7812,0.5859)session/icons/mappreview/" + mapData.preview;
    618584}
    619585
    620586/**
    621587 * Start the joining process on the currectly selected game.
    622588 */
     
    859825        break;
    860826    case "ban": // TODO: Split reason from nick and pass it too, for now just support "/ban nick"
    861827        Engine.LobbyBan(nick, "");
    862828        break;
    863829    case "quit":
    864         lobbyStop();
    865         Engine.SwitchGuiPage("page_pregame.xml");
     830        returnToMainMenu();
    866831        break;
    867832    case "say":
    868833    case "me":
    869834        return false;
    870835    default:
     
    10881053        }
    10891054    }
    10901055
    10911056}
    10921057
     1058function returnToMainMenu()
     1059{
     1060    lobbyStop();
     1061    Engine.SwitchGuiPage("page_pregame.xml");
     1062}
     1063
    10931064/* Utilities */
    10941065// Generate a (mostly) unique color for this player based on their name.
    10951066// See http://stackoverflow.com/questions/3426404/create-a-hexadecimal-colour-based-on-a-string-with-jquery-javascript
    10961067function getPlayerColor(playername)
    10971068{
  • binaries/data/mods/public/gui/lobby/lobby.xml

     
    33<objects>
    44    <script file="gui/common/functions_global_object.js"/>
    55    <script file="gui/common/functions_utility.js"/>
    66    <script file="gui/common/timer.js"/>
    77    <script file="gui/common/music.js"/>
     8    <script file="gui/common/settings.js"/>
    89
    910    <script file="gui/lobby/lobby.js"/>
    1011
    1112    <object type="image" style="ModernWindow" size="0 0 100% 100%" name="lobbyWindow">
    1213
     
    161162                </action>
    162163            </object>
    163164
    164165            <object type="button" style="ModernButtonRed" size="0 100%-25 100% 100%">
    165166                <translatableAttribute id="caption">Main Menu</translatableAttribute>
    166                 <action on="Press">
    167                     lobbyStop();
    168                     Engine.SwitchGuiPage("page_pregame.xml");
    169                 </action>
     167                <action on="Press">returnToMainMenu();</action>
    170168            </object>
    171169        </object>
    172170
    173171        <!-- Middle panel: Filters, game list, chat box. -->
    174172        <object name="middlePanel" size="20%+5 5% 100%-255 97.2%">
  • binaries/data/mods/public/gui/session/session.js

     
    1111// Cache the basic player data (name, civ, color)
    1212var g_Players = [];
    1313// Cache the useful civ data
    1414var g_CivData = {};
    1515
    16 var g_GameSpeeds = {};
    17 var g_CurrentSpeed;
    18 
    1916var g_PlayerAssignments = { "local": { "name": translate("You"), "player": 1 } };
    2017
    2118// Cache dev-mode settings that are frequently or widely used
    2219var g_DevSettings = {
    2320    controlAll: false
     
    145142}
    146143
    147144// Init
    148145function init(initData, hotloadData)
    149146{
     147    initMusic();
     148
     149    if (!validSettings(function() { leaveGame(true); }))
     150        return;
     151
    150152    if (initData)
    151153    {
    152154        g_IsNetworked = initData.isNetworked; // Set network mode
    153155        g_IsController = initData.isController; // Set controller mode
    154156        g_PlayerAssignments = initData.playerAssignments;
     
    175177    if (Engine.GetPlayerID() <= 0)
    176178        g_IsObserver = true;
    177179
    178180    updateTopPanel();
    179181
    180     g_GameSpeeds = initGameSpeeds();
    181     g_CurrentSpeed = Engine.GetSimRate();
    182182    var gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
    183     gameSpeed.list = g_GameSpeeds.names;
    184     gameSpeed.list_data = g_GameSpeeds.speeds;
    185     var idx = g_GameSpeeds.speeds.indexOf(g_CurrentSpeed);
    186     gameSpeed.selected = idx != -1 ? idx : g_GameSpeeds["default"];
     183    var gameSpeeds = prepareForDropdown("GameSpeeds");
     184    gameSpeed.list = gameSpeeds.Title;
     185    gameSpeed.list_data = gameSpeeds.Speed;
     186    var idx = gameSpeed.list_data.indexOf(Engine.GetSimRate());
     187    gameSpeed.selected = idx != -1 ? idx : gameSpeeds.default;
    187188    gameSpeed.onSelectionChange = function() { changeGameSpeed(+this.list_data[this.selected]); }
    188189    initMenuPosition(); // set initial position
    189190
    190191    // Populate player selection dropdown
    191192    var playerNames = [];
     
    207208
    208209    if (hotloadData)
    209210        g_Selection.selected = hotloadData.selection;
    210211
    211212    // Starting for the first time:
    212     initMusic();
    213213    if (!g_IsObserver)
    214214    {
    215215        var civMusic = g_CivData[g_Players[Engine.GetPlayerID()].civ].Music;
    216216        global.music.storeTracks(civMusic);
    217217    }
     
    356356                            "players": g_Players,
    357357                            "mapSettings": mapSettings
    358358                         });
    359359}
    360360
     361
    361362// Return some data that we'll use when hotloading this file after changes
    362363function getHotloadData()
    363364{
    364365    return { selection: g_Selection.selected };
    365366}
     
    398399/**
    399400 * Called every frame.
    400401 */
    401402function onTick()
    402403{
     404    if (!g_Settings)
     405        return;
     406
    403407    var now = new Date;
    404408    var tickLength = new Date - lastTickTime;
    405409    lastTickTime = now;
    406410
    407411    checkPlayerState();
     
    507511
    508512function changeGameSpeed(speed)
    509513{
    510514    // For non-networked games only
    511515    if (!g_IsNetworked)
    512     {
    513516        Engine.SetSimRate(speed);
    514         g_CurrentSpeed = speed;
    515     }
    516517}
    517518
    518519/**
    519520 * Recomputes GUI state that depends on simulation state or selection state. Called directly every simulation
    520521 * update (see session.xml), or from onTick when the selection has changed.
  • binaries/data/mods/public/gui/session/session.xml

     
    66<script file="gui/common/functions_civinfo.js"/>
    77<script file="gui/common/functions_global_object.js"/>
    88<script file="gui/common/functions_utility.js"/>
    99<script file="gui/common/l10n.js"/>
    1010<script file="gui/common/music.js"/>
     11<script file="gui/common/settings.js"/>
    1112<script file="gui/common/timer.js"/>
    1213<script file="gui/common/tooltips.js"/>
    1314<!-- load all scripts in this directory -->
    1415<script directory="gui/session/"/>
    1516
  • binaries/data/mods/public/gui/summary/layout.js

     
    137137{
    138138    for (var h = 0; h < MAX_HEADINGTITLE; ++h)
    139139    {
    140140        Engine.GetGUIObjectByName("titleHeading["+ h +"]").hidden = true;
    141141        Engine.GetGUIObjectByName("Heading[" + h + "]").hidden = true;
    142         for (var p = 0; p < MAX_SLOTS; ++p)
     142        for (let p = 0; p < g_Settings.MaxPlayers; ++p)
    143143        {
    144144            Engine.GetGUIObjectByName("valueData[" + p + "][" + h + "]").hidden = true;
    145             for (var t = 0; t < MAX_TEAMS; ++t)
     145            for (let t = 0; t < g_Settings.MaxTeams; ++t)
    146146            {
    147147                Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + p + "][" + h + "]").hidden = true;
    148148                Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + h + "]").hidden = true;
    149149            }
    150150        }
     
    187187
    188188function updateGeneralPanelCounter(counters)
    189189{
    190190    var rowPlayerObjectWidth = 0;
    191191    var left = 0;
    192     for (var p = 0; p < MAX_SLOTS; ++p)
     192    for (let p = 0; p < g_Settings.MaxPlayers; ++p)
    193193    {
    194194        left = 240;
    195195        var counterObject;
    196196        for (var w in counters)
    197197        {
     
    202202        }
    203203        if (rowPlayerObjectWidth == 0)
    204204            rowPlayerObjectWidth = left;
    205205
    206206        var counterTotalObject;
    207         for (var t = 0; t < MAX_TEAMS; ++t)
     207        for (var t = 0; t < g_Settings.MaxTeams; ++t)
    208208        {
    209209            left = 240;
    210210            for (var w in counters)
    211211            {
    212212                counterObject = Engine.GetGUIObjectByName("valueDataTeam[" + t + "][" + p + "][" + w + "]");
     
    262262        Engine.GetGUIObjectByName("playerNameHeading").caption = "";
    263263}
    264264
    265265function updateObjectPlayerPosition()
    266266{
    267     for (var h = 0; h < MAX_SLOTS; ++h)
     267    for (let h = 0; h < g_Settings.MaxPlayers; ++h)
    268268    {
    269269        var playerBox = Engine.GetGUIObjectByName("playerBox[" + h + "]");
    270270        var boxSize = playerBox.size;
    271271        boxSize.top += h * (PLAYER_BOX_Y_SIZE + PLAYER_BOX_GAP);
    272272        boxSize.bottom = boxSize.top + PLAYER_BOX_Y_SIZE;
    273273        playerBox.size = boxSize;
    274274
    275         for (var i = 0; i < MAX_TEAMS; ++i)
     275        for (let i = 0; i < g_Settings.MaxTeams; ++i)
    276276        {
    277277            var playerBoxt = Engine.GetGUIObjectByName("playerBoxt[" + i + "][" + h + "]");
    278278            boxSize = playerBoxt.size;
    279279            boxSize.top += h * (PLAYER_BOX_Y_SIZE + PLAYER_BOX_GAP);
    280280            boxSize.bottom = boxSize.top + PLAYER_BOX_Y_SIZE;
  • binaries/data/mods/public/gui/summary/summary.js

     
    1 // Max player slots for any map (TODO: should read from config)
    2 const MAX_SLOTS = 8;
    3 const MAX_TEAMS = 4;
    41const MAX_HEADINGTITLE = 8;
    52
    63// const for filtering long collective headings
    74const LONG_HEADING_WIDTH = 250;
    85// Vertical size of player box
     
    4340 * Select active panel
    4441 * @param panelNumber Number of panel, which should get active state (integer)
    4542 */
    4643function selectPanel(panelNumber)
    4744{
     45    if (!g_Settings)
     46        return;
     47
    4848    var panelNames = [ 'scorePanel', 'buildingsPanel', 'unitsPanel', 'resourcesPanel', 'marketPanel', 'miscPanel'];
    4949
    5050    function adjustTabDividers(tabSize)
    5151    {
    5252        var leftSpacer = Engine.GetGUIObjectByName("tabDividerLeft");
     
    130130        teamCounterFn(panelInfo.counters);
    131131}
    132132
    133133function init(data)
    134134{
     135    if (!g_Settings)
     136        return;
     137
    135138    updateObjectPlayerPosition();
    136139    g_GameData = data;
    137140
    138     // Map
    139     var mapDisplayType = translate("Scenario");
    140 
    141141    Engine.GetGUIObjectByName("timeElapsed").caption = sprintf(translate("Game time elapsed: %(time)s"), { time: timeToString(data.timeElapsed) });
    142142
    143143    Engine.GetGUIObjectByName("summaryText").caption = data.gameResult;
    144144
    145     // This is only defined for random maps
    146     if (data.mapSettings.Size)
    147     {
    148         // load the map sizes from the JSON file
    149         var mapSizes = initMapSizes();
    150 
    151         // retrieve the index of the map size
    152         for (var mapSizeIndex in mapSizes.tiles)
    153         {
    154             if (mapSizes.tiles[mapSizeIndex] == data.mapSettings.Size)
    155             {
    156                 mapDisplayType = mapSizes.names[mapSizeIndex];
    157                 break;
    158             }
    159         }
    160     }
    161 
    162     Engine.GetGUIObjectByName("mapName").caption = sprintf(translate("%(mapName)s - %(mapType)s"), { mapName: translate(data.mapSettings.Name), mapType: mapDisplayType});
     145    var mapDisplayType = data.mapSettings.mapType == "random" ? translateMapSize(data.mapSettings.Size) : translateMapType(data.mapSettings.mapType);
     146    Engine.GetGUIObjectByName("mapName").caption = sprintf(translate("%(mapName)s - %(mapType)s"),
     147            { mapName: translate(data.mapSettings.Name), mapType: mapDisplayType});
    163148
    164149    // Panels
    165150    g_MaxPlayers = data.playerStates.length - 1;
    166151
    167152    if (data.mapSettings.LockTeams) // teams ARE locked
  • binaries/data/mods/public/gui/summary/summary.xml

     
    88
    99<objects>
    1010    <script file="gui/common/functions_global_object.js"/>
    1111    <script file="gui/common/functions_civinfo.js"/>
    1212    <script file="gui/common/functions_utility.js"/>
     13    <script file="gui/common/settings.js"/>
    1314    <script file="gui/summary/counters.js"/>
    1415    <script file="gui/summary/layout.js"/>
    1516    <script file="gui/summary/summary.js"/>
    1617
    1718    <object type="image"
  • binaries/data/mods/public/l10n/messages.json

     
    451451                }
    452452            },
    453453            {
    454454                "extractor": "json",
    455455                "filemasks": [
    456                     "simulation/data/game_speeds.json",
    457                     "simulation/data/player_defaults.json"
     456                    "simulation/data/settings/PlayerDefaults.json"
    458457                ],
    459458                "options": {
    460459                    "keywords": [
    461460                        "Name"
    462461                    ]
    463462                }
    464463            },
    465464            {
    466465                "extractor": "json",
    467466                "filemasks": [
    468                     "simulation/data/map_sizes.json"
     467                    "simulation/data/settings/MapSizes.json"
    469468                ],
    470469                "options": {
    471470                    "keywords": [
    472471                        "Name",
    473472                        "LongName"
    474473                    ]
    475474                }
    476475            },
    477476            {
    478477                "extractor": "json",
     478                "filemasks": [
     479                    "simulation/data/settings/GameTypes.json"
     480                ],
     481                "options": {
     482                    "keywords": [
     483                        "Title",
     484                        "Description"
     485                    ]
     486                }
     487            },
     488            {
     489                "extractor": "json",
     490                "filemasks": [
     491                    "simulation/data/settings/AI_Difficulties.json",
     492                    "simulation/data/settings/Ceasefire.json",
     493                    "simulation/data/settings/GameSpeeds.json",
     494                    "simulation/data/settings/MapTypes.json",
     495                    "simulation/data/settings/PopulationCapacity.json",
     496                    "simulation/data/settings/StartingResources.json"
     497                ],
     498                "options": {
     499                    "keywords": [
     500                        "Title"
     501                    ]
     502                }
     503            },
     504            {
     505                "extractor": "json",
    479506                "filemasks": [
    480507                    "simulation/ai/**.json"
    481508                ],
    482509                "options": {
    483510                    "keywords": [
  • binaries/data/mods/public/simulation/data/game_speeds.json

     
    1 {
    2     "Speeds":
    3     [
    4         {
    5             "Name": "Turtle (0.1x)",
    6             "Speed": 0.10
    7         },
    8         {
    9             "Name": "Slow (0.25x)",
    10             "Speed": 0.25
    11         },
    12         {
    13             "Name": "Leisurely (0.5x)",
    14             "Speed": 0.50
    15         },
    16         {
    17             "Name": "Relaxed (0.75x)",
    18             "Speed": 0.75
    19         },
    20         {
    21             "Name": "Normal (1x)",
    22             "Speed": 1.0,
    23             "Default": true
    24         },
    25         {
    26             "Name": "Fast (1.25x)",
    27             "Speed": 1.25
    28         },
    29         {
    30             "Name": "Very Fast (1.5x)",
    31             "Speed": 1.5
    32         },
    33         {
    34             "Name": "Insane (2x)",
    35             "Speed": 2.0
    36         }
    37     ]
    38 }
  • binaries/data/mods/public/simulation/data/map_sizes.json

     
    1 {
    2     "Sizes":
    3     [
    4         {
    5             "Name": "Tiny",
    6             "LongName": "Tiny",
    7             "Tiles": 128
    8         },
    9         {
    10             "Name": "Small",
    11             "LongName": "Small (2 players)",
    12             "Tiles": 192
    13         },
    14         {
    15             "Name": "Medium",
    16             "LongName": "Medium (3 players)",
    17             "Tiles": 256,
    18             "Default": true
    19         },
    20         {
    21             "Name": "Normal",
    22             "LongName": "Normal (4 players)",
    23             "Tiles": 320
    24         },
    25         {
    26             "Name": "Large",
    27             "LongName": "Large (6 players)",
    28             "Tiles": 384
    29         },
    30         {
    31             "Name": "Very Large",
    32             "LongName": "Very Large (8 players)",
    33             "Tiles": 448
    34         },
    35         {
    36             "Name": "Giant",
    37             "LongName": "Giant",
    38             "Tiles": 512
    39         }
    40     ]
    41 }
  • binaries/data/mods/public/simulation/data/player_defaults.json

     
    1 {
    2     "PlayerData":
    3     [
    4         {
    5             "Name": "Gaia",
    6             "Civ": "gaia",
    7             "Color": { "r": 255, "g": 255, "b": 255 },
    8             "AI": "",
    9             "AIDiff": 3
    10         },
    11         {
    12             "Name": "Player 1",
    13             "Civ": "athen",
    14             "Color": { "r": 46, "g": 46, "b": 200 },
    15             "AI": "",
    16             "AIDiff": 3
    17         },
    18         {
    19             "Name": "Player 2",
    20             "Civ": "cart",
    21             "Color": { "r": 150, "g": 20, "b": 20 },
    22             "AI": "petra",
    23             "AIDiff": 3
    24         },
    25         {
    26             "Name": "Player 3",
    27             "Civ": "gaul",
    28             "Color": { "r": 50, "g": 165, "b": 5 },
    29             "AI": "petra",
    30             "AIDiff": 3
    31         },
    32         {
    33             "Name": "Player 4",
    34             "Civ": "iber",
    35             "Color": { "r": 230, "g": 230, "b": 75 },
    36             "AI": "petra",
    37             "AIDiff": 3
    38         },
    39         {
    40             "Name": "Player 5",
    41             "Civ": "mace",
    42             "Color": { "r": 50, "g": 170, "b": 170 },
    43             "AI": "petra",
    44             "AIDiff": 3
    45         },
    46         {
    47             "Name": "Player 6",
    48             "Civ": "maur",
    49             "Color": { "r": 160, "g": 80, "b": 200 },
    50             "AI": "petra",
    51             "AIDiff": 3
    52         },
    53         {
    54             "Name": "Player 7",
    55             "Civ": "pers",
    56             "Color": { "r": 235, "g": 120, "b": 20 },
    57             "AI": "petra",
    58             "AIDiff": 3
    59         },
    60         {
    61             "Name": "Player 8",
    62             "Civ": "rome",
    63             "Color": { "r": 64, "g": 64, "b": 64 },
    64             "AI": "petra",
    65             "AIDiff": 3
    66         }
    67     ]
    68 }
  • binaries/data/mods/public/simulation/data/settings/AI_Difficulties.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "AI_Difficulties":
     4    [
     5        {
     6            "Name": "sandbox",
     7            "Title": "Sandbox"
     8        },
     9        {
     10            "Name": "very easy",
     11            "Title": "Very Easy"
     12        },
     13        {
     14            "Name": "easy",
     15            "Title": "Easy"
     16        },
     17        {
     18            "Name": "medium",
     19            "Title": "Medium",
     20            "Default": true
     21        },
     22        {
     23            "Name": "hard",
     24            "Title": "Hard"
     25        },
     26        {
     27            "Name": "very hard",
     28            "Title": "Very Hard"
     29        }
     30    ]
     31}
     32 No newline at end of file
  • binaries/data/mods/public/simulation/data/settings/Ceasefire.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "Ceasefire":
     4    [
     5        {
     6            "Duration": 0,
     7            "Title": "No ceasefire",
     8            "Default": true
     9        },
     10        {
     11            "Duration": 1,
     12            "Title": "1 minute"
     13        },
     14        {
     15            "Duration": 2,
     16            "Title": "2 minutes"
     17        },
     18        {
     19            "Duration": 3,
     20            "Title": "3 minutes"
     21        },
     22        {
     23            "Duration": 5,
     24            "Title": "5 minutes"
     25        },
     26        {
     27            "Duration": 10,
     28            "Title": "10 minutes"
     29        },
     30        {
     31            "Duration": 15,
     32            "Title": "15 minutes"
     33        },
     34        {
     35            "Duration": 20,
     36            "Title": "20 minutes"
     37        },
     38        {
     39            "Duration": 30,
     40            "Title": "30 minutes"
     41        },
     42        {
     43            "Duration": 45,
     44            "Title": "45 minutes"
     45        },
     46        {
     47            "Duration": 60,
     48            "Title": "60 minutes"
     49        }
     50    ]
     51}
  • binaries/data/mods/public/simulation/data/settings/GameSpeeds.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "GameSpeeds":
     4    [
     5        {
     6            "Speed": 0.10,
     7            "Title": "Turtle (0.1x)"
     8        },
     9        {
     10            "Speed": 0.25,
     11            "Title": "Slow (0.25x)"
     12        },
     13        {
     14            "Speed": 0.50,
     15            "Title": "Leisurely (0.5x)"
     16        },
     17        {
     18            "Speed": 0.75,
     19            "Title": "Relaxed (0.75x)"
     20        },
     21        {
     22            "Speed": 1.0,
     23            "Title": "Normal (1x)",
     24            "Default": true
     25        },
     26        {
     27            "Speed": 1.25,
     28            "Title": "Fast (1.25x)"
     29        },
     30        {
     31            "Speed": 1.5,
     32            "Title": "Very Fast (1.5x)"
     33        },
     34        {
     35            "Speed": 2.0,
     36            "Title": "Insane (2x)"
     37        }
     38    ]
     39}
  • binaries/data/mods/public/simulation/data/settings/GameTypes.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "GameTypes":
     4    [
     5        {
     6            "Name": "endless",
     7            "Title": "None",
     8            "Description": "Endless Game",
     9            "Scripts": []
     10        },
     11        {
     12            "Name": "conquest",
     13            "Title": "Conquest",
     14            "Description": "Defeat all opponents",
     15            "Scripts":
     16            [
     17                "scripts/TriggerHelper.js",
     18                "scripts/ConquestCommon.js",
     19                "scripts/Conquest.js"
     20            ],
     21            "Default": true
     22        },
     23        {
     24            "Name": "conquestStructures",
     25            "Title": "Conquest Structures",
     26            "Description": "Destroy all structures of enemies",
     27            "Scripts":
     28            [
     29                "scripts/TriggerHelper.js",
     30                "scripts/ConquestCommon.js",
     31                "scripts/ConquestStructures.js"
     32            ]
     33        },
     34        {
     35            "Name": "conquestUnits",
     36            "Title": "Conquest Units",
     37            "Description": "Kill all enemy units",
     38            "Scripts":
     39            [
     40                "scripts/TriggerHelper.js",
     41                "scripts/ConquestCommon.js",
     42                "scripts/ConquestUnits.js"
     43            ]
     44        },
     45        {
     46            "Name": "wonder",
     47            "Title": "Wonder",
     48            "Description": "Build and protect a wonder to win",
     49            "Scripts":
     50            [
     51                "scripts/TriggerHelper.js",
     52                "scripts/ConquestCommon.js",
     53                "scripts/Conquest.js",
     54                "scripts/WonderVictory.js"
     55            ]
     56        }
     57    ]
     58}
  • binaries/data/mods/public/simulation/data/settings/MapSizes.json

     
     1{
     2    "TranslatedKeys": ["Name", "LongName"],
     3    "MapSizes":
     4    [
     5        {
     6            "Tiles": 128,
     7            "Name": "Tiny",
     8            "LongName": "Tiny"
     9        },
     10        {
     11            "Tiles": 192,
     12            "Name": "Small",
     13            "LongName": "Small (2 players)"
     14        },
     15        {
     16            "Tiles": 256,
     17            "Name": "Medium",
     18            "LongName": "Medium (3 players)",
     19            "Default": true
     20        },
     21        {
     22            "Tiles": 320,
     23            "Name": "Normal",
     24            "LongName": "Normal (4 players)"
     25        },
     26        {
     27            "Tiles": 384,
     28            "Name": "Large",
     29            "LongName": "Large (6 players)"
     30        },
     31        {
     32            "Tiles": 448,
     33            "Name": "Very Large",
     34            "LongName": "Very Large (8 players)"
     35        },
     36        {
     37            "Tiles": 512,
     38            "Name": "Giant",
     39            "LongName": "Giant"
     40        }
     41    ]
     42}
  • binaries/data/mods/public/simulation/data/settings/MapTypes.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "MapTypes":
     4    [
     5        {
     6            "Name": "skirmish",
     7            "Title": "Skirmish",
     8            "Default": true
     9        },
     10        {
     11            "Name": "random",
     12            "Title": "Random"
     13        },
     14        {
     15            "Name": "scenario",
     16            "Title": "Scenario"
     17        }
     18    ]
     19}
     20 No newline at end of file
  • binaries/data/mods/public/simulation/data/settings/PlayerDefaults.json

     
     1{
     2    "TranslatedKeys": ["Name"],
     3    "PlayerDefaults":
     4    [
     5        {
     6            "Name": "Gaia",
     7            "Civ": "gaia",
     8            "Color": { "r": 255, "g": 255, "b": 255 },
     9            "AI": "",
     10            "AIDiff": 3
     11        },
     12        {
     13            "Name": "Player 1",
     14            "Civ": "athen",
     15            "Color": { "r": 46, "g": 46, "b": 200 },
     16            "AI": "",
     17            "AIDiff": 3
     18        },
     19        {
     20            "Name": "Player 2",
     21            "Civ": "cart",
     22            "Color": { "r": 150, "g": 20, "b": 20 },
     23            "AI": "petra",
     24            "AIDiff": 3
     25        },
     26        {
     27            "Name": "Player 3",
     28            "Civ": "gaul",
     29            "Color": { "r": 50, "g": 165, "b": 5 },
     30            "AI": "petra",
     31            "AIDiff": 3
     32        },
     33        {
     34            "Name": "Player 4",
     35            "Civ": "iber",
     36            "Color": { "r": 230, "g": 230, "b": 75 },
     37            "AI": "petra",
     38            "AIDiff": 3
     39        },
     40        {
     41            "Name": "Player 5",
     42            "Civ": "mace",
     43            "Color": { "r": 50, "g": 170, "b": 170 },
     44            "AI": "petra",
     45            "AIDiff": 3
     46        },
     47        {
     48            "Name": "Player 6",
     49            "Civ": "maur",
     50            "Color": { "r": 160, "g": 80, "b": 200 },
     51            "AI": "petra",
     52            "AIDiff": 3
     53        },
     54        {
     55            "Name": "Player 7",
     56            "Civ": "pers",
     57            "Color": { "r": 235, "g": 120, "b": 20 },
     58            "AI": "petra",
     59            "AIDiff": 3
     60        },
     61        {
     62            "Name": "Player 8",
     63            "Civ": "rome",
     64            "Color": { "r": 64, "g": 64, "b": 64 },
     65            "AI": "petra",
     66            "AIDiff": 3
     67        }
     68    ]
     69}
  • binaries/data/mods/public/simulation/data/settings/PlayerLimit.json

     
     1{
     2    "MaxPlayers": 8,
     3    "MaxTeams": 4
     4}
  • binaries/data/mods/public/simulation/data/settings/PopulationCapacity.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "PopulationCapacity":
     4    [
     5        {
     6            "Population": 50,
     7            "Title": "50"
     8        },
     9        {
     10            "Population": 100,
     11            "Title": "100"
     12        },
     13        {
     14            "Population": 150,
     15            "Title": "150"
     16        },
     17        {
     18            "Population": 200,
     19            "Title": "200"
     20        },
     21        {
     22            "Population": 250,
     23            "Title": "250"
     24        },
     25        {
     26            "Population": 300,
     27            "Title": "300",
     28            "Default": true
     29        },
     30        {
     31            "Population": 10000,
     32            "Title": "Unlimited"
     33        }
     34    ]
     35}
  • binaries/data/mods/public/simulation/data/settings/StartingResources.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "StartingResources":
     4    [
     5        {
     6            "Resources": 100,
     7            "Title": "Very Low"
     8        },
     9        {
     10            "Resources": 300,
     11            "Title": "Low",
     12            "Default": true
     13        },
     14        {
     15            "Resources": 500,
     16            "Title": "Medium"
     17        },
     18        {
     19            "Resources": 1000,
     20            "Title": "High"
     21        },
     22        {
     23            "Resources": 3000,
     24            "Title": "Very High"
     25        },
     26        {
     27            "Resources": 50000,
     28            "Title": "Deathmatch"
     29        }
     30    ]
     31}
  • binaries/data/mods/public/simulation/helpers/Player.js

     
    1313    // Default settings
    1414    if (!settings)
    1515        settings = {};
    1616
    1717    // Get default player data
    18     var rawData = Engine.ReadJSONFile("player_defaults.json");
    19     if (!(rawData && rawData.PlayerData))
    20         throw("Player.js: Error reading player_defaults.json");
     18    var rawData = Engine.ReadJSONFile("settings/PlayerDefaults.json");
     19    if (!rawData || !rawData.PlayerDefaults)
     20        throw("Player.js: Error reading PlayerDefaults.json");
    2121
    2222    // Add gaia to simplify iteration
    2323    if (settings.PlayerData && settings.PlayerData[0])
    2424        settings.PlayerData.unshift(null);
    2525
    26     var playerDefaults = rawData.PlayerData;
     26    var playerDefaults = rawData.PlayerDefaults;
    2727    var playerData = settings.PlayerData;
    2828
    2929    // Get player manager
    3030    var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
    3131    var numPlayers = cmpPlayerManager.GetNumPlayers();
     
    168168            var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player);
    169169            cmpPlayer.SetLockTeams(true);
    170170        }
    171171
    172172    // Disable the AIIinterface when no AI players are present
    173     if (playerData && !playerData.some(function(v) { return v && v.AI ? true : false; }))
     173    if (playerData && playerData.every(player => !player || !player.AI))
    174174        Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface).Disable();
    175175}
    176176
    177177// Get a setting if it exists or return default
    178178function getSetting(settings, defaults, idx, property)
  • source/simulation2/Simulation2.cpp

     
    878878    return file.DecodeUTF8(); // assume it's UTF-8
    879879}
    880880
    881881std::string CSimulation2::GetPlayerDefaults()
    882882{
    883     return ReadJSON(L"simulation/data/player_defaults.json");
     883    return ReadJSON(L"simulation/data/settings/PlayerDefaults.json");
    884884}
    885885
    886886std::string CSimulation2::GetMapSizes()
    887887{
    888     return ReadJSON(L"simulation/data/map_sizes.json");
     888    return ReadJSON(L"simulation/data/settings/MapSizes.json");
    889889}
    890890
    891891std::string CSimulation2::GetAIData()
    892892{
    893893    ScriptInterface& scriptInterface = GetScriptInterface();
  • source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp

     
    139139    sizer->Add(Tooltipped(new wxTextCtrl(this, ID_MapDescription, wxEmptyString, wxDefaultPosition, wxSize(-1, 100), wxTE_MULTILINE),
    140140            _("Short description used on the map selection screen")), wxSizerFlags().Expand());
    141141
    142142    sizer->AddSpacer(5);
    143143
     144    // TODO: load from GameTypes.json
    144145    wxArrayString gameTypes;
    145146    gameTypes.Add(_T("conquest"));
     147    gameTypes.Add(_T("conquestStructures"));
     148    gameTypes.Add(_T("conquestUnits"));
    146149    gameTypes.Add(_T("wonder"));
    147150    gameTypes.Add(_T("endless"));
    148151
    149152    wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);
    150153    gridSizer->AddGrowableCol(1);
  • source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp

     
    535535    // Get player names
    536536    wxArrayString players;
    537537    AtlasMessage::qGetPlayerDefaults qryPlayers;
    538538    qryPlayers.Post();
    539539    AtObj playerData = AtlasObject::LoadFromJSON(*qryPlayers.defaults);
    540     AtObj playerDefs = *playerData["PlayerData"];
     540    AtObj playerDefs = *playerData["PlayerDefaults"];
    541541    for (AtIter p = playerDefs["item"]; p.defined(); ++p)
    542542    {
    543543        players.Add(wxString(p["Name"]));
    544544    }
    545545    wxDynamicCast(FindWindow(ID_PlayerSelect), PlayerComboBox)->SetPlayers(players);
  • source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Player/Player.cpp

     
    517517            POST_MESSAGE(LoadPlayerSettings, (true));
    518518            m_MapSettings.NotifyObservers();
    519519        }
    520520    }
    521521
    522     // TODO: we shouldn't hardcode this, but instead dynamically create
    523     //  new player notebook pages on demand; of course the default data
    524     //  will be limited by the entries in player_defaults.json
     522    // TODO: Load value from PlayerLimit.json
    525523    static const size_t MAX_NUM_PLAYERS = 8;
    526524
    527525    bool m_InGUIUpdate;
    528526    AtObj m_PlayerDefaults;
    529527    PlayerNotebook* m_Players;
     
    640638void PlayerSettingsControl::LoadDefaults()
    641639{
    642640    AtlasMessage::qGetPlayerDefaults qryPlayers;
    643641    qryPlayers.Post();
    644642    AtObj playerData = AtlasObject::LoadFromJSON(*qryPlayers.defaults);
    645     m_PlayerDefaults = *playerData["PlayerData"];
     643    m_PlayerDefaults = *playerData["PlayerDefaults"];
    646644}
    647645
    648646void PlayerSettingsControl::ReadFromEngine()
    649647{
    650648    AtlasMessage::qGetMapSettings qry;