From bbc325fb5a3ba752264de0cbd40a5eaa0492fc6c Mon Sep 17 00:00:00 2001 From: elexis Date: Fri, 4 Dec 2015 23:45:35 +0000 Subject: [PATCH] Gamesetup cleanup. Refs #3680. Don't even load non-playable civs in the gamesetup and add sanity checks to sanitizePlayerData() and loadCivData() so that we can remove later checks. Remove some blatantly wrong code from launchGame(). Move hardcoded romanNumbers to a global. This was SVN commit r17381. --- .../data/mods/public/gui/civinfo/civinfo.js | 7 +- .../public/gui/common/functions_civinfo.js | 6 + .../mods/public/gui/gamesetup/gamesetup.js | 131 ++++++++---------- 3 files changed, 66 insertions(+), 78 deletions(-) diff --git a/binaries/data/mods/public/gui/civinfo/civinfo.js b/binaries/data/mods/public/gui/civinfo/civinfo.js index a6ea7858ae..07491bc04b 100644 --- a/binaries/data/mods/public/gui/civinfo/civinfo.js +++ b/binaries/data/mods/public/gui/civinfo/civinfo.js @@ -1,11 +1,14 @@ -const g_CivData = loadCivData(); +/** + * Load playable civs. + */ +const g_CivData = loadCivData(true); /** * Initialize the dropdown containing all the available civs. */ function init(settings) { - var civList = Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase); + var civList = Object.keys(g_CivData).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase); var civSelection = Engine.GetGUIObjectByName("civSelection"); civSelection.list = civList.map(civ => civ.name); diff --git a/binaries/data/mods/public/gui/common/functions_civinfo.js b/binaries/data/mods/public/gui/common/functions_civinfo.js index f65152d834..1c0aadc0f0 100644 --- a/binaries/data/mods/public/gui/common/functions_civinfo.js +++ b/binaries/data/mods/public/gui/common/functions_civinfo.js @@ -17,6 +17,12 @@ function loadCivData(playableOnly = false) translateObjectKeys(data, ["Name", "Description", "History", "Special"]); if (!playableOnly || data.SelectableInGameSetup) civData[data.Code] = data; + + // Sanity check + for (let prop of ["Code", "Culture", "Name", "Emblem", "History", "Music", "Factions", "CivBonuses", + "TeamBonuses", "Structures", "StartEntities", "Formations", "AINames","SelectableInGameSetup"]) + if (!data[prop]) + error(filename + " doesn't contain " + prop); } return civData; diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index 9ce2492d5b..704dd49e4c 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -9,10 +9,20 @@ const g_PopulationCapacities = prepareForDropdown(g_Settings ? g_Settings.Popula const g_StartingResources = prepareForDropdown(g_Settings ? g_Settings.StartingResources : undefined); const g_VictoryConditions = prepareForDropdown(g_Settings ? g_Settings.VictoryConditions : undefined); -// All colors except gaia +/** + * All selectable playercolors except gaia. + */ const g_PlayerColors = g_Settings ? g_Settings.PlayerDefaults.slice(1).map(pData => pData.Color) : undefined; -const g_CivData = loadCivData(); +/** + * Used for generating the botnames. + */ +const g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"]; + +/** + * Load playable civs. + */ +const g_CivData = loadCivData(true); // Is this is a networked game, or offline var g_IsNetworked; @@ -37,7 +47,9 @@ var g_ReadyInit = true; // 2 - Host's initial ready, suppressed settings message, 1 - Will show settings message, <=0 - Suppressed settings message var g_ReadyChanged = 2; -// Has the game started? +/** + * Used to prevent calling resetReadyData when starting a game. + */ var g_GameStarted = false; var g_PlayerAssignments = {}; @@ -564,7 +576,7 @@ function getSetting(settings, defaults, property) */ function initCivNameList() { - var civList = Object.keys(g_CivData).filter(civ => g_CivData[civ].SelectableInGameSetup).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase); + var civList = Object.keys(g_CivData).map(civ => ({ "name": g_CivData[civ].Name, "code": civ })).sort(sortNameIgnoreCase); var civListNames = civList.map(civ => civ.name); var civListCodes = civList.map(civ => civ.code); @@ -702,20 +714,8 @@ function loadGameAttributes() if (!g_IsNetworked) mapSettings.CheatsEnabled = true; - var civListCodes = [ civ.Code for each (civ in g_CivData) if (civ.SelectableInGameSetup !== false) ]; - civListCodes.push("random"); - - var playerData = mapSettings.PlayerData; - - // Validate player civs - if (playerData) - for (var i = 0; i < playerData.length; ++i) - { - if (civListCodes.indexOf(playerData[i].Civ) < 0) - playerData[i].Civ = "random"; - } - // Refresh probably obsoleted/incomplete map data. + var playerData = mapSettings.PlayerData; var newMapData = loadMapData(mapName); if (newMapData && newMapData.settings) { @@ -781,14 +781,13 @@ function saveGameAttributes() function sanitizePlayerData(playerData) { - // Ignore gaia + // Remove gaia if (playerData.length && !playerData[0]) playerData.shift(); - // Set default color if no color present playerData.forEach((pData, index) => { - if (pData && !pData.Color) - pData.Color = g_PlayerColors[index]; + pData.Color = pData.Color || g_PlayerColors[index]; + pData.Civ = pData.Civ || "random"; }); // Replace colors with the best matching color of PlayerDefaults @@ -1086,12 +1085,12 @@ function launchGame() return; } - // Check that we have a map if (!g_GameAttributes.map) return; saveGameAttributes(); + // Select random map if (g_GameAttributes.map == "random") { let victoryScriptsSelected = g_GameAttributes.settings.VictoryScripts; @@ -1101,58 +1100,41 @@ function launchGame() g_GameAttributes.settings.VictoryScripts = victoryScriptsSelected; g_GameAttributes.settings.GameType = gameTypeSelected; } - if (!g_GameAttributes.settings.TriggerScripts) - g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts; - else - g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts.concat(g_GameAttributes.settings.TriggerScripts); + + g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts.concat(g_GameAttributes.settings.TriggerScripts || []); + + // Prevent reseting the readystate g_GameStarted = true; + g_GameAttributes.settings.mapType = g_GameAttributes.mapType; - var numPlayers = g_GameAttributes.settings.PlayerData.length; - // Assign random civilizations to players with that choice - // (this is synchronized because we're the host) - var cultures = []; - for each (var civ in g_CivData) - if (civ.Culture !== undefined && cultures.indexOf(civ.Culture) < 0 && civ.SelectableInGameSetup !== false) - cultures.push(civ.Culture); - var allcivs = new Array(cultures.length); - for (var i = 0; i < allcivs.length; ++i) - allcivs[i] = []; - for each (var civ in g_CivData) - if (civ.Culture !== undefined && civ.SelectableInGameSetup !== false) - allcivs[cultures.indexOf(civ.Culture)].push(civ.Code); - const romanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"]; - for (var i = 0; i < numPlayers; ++i) + // Get a unique array of cultures + var cultures = Object.keys(g_CivData).map(civ => g_CivData[civ].Culture); + cultures = cultures.filter((culture, index) => cultures.indexOf(culture) === index); + + // Determine random civs and botnames + for (let i in g_GameAttributes.settings.PlayerData) { - var civs = allcivs[Math.floor(Math.random()*allcivs.length)]; - - if (!g_GameAttributes.settings.PlayerData[i].Civ || g_GameAttributes.settings.PlayerData[i].Civ == "random") - g_GameAttributes.settings.PlayerData[i].Civ = civs[Math.floor(Math.random()*civs.length)]; - // Setting names for AI players. Check if the player is AI and the match is not a scenario - if (g_GameAttributes.mapType !== "scenario" && g_GameAttributes.settings.PlayerData[i].AI) + // Pick a random civ of a random culture + let chosenCiv = g_GameAttributes.settings.PlayerData[i].Civ || "random"; + if (chosenCiv == "random") { - // Get the civ specific names - if (g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].AINames !== undefined) - var civAINames = shuffleArray(g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].AINames); - else - var civAINames = [g_CivData[g_GameAttributes.settings.PlayerData[i].Civ].Name]; - // Choose the name - var usedName = 0; - if (i < civAINames.length) - var chosenName = civAINames[i]; - else - var chosenName = civAINames[Math.floor(Math.random() * civAINames.length)]; - for (var j = 0; j < numPlayers; ++j) - if (g_GameAttributes.settings.PlayerData[j].Name && g_GameAttributes.settings.PlayerData[j].Name.indexOf(chosenName) !== -1) - usedName++; - - // Assign civ specific names to AI players - chosenName = translate(chosenName); - if (usedName) - g_GameAttributes.settings.PlayerData[i].Name = sprintf(translate("%(playerName)s %(romanNumber)s"), { "playerName": chosenName, "romanNumber": romanNumbers[usedName+1] }); - else - g_GameAttributes.settings.PlayerData[i].Name = chosenName; + let culture = cultures[Math.floor(Math.random() * cultures.length)]; + let civs = Object.keys(g_CivData).filter(civ => g_CivData[civ].Culture == culture); + chosenCiv = civs[Math.floor(Math.random() * civs.length)]; } + g_GameAttributes.settings.PlayerData[i].Civ = chosenCiv; + + // Pick one of the available botnames for the chosen civ + if (g_GameAttributes.mapType === "scenario" || !g_GameAttributes.settings.PlayerData[i].AI) + continue; + + let chosenName = translate(g_CivData[chosenCiv].AINames[Math.floor(Math.random() * g_CivData[chosenCiv].AINames.length)]); + + // Count how many players use the chosenName + let usedName = g_GameAttributes.settings.PlayerData.filter(pData => pData.Name && pData.Name.indexOf(chosenName) !== -1).length; + + g_GameAttributes.settings.PlayerData[i].Name = !usedName ? chosenName : sprintf(translate("%(playerName)s %(romanNumber)s"), { "playerName": chosenName, "romanNumber": g_RomanNumbers[usedName+1] }); } // Copy playernames from initial player assignment to the settings @@ -1171,16 +1153,13 @@ function launchGame() else { // Find the player ID which the user has been assigned to - var numPlayers = g_GameAttributes.settings.PlayerData.length; - var playerID = -1; - for (var i = 0; i < numPlayers; ++i) + let playerID = -1; + for (let i in g_GameAttributes.settings.PlayerData) { - var assignBox = Engine.GetGUIObjectByName("playerAssignment["+i+"]"); + let assignBox = Engine.GetGUIObjectByName("playerAssignment["+i+"]"); if (assignBox.list_data[assignBox.selected] == "local") - playerID = i+1; + playerID = +i+1; } - // Remove extra player data - g_GameAttributes.settings.PlayerData = g_GameAttributes.settings.PlayerData.slice(0, numPlayers); Engine.StartGame(g_GameAttributes, playerID); Engine.SwitchGuiPage("page_loading.xml", { @@ -1925,7 +1904,7 @@ function resetReadyData() return; if (g_ReadyChanged < 1) - addChatMessage({ "type": "settings"}); + addChatMessage({ "type": "settings" }); else if (g_ReadyChanged == 2 && !g_ReadyInit) return; // duplicate calls on init else