Index: binaries/data/mods/public/globalscripts/Templates.js =================================================================== --- binaries/data/mods/public/globalscripts/Templates.js +++ binaries/data/mods/public/globalscripts/Templates.js @@ -8,7 +8,7 @@ { let propertyNames = [ "Code", "Culture", "Name", "Emblem", "History", "Music", "Factions", "CivBonuses", "TeamBonuses", - "Structures", "StartEntities", "Formations", "AINames", "SkirmishReplacements", "SelectableInGameSetup"]; + "Structures", "StartEntities", "Formations", "AINames", "AINameNumbers", "SkirmishReplacements", "SelectableInGameSetup"]; let civData = {}; Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js =================================================================== --- binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -56,11 +56,6 @@ */ var g_NumPlayersList = Array(g_MaxPlayers).fill(0).map((v, i) => i + 1); -/** - * Used for generating the botnames. - */ -var g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"]; - var g_PlayerTeamList = prepareForDropdown([{ "label": translateWithContext("team", "None"), "id": -1 @@ -2317,26 +2312,10 @@ g_CivData[civ].Culture == culture && g_CivData[civ].SelectableInGameSetup)); } 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 = pickRandom(g_CivData[chosenCiv].AINames); - - if (!g_IsNetworked) - chosenName = translate(chosenName); - - // 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] - }); } + chooseAINames(); + // Copy playernames for the purpose of replays for (let guid in g_PlayerAssignments) { @@ -2376,6 +2355,55 @@ } } +/** + * Assigns names to the AI players depending on the chosen civ. + * Tries to pick unique names, otherwise deduplicates playernames by appending a number from the civ file. + */ +function chooseAINames() +{ + if (g_GameAttributes.mapType === "scenario") + return; + + let nameUsers = name => + g_GameAttributes.settings.PlayerData.filter( + pData => pData.Name && pData.Name.indexOf(name) !== -1).length; + + g_GameAttributes.settings.PlayerData.forEach((pData, i) => { + + if (!pData.AI) + return; + + let civNames = g_CivData[pData.Civ].AINames; + + let unusedCivNames = civNames.filter(name => !nameUsers(name)); + let chosenName = pickRandom(unusedCivNames.length ? unusedCivNames : civNames); + + // Don't translate playernames visible to all players into the local language of the host + if (!g_IsNetworked) + chosenName = translate(chosenName); + + if (!unusedCivNames.length) + { + // Count how many players use the chosenName + let useCount = g_GameAttributes.settings.PlayerData.filter( + pData => pData.Name && pData.Name.indexOf(chosenName) != -1).length; + + let chosenNumber = g_CivData[pData.Civ].AINameNumbers[useCount]; + + if (!g_IsNetworked) + chosenNumber = translateWithContext("AI name number", chosenNumber); + + chosenName = + sprintf(translate("%(playerName)s %(playerNumber)s"), { + "playerName": chosenName, + "playerNumber": chosenNumber + }); + } + + pData.Name = chosenName; + }); +} + function launchTutorial() { g_GameAttributes.mapType = "scenario"; Index: binaries/data/mods/public/l10n/messages.json =================================================================== --- binaries/data/mods/public/l10n/messages.json +++ binaries/data/mods/public/l10n/messages.json @@ -19,6 +19,21 @@ "AINames" ] } + }, + { + "extractor": "json", + "filemasks": [ + "simulation/data/civs/**.json" + ], + "options": { + "keywords": [ + "AINameNumbers" + ], + "comments": [ + "Translation: Number appended to ambiguous names. For example VII for Cleopatra VII." + ], + "context": "AI name number" + } } ] }, Index: binaries/data/mods/public/simulation/data/civs/athen.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/athen.json +++ binaries/data/mods/public/simulation/data/civs/athen.json @@ -168,6 +168,17 @@ "Iphicrates", "Demosthenes" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_ranged_b": "units/athen_infantry_slinger_b", Index: binaries/data/mods/public/simulation/data/civs/brit.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/brit.json +++ binaries/data/mods/public/simulation/data/civs/brit.json @@ -145,6 +145,17 @@ "Dubnovellaunus", "Vosenius" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_ranged_b": "units/brit_infantry_slinger_b", Index: binaries/data/mods/public/simulation/data/civs/cart.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/cart.json +++ binaries/data/mods/public/simulation/data/civs/cart.json @@ -173,6 +173,17 @@ "Himilco Phameas", "Hasdrubal the Boetharch" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_ranged_b": "units/cart_infantry_archer_b", Index: binaries/data/mods/public/simulation/data/civs/gaul.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/gaul.json +++ binaries/data/mods/public/simulation/data/civs/gaul.json @@ -140,6 +140,17 @@ "Valetiacus", "Viridovix" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/structures/default_house_5": "structures/{civ}_house" Index: binaries/data/mods/public/simulation/data/civs/iber.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/iber.json +++ binaries/data/mods/public/simulation/data/civs/iber.json @@ -136,6 +136,17 @@ "Minurus", "Tautalus" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_melee_b": "units/iber_infantry_swordsman_b", Index: binaries/data/mods/public/simulation/data/civs/kush.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/kush.json +++ binaries/data/mods/public/simulation/data/civs/kush.json @@ -163,6 +163,17 @@ "Shanakdakhete", "Amanishakheto" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_ranged_b": "units/kush_infantry_archer_b", Index: binaries/data/mods/public/simulation/data/civs/mace.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/mace.json +++ binaries/data/mods/public/simulation/data/civs/mace.json @@ -163,6 +163,17 @@ "Craterus", "Meleager" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_cavalry" : "units/mace_cavalry_spearman_b", Index: binaries/data/mods/public/simulation/data/civs/maur.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/maur.json +++ binaries/data/mods/public/simulation/data/civs/maur.json @@ -154,6 +154,17 @@ "Satadhanvan Maurya", "Brihadratha Maurya" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_ranged_b": "units/maur_infantry_archer_b", Index: binaries/data/mods/public/simulation/data/civs/pers.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/pers.json +++ binaries/data/mods/public/simulation/data/civs/pers.json @@ -161,6 +161,17 @@ "Haxamanish", "Xsayarsa II" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_ranged_b": "units/pers_infantry_archer_b", Index: binaries/data/mods/public/simulation/data/civs/ptol.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/ptol.json +++ binaries/data/mods/public/simulation/data/civs/ptol.json @@ -178,6 +178,17 @@ "Arsinoe IV", "Arsinoe II" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_infantry_melee_b": "units/ptol_infantry_pikeman_b", Index: binaries/data/mods/public/simulation/data/civs/rome.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/rome.json +++ binaries/data/mods/public/simulation/data/civs/rome.json @@ -149,6 +149,17 @@ "Quintus Caecilius Metellus Pius", "Marcus Licinius Crassus" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/units/default_cavalry" : "units/rome_cavalry_spearman_b", Index: binaries/data/mods/public/simulation/data/civs/sele.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/sele.json +++ binaries/data/mods/public/simulation/data/civs/sele.json @@ -188,6 +188,17 @@ "Antiochus XIII Asiaticus", "Philip II Philoromaeus" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/structures/default_house_10" : "structures/{civ}_house" Index: binaries/data/mods/public/simulation/data/civs/spart.json =================================================================== --- binaries/data/mods/public/simulation/data/civs/spart.json +++ binaries/data/mods/public/simulation/data/civs/spart.json @@ -161,6 +161,17 @@ "Eucleidas", "Agesipolis" ], + "AINameNumbers": + [ + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII" + ], "SkirmishReplacements": { "skirmish/structures/default_house_10" : "structures/{civ}_house",