Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/Ceasefire.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/Ceasefire.js (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/Ceasefire.js (nonexistent) @@ -1,55 +0,0 @@ -GameSettingControls.Ceasefire = class extends GameSettingControlDropdown -{ - constructor(...args) - { - super(...args); - - this.values = prepareForDropdown(g_Settings.Ceasefire); - - this.dropdown.list = this.values.Title; - this.dropdown.list_data = this.values.Duration; - } - - onMapChange(mapData) - { - let mapValue = - mapData && - mapData.settings && - mapData.settings.Ceasefire || undefined; - - if (mapValue !== undefined && mapValue != g_GameAttributes.settings.Ceasefire) - { - g_GameAttributes.settings.Ceasefire = mapValue; - this.gameSettingsControl.updateGameAttributes(); - } - - this.setEnabled(g_GameAttributes.mapType != "scenario"); - } - - onGameAttributesChange() - { - if (g_GameAttributes.settings.Ceasefire == undefined) - { - g_GameAttributes.settings.Ceasefire = this.values.Default; - this.gameSettingsControl.updateGameAttributes(); - } - } - - onGameAttributesBatchChange() - { - this.setSelectedValue(g_GameAttributes.settings.Ceasefire); - } - - onSelectionChange(itemIdx) - { - g_GameAttributes.settings.Ceasefire = this.values.Duration[itemIdx]; - this.gameSettingsControl.updateGameAttributes(); - this.gameSettingsControl.setNetworkGameAttributes(); - } -}; - -GameSettingControls.Ceasefire.prototype.TitleCaption = - translate("Ceasefire"); - -GameSettingControls.Ceasefire.prototype.Tooltip = - translate("Set time where no attacks are possible."); Property changes on: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/Ceasefire.js ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/WonderDuration.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/WonderDuration.js (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/WonderDuration.js (nonexistent) @@ -1,85 +0,0 @@ -GameSettingControls.WonderDuration = class extends GameSettingControlDropdown -{ - constructor(...args) - { - super(...args); - - this.values = prepareForDropdown(g_Settings.VictoryDurations); - - this.dropdown.list = this.values.Title; - this.dropdown.list_data = this.values.Duration; - - this.available = false; - } - - onMapChange(mapData) - { - this.setEnabled(g_GameAttributes.mapType != "scenario"); - - let mapValue = - mapData && - mapData.settings && - mapData.settings.VictoryConditions && - mapData.settings.VictoryConditions.indexOf(this.NameWonderVictory) != -1 && - mapData.settings.WonderDuration || undefined; - - if (mapValue === undefined || mapValue == g_GameAttributes.settings.WonderDuration) - return; - - if (!g_GameAttributes.settings.VictoryConditions) - g_GameAttributes.settings.VictoryConditions = []; - - if (g_GameAttributes.settings.VictoryConditions.indexOf(this.NameWonderVictory) == -1) - g_GameAttributes.settings.VictoryConditions.push(this.NameWonderVictory); - - g_GameAttributes.settings.WonderDuration = mapValue; - - this.gameSettingsControl.updateGameAttributes(); - } - - onGameAttributesChange() - { - if (!g_GameAttributes.settings.VictoryConditions) - return; - - this.available = g_GameAttributes.settings.VictoryConditions.indexOf(this.NameWonderVictory) != -1; - - if (this.available) - { - if (g_GameAttributes.settings.WonderDuration === undefined) - { - g_GameAttributes.settings.WonderDuration = this.values.Duration[this.values.Default]; - this.gameSettingsControl.updateGameAttributes(); - } - } - else if (g_GameAttributes.settings.WonderDuration !== undefined) - { - delete g_GameAttributes.settings.WonderDuration; - this.gameSettingsControl.updateGameAttributes(); - } - } - - onGameAttributesBatchChange() - { - this.setHidden(!this.available); - - if (this.available) - this.setSelectedValue(g_GameAttributes.settings.WonderDuration); - } - - onSelectionChange(itemIdx) - { - g_GameAttributes.settings.WonderDuration = this.values.Duration[itemIdx]; - this.gameSettingsControl.updateGameAttributes(); - this.gameSettingsControl.setNetworkGameAttributes(); - } -}; - -GameSettingControls.WonderDuration.prototype.TitleCaption = - translate("Wonder Duration"); - -GameSettingControls.WonderDuration.prototype.Tooltip = - translate("Minutes until the player has achieved Wonder Victory"); - -GameSettingControls.WonderDuration.prototype.NameWonderVictory = - "wonder"; Property changes on: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/WonderDuration.js ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicCount.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicCount.js (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicCount.js (nonexistent) @@ -1,86 +0,0 @@ -GameSettingControls.RelicCount = class extends GameSettingControlDropdown -{ - constructor(...args) - { - super(...args); - - this.values = Object.keys(g_CivData).map((v, i) => i + 1); - - this.dropdown.list = this.values; - this.dropdown.list_data = this.values; - - this.available = false; - } - - onMapChange(mapData) - { - this.setEnabled(g_GameAttributes.mapType != "scenario"); - - let mapValue = - mapData && - mapData.settings && - mapData.settings.VictoryConditions && - mapData.settings.VictoryConditions.indexOf(this.NameCaptureTheRelic) != -1 && - mapData.settings.RelicCount || undefined; - - if (mapValue === undefined || mapValue == g_GameAttributes.settings.RelicCount) - return; - - if (!g_GameAttributes.settings.VictoryConditions) - g_GameAttributes.settings.VictoryConditions = []; - - if (g_GameAttributes.settings.VictoryConditions.indexOf(this.NameCaptureTheRelic) == -1) - g_GameAttributes.settings.VictoryConditions.push(this.NameCaptureTheRelic); - - g_GameAttributes.settings.RelicCount = mapValue; - this.gameSettingsControl.updateGameAttributes(); - } - - onGameAttributesChange() - { - if (!g_GameAttributes.settings.VictoryConditions) - return; - - this.available = g_GameAttributes.settings.VictoryConditions.indexOf(this.NameCaptureTheRelic) != -1; - - if (this.available) - { - if (g_GameAttributes.settings.RelicCount === undefined) - { - g_GameAttributes.settings.RelicCount = this.DefaultRelicCount; - this.gameSettingsControl.updateGameAttributes(); - } - } - else if (g_GameAttributes.settings.RelicCount !== undefined) - { - delete g_GameAttributes.settings.RelicCount; - this.gameSettingsControl.updateGameAttributes(); - } - } - - onGameAttributesBatchChange() - { - this.setHidden(!this.available); - - if (this.available) - this.setSelectedValue(g_GameAttributes.settings.RelicCount); - } - - onSelectionChange(itemIdx) - { - g_GameAttributes.settings.RelicCount = this.values[itemIdx]; - this.gameSettingsControl.updateGameAttributes(); - this.gameSettingsControl.setNetworkGameAttributes(); - } -}; - -GameSettingControls.RelicCount.prototype.TitleCaption = - translate("Relic Count"); - -GameSettingControls.RelicCount.prototype.Tooltip = - translate("Total number of relics spawned on the map. Relic victory is most realistic with only one or two relics. With greater numbers, the relics are important to capture to receive aura bonuses."); - -GameSettingControls.RelicCount.prototype.NameCaptureTheRelic = - "capture_the_relic"; - -GameSettingControls.RelicCount.prototype.DefaultRelicCount = 2; Property changes on: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicCount.js ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicDuration.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicDuration.js (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicDuration.js (nonexistent) @@ -1,85 +0,0 @@ -GameSettingControls.RelicDuration = class extends GameSettingControlDropdown -{ - constructor(...args) - { - super(...args); - - this.values = prepareForDropdown(g_Settings.VictoryDurations); - - this.dropdown.list = this.values.Title; - this.dropdown.list_data = this.values.Duration; - - this.available = false; - } - - onMapChange(mapData) - { - this.setEnabled(g_GameAttributes.mapType != "scenario"); - - let mapValue = - mapData && - mapData.settings && - mapData.settings.VictoryConditions && - mapData.settings.VictoryConditions.indexOf(this.NameCaptureTheRelic) != -1 && - mapData.settings.RelicDuration || undefined; - - if (mapValue === undefined || mapValue == g_GameAttributes.settings.RelicDuration) - return; - - if (!g_GameAttributes.settings.VictoryConditions) - g_GameAttributes.settings.VictoryConditions = []; - - if (g_GameAttributes.settings.VictoryConditions.indexOf(this.NameCaptureTheRelic) == -1) - g_GameAttributes.settings.VictoryConditions.push(this.NameCaptureTheRelic); - - g_GameAttributes.settings.RelicDuration = mapValue; - - this.gameSettingsControl.updateGameAttributes(); - } - - onGameAttributesChange() - { - if (!g_GameAttributes.settings.VictoryConditions) - return; - - this.available = g_GameAttributes.settings.VictoryConditions.indexOf(this.NameCaptureTheRelic) != -1; - - if (this.available) - { - if (g_GameAttributes.settings.RelicDuration === undefined) - { - g_GameAttributes.settings.RelicDuration = this.values.Duration[this.values.Default]; - this.gameSettingsControl.updateGameAttributes(); - } - } - else if (g_GameAttributes.settings.RelicDuration !== undefined) - { - delete g_GameAttributes.settings.RelicDuration; - this.gameSettingsControl.updateGameAttributes(); - } - } - - onGameAttributesBatchChange() - { - this.setHidden(!this.available); - - if (this.available) - this.setSelectedValue(g_GameAttributes.settings.RelicDuration); - } - - onSelectionChange(itemIdx) - { - g_GameAttributes.settings.RelicDuration = this.values.Duration[itemIdx]; - this.gameSettingsControl.updateGameAttributes(); - this.gameSettingsControl.setNetworkGameAttributes(); - } -}; - -GameSettingControls.RelicDuration.prototype.TitleCaption = - translate("Relic Duration"); - -GameSettingControls.RelicDuration.prototype.Tooltip = - translate("Minutes until the player has achieved Relic Victory."); - -GameSettingControls.RelicDuration.prototype.NameCaptureTheRelic = - "capture_the_relic"; Property changes on: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/Single/Dropdowns/RelicDuration.js ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/simulation/data/settings/victory_times.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/settings/victory_times.json (revision 23429) +++ ps/trunk/binaries/data/mods/public/simulation/data/settings/victory_times.json (nonexistent) @@ -1,4 +0,0 @@ -{ - "Times": [0, 1, 3, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 75, 90, 105, 120], - "Default": 20 -} Property changes on: ps/trunk/binaries/data/mods/public/simulation/data/settings/victory_times.json ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/simulation/data/settings/ceasefire.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/settings/ceasefire.json (revision 23429) +++ ps/trunk/binaries/data/mods/public/simulation/data/settings/ceasefire.json (nonexistent) @@ -1,4 +0,0 @@ -{ - "Times": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 45, 60], - "Default": 0 -} Property changes on: ps/trunk/binaries/data/mods/public/simulation/data/settings/ceasefire.json ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/gui/common/gamedescription.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/common/gamedescription.js (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/common/gamedescription.js (revision 23430) @@ -1,432 +1,437 @@ /** * Highlights the victory condition in the game-description. */ var g_DescriptionHighlight = "orange"; /** * The rating assigned to lobby players who didn't complete a ranked 1v1 yet. */ var g_DefaultLobbyRating = 1200; /** * XEP-0172 doesn't restrict nicknames, but our lobby policy does. * So use this human readable delimiter to separate buddy names in the config file. */ var g_BuddyListDelimiter = ","; /** * Returns the nickname without the lobby rating. */ function splitRatingFromNick(playerName) { let result = /^(\S+)\ \((\d+)\)$/g.exec(playerName); return { "nick": result ? result[1] : playerName, "rating": result ? +result[2] : "" }; } /** * Array of playernames that the current user has marked as buddies. */ var g_Buddies = Engine.ConfigDB_GetValue("user", "lobby.buddies").split(g_BuddyListDelimiter); /** * Denotes which players are a lobby buddy of the current user. */ var g_BuddySymbol = '•'; /** * Returns a formatted string describing the player assignments. * Needs g_CivData to translate! * * @param {object} playerDataArray - As known from gamesetup and simstate. * @param {(string[]|false)} playerStates - One of "won", "defeated", "active" for each player. * @returns {string} */ function formatPlayerInfo(playerDataArray, playerStates) { let playerDescriptions = {}; let playerIdx = 0; for (let playerData of playerDataArray) { if (playerData == null || playerData.Civ && playerData.Civ == "gaia") continue; ++playerIdx; let teamIdx = playerData.Team; let isAI = playerData.AI && playerData.AI != ""; let playerState = playerStates && playerStates[playerIdx] || playerData.State; let isActive = !playerState || playerState == "active"; let playerDescription; if (isAI) { if (playerData.Civ) { if (isActive) // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(civ)s, %(AIdescription)s)"); else // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(civ)s, %(AIdescription)s, %(state)s)"); } else { if (isActive) // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(AIdescription)s)"); else // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(AIdescription)s, %(state)s)"); } } else { if (playerData.Offline) { // Can only occur in the lobby for now, so no strings with civ needed if (isActive) // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (OFFLINE)"); else // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (OFFLINE, %(state)s)"); } else { if (playerData.Civ) if (isActive) // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(civ)s)"); else // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(civ)s, %(state)s)"); else if (isActive) // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s"); else // Translation: Describe a player in a selected game, f.e. in the replay- or savegame menu playerDescription = translate("%(playerName)s (%(state)s)"); } } // Sort player descriptions by team if (!playerDescriptions[teamIdx]) playerDescriptions[teamIdx] = []; let playerNick = splitRatingFromNick(playerData.Name).nick; playerDescriptions[teamIdx].push(sprintf(playerDescription, { "playerName": coloredText( (g_Buddies.indexOf(playerNick) != -1 ? g_BuddySymbol + " " : "") + escapeText(playerData.Name), (typeof getPlayerColor == 'function' ? (isAI ? "white" : getPlayerColor(playerNick)) : rgbToGuiColor(playerData.Color || g_Settings.PlayerDefaults[playerIdx].Color))), "civ": !playerData.Civ ? translate("Unknown Civilization") : g_CivData && g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? translate(g_CivData[playerData.Civ].Name) : playerData.Civ, "state": playerState == "defeated" ? translateWithContext("playerstate", "defeated") : translateWithContext("playerstate", "won"), "AIdescription": translateAISettings(playerData) })); } let teams = Object.keys(playerDescriptions); if (teams.indexOf("observer") > -1) teams.splice(teams.indexOf("observer"), 1); let teamDescription = []; // If there are no teams, merge all playersDescriptions if (teams.length == 1) teamDescription.push(playerDescriptions[teams[0]].join("\n")); // If there are teams, merge "Team N:" + playerDescriptions else teamDescription = teams.map(team => { let teamCaption = team == -1 ? translate("No Team") : sprintf(translate("Team %(team)s"), { "team": +team + 1 }); // Translation: Describe players of one team in a selected game, f.e. in the replay- or savegame menu or lobby return sprintf(translate("%(team)s:\n%(playerDescriptions)s"), { "team": '[font="sans-bold-14"]' + teamCaption + "[/font]", "playerDescriptions": playerDescriptions[team].join("\n") }); }); if (playerDescriptions.observer) teamDescription.push(sprintf(translate("%(team)s:\n%(playerDescriptions)s"), { "team": '[font="sans-bold-14"]' + translatePlural("Observer", "Observers", playerDescriptions.observer.length) + "[/font]", "playerDescriptions": playerDescriptions.observer.join("\n") })); return teamDescription.join("\n\n"); } /** * Sets an additional map label, map preview image and describes the chosen gamesettings more closely. * * Requires g_GameAttributes and g_VictoryConditions. */ function getGameDescription(mapCache) { let titles = []; if (!g_GameAttributes.settings.VictoryConditions.length) titles.push({ "label": translateWithContext("victory condition", "Endless Game"), "value": translate("No winner will be determined, even if everyone is defeated.") }); for (let victoryCondition of g_VictoryConditions) { if (g_GameAttributes.settings.VictoryConditions.indexOf(victoryCondition.Name) == -1) continue; let title = translateVictoryCondition(victoryCondition.Name); if (victoryCondition.Name == "wonder") + { + let wonderDuration = Math.round(g_GameAttributes.settings.WonderDuration); title = sprintf( translatePluralWithContext( "victory condition", "Wonder (%(min)s minute)", "Wonder (%(min)s minutes)", - g_GameAttributes.settings.WonderDuration + wonderDuration ), - { "min": g_GameAttributes.settings.WonderDuration } - ); + { "min": wonderDuration }); + } let isCaptureTheRelic = victoryCondition.Name == "capture_the_relic"; if (isCaptureTheRelic) + { + let relicDuration = Math.round(g_GameAttributes.settings.RelicDuration); title = sprintf( translatePluralWithContext( "victory condition", "Capture the Relic (%(min)s minute)", "Capture the Relic (%(min)s minutes)", - g_GameAttributes.settings.RelicDuration + relicDuration ), - { "min": g_GameAttributes.settings.RelicDuration } - ); + { "min": relicDuration }); + } titles.push({ "label": title, "value": victoryCondition.Description }); if (isCaptureTheRelic) titles.push({ "label": translate("Relic Count"), - "value": g_GameAttributes.settings.RelicCount + "value": Math.round(g_GameAttributes.settings.RelicCount) }); if (victoryCondition.Name == "regicide") if (g_GameAttributes.settings.RegicideGarrison) titles.push({ "label": translate("Hero Garrison"), "value": translate("Heroes can be garrisoned.") }); else titles.push({ "label": translate("Exposed Heroes"), "value": translate("Heroes cannot be garrisoned and they are vulnerable to raids.") }); } if (g_GameAttributes.settings.RatingEnabled && g_GameAttributes.settings.PlayerData.length == 2) titles.push({ "label": translate("Rated game"), "value": translate("When the winner of this match is determined, the lobby score will be adapted.") }); if (g_GameAttributes.settings.LockTeams) titles.push({ "label": translate("Locked Teams"), "value": translate("Players can't change the initial teams.") }); else titles.push({ "label": translate("Diplomacy"), "value": translate("Players can make alliances and declare war on allies.") }); if (g_GameAttributes.settings.LastManStanding) titles.push({ "label": translate("Last Man Standing"), "value": translate("Only one player can win the game. If the remaining players are allies, the game continues until only one remains.") }); else titles.push({ "label": translate("Allied Victory"), "value": translate("If one player wins, his or her allies win too. If one group of allies remains, they win.") }); + let ceasefire = Math.round(g_GameAttributes.settings.Ceasefire); titles.push({ "label": translate("Ceasefire"), "value": - g_GameAttributes.settings.Ceasefire == 0 ? + ceasefire == 0 ? translate("disabled") : sprintf(translatePlural( "For the first minute, other players will stay neutral.", "For the first %(min)s minutes, other players will stay neutral.", - g_GameAttributes.settings.Ceasefire), - { "min": g_GameAttributes.settings.Ceasefire }) + ceasefire), + { "min": ceasefire }) }); if (g_GameAttributes.map == "random") titles.push({ "label": translateWithContext("Map Selection", "Random Map"), "value": translate("Randomly select a map from the list.") }); else { titles.push({ "label": translate("Map Name"), "value": mapCache.translateMapName( mapCache.getTranslatableMapName(g_GameAttributes.mapType, g_GameAttributes.map, g_GameAttributes)) }); titles.push({ "label": translate("Map Description"), "value": mapCache.getTranslatedMapDescription(g_GameAttributes.mapType, g_GameAttributes.map) }); } titles.push({ "label": translate("Map Type"), "value": g_MapTypes.Title[g_MapTypes.Name.indexOf(g_GameAttributes.mapType)] }); if (g_GameAttributes.mapType == "random") { let mapSize = g_MapSizes.Name[g_MapSizes.Tiles.indexOf(g_GameAttributes.settings.Size)]; if (mapSize) titles.push({ "label": translate("Map Size"), "value": mapSize }); } if (g_GameAttributes.settings.Biome) { let biome = g_Settings.Biomes.find(b => b.Id == g_GameAttributes.settings.Biome); titles.push({ "label": biome ? biome.Title : translateWithContext("biome", "Random Biome"), "value": biome ? biome.Description : translate("Randomly select a biome from the list.") }); } if (g_GameAttributes.settings.TriggerDifficulty !== undefined) { let triggerDifficulty = g_Settings.TriggerDifficulties.find(difficulty => difficulty.Difficulty == g_GameAttributes.settings.TriggerDifficulty); titles.push({ "label": triggerDifficulty.Title, "value": triggerDifficulty.Tooltip }); } if (g_GameAttributes.settings.Nomad !== undefined) titles.push({ "label": g_GameAttributes.settings.Nomad ? translate("Nomad Mode") : translate("Civic Centers"), "value": g_GameAttributes.settings.Nomad ? translate("Players start with only few units and have to find a suitable place to build their city.") : translate("Players start with a Civic Center.") }); if (g_GameAttributes.settings.StartingResources !== undefined) titles.push({ "label": translate("Starting Resources"), "value": g_GameAttributes.settings.PlayerData && g_GameAttributes.settings.PlayerData.some(pData => pData && pData.Resources !== undefined) ? translateWithContext("starting resources", "Per Player") : sprintf(translate("%(startingResourcesTitle)s (%(amount)s)"), { "startingResourcesTitle": g_StartingResources.Title[ g_StartingResources.Resources.indexOf( g_GameAttributes.settings.StartingResources)], "amount": g_GameAttributes.settings.StartingResources }) }); if (g_GameAttributes.settings.PopulationCap !== undefined) titles.push({ "label": translate("Population Limit"), "value": g_GameAttributes.settings.PlayerData && g_GameAttributes.settings.PlayerData.some(pData => pData && pData.PopulationLimit !== undefined) ? translateWithContext("population limit", "Per Player") : g_PopulationCapacities.Title[ g_PopulationCapacities.Population.indexOf( g_GameAttributes.settings.PopulationCap)] }); titles.push({ "label": translate("Treasures"), "value": g_GameAttributes.settings.DisableTreasures ? translateWithContext("treasures", "Disabled") : translateWithContext("treasures", "As defined by the map.") }); titles.push({ "label": translate("Revealed Map"), "value": g_GameAttributes.settings.RevealMap }); titles.push({ "label": translate("Explored Map"), "value": g_GameAttributes.settings.ExploreMap }); titles.push({ "label": translate("Cheats"), "value": g_GameAttributes.settings.CheatsEnabled }); return titles.map(title => sprintf(translate("%(label)s %(details)s"), { "label": coloredText(title.label, g_DescriptionHighlight), "details": title.value === true ? translateWithContext("gamesetup option", "enabled") : title.value || translateWithContext("gamesetup option", "disabled") })).join("\n"); } /** * Sets the win/defeat icon to indicate current player's state. */ function setOutcomeIcon(state, image) { if (state == "won") { image.sprite = "stretched:session/icons/victory.png"; image.tooltip = translate("Victorious"); } else if (state == "defeated") { image.sprite = "stretched:session/icons/defeat.png"; image.tooltip = translate("Defeated"); } } function translateAISettings(playerData) { if (!playerData.AI) return ""; return sprintf(translate("%(AIdifficulty)s %(AIbehavior)s %(AIname)s"), { "AIname": translateAIName(playerData.AI), "AIdifficulty": translateAIDifficulty(playerData.AIDiff), "AIbehavior": translateAIBehavior(playerData.AIBehavior), }); } Index: ps/trunk/binaries/data/mods/public/gui/common/settings.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/common/settings.js (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/common/settings.js (revision 23430) @@ -1,432 +1,386 @@ /** * The maximum number of players that the engine supports. * TODO: Maybe we can support more than 8 players sometime. */ const g_MaxPlayers = 8; /** * The maximum number of teams allowed. */ const g_MaxTeams = 4; /** * Directory containing all editable settings. */ const g_SettingsDirectory = "simulation/data/settings/"; /** * Directory containing all biomes supported for random map scripts. */ const g_BiomesDirectory = "maps/random/rmbiome/"; /** * An object containing all values given by setting name. * Used by lobby, gamesetup, session, summary screen and replay menu. */ const g_Settings = loadSettingsValues(); /** * Loads and translates all values of all settings which * can be configured by dropdowns in the gamesetup. * * @returns {Object|undefined} */ function loadSettingsValues() { var settings = { "AIDescriptions": loadAIDescriptions(), "AIDifficulties": loadAIDifficulties(), "AIBehaviors": loadAIBehaviors(), - "Ceasefire": loadCeasefire(), - "VictoryDurations": loadVictoryDuration(), "GameSpeeds": loadSettingValuesFile("game_speeds.json"), "MapTypes": loadMapTypes(), "MapSizes": loadSettingValuesFile("map_sizes.json"), "Biomes": loadBiomes(), "PlayerDefaults": loadPlayerDefaults(), "PopulationCapacities": loadPopulationCapacities(), "StartingResources": loadSettingValuesFile("starting_resources.json"), "VictoryConditions": loadVictoryConditions(), "TriggerDifficulties": loadSettingValuesFile("trigger_difficulties.json") }; if (Object.keys(settings).some(key => settings[key] === undefined)) return undefined; return deepfreeze(settings); } /** * Returns an array of objects reflecting all possible values for a given setting. * * @param {string} filename * @see simulation/data/settings/ * @returns {Array|undefined} */ function loadSettingValuesFile(filename) { var json = Engine.ReadJSONFile(g_SettingsDirectory + filename); if (!json || !json.Data) { error("Could not load " + filename + "!"); return undefined; } if (json.TranslatedKeys) { let keyContext = json.TranslatedKeys; if (json.TranslationContext) { keyContext = {}; for (let key of json.TranslatedKeys) keyContext[key] = json.TranslationContext; } translateObjectKeys(json.Data, keyContext); } return json.Data; } /** * Loads the descriptions as defined in simulation/ai/.../data.json and loaded by ICmpAIManager.cpp. * * @returns {Array} */ function loadAIDescriptions() { var ais = Engine.GetAIs(); translateObjectKeys(ais, ["name", "description"]); return ais.sort((a, b) => a.data.name.localeCompare(b.data.name)); } /** * Hardcoded, as modding is not supported without major changes. * Notice the AI code parses the difficulty level by the index, not by name. * * @returns {Array} */ function loadAIDifficulties() { return [ { "Name": "sandbox", "Title": translateWithContext("aiDiff", "Sandbox") }, { "Name": "very easy", "Title": translateWithContext("aiDiff", "Very Easy") }, { "Name": "easy", "Title": translateWithContext("aiDiff", "Easy") }, { "Name": "medium", "Title": translateWithContext("aiDiff", "Medium"), "Default": true }, { "Name": "hard", "Title": translateWithContext("aiDiff", "Hard") }, { "Name": "very hard", "Title": translateWithContext("aiDiff", "Very Hard") } ]; } function loadAIBehaviors() { return [ { "Name": "random", "Title": translateWithContext("aiBehavior", "Random"), "Default": true }, { "Name": "balanced", "Title": translateWithContext("aiBehavior", "Balanced"), }, { "Name": "defensive", "Title": translateWithContext("aiBehavior", "Defensive") }, { "Name": "aggressive", "Title": translateWithContext("aiBehavior", "Aggressive") } ]; } /** - * Loads available victory times for victory conditions like Wonder and Capture the Relic. - */ -function loadVictoryDuration() -{ - var jsonFile = "victory_times.json"; - var json = Engine.ReadJSONFile(g_SettingsDirectory + jsonFile); - - if (!json || json.Default === undefined || !json.Times || !Array.isArray(json.Times)) - { - error("Could not load " + jsonFile); - return undefined; - } - - return json.Times.map(duration => ({ - "Duration": duration, - "Default": duration == json.Default, - "Title": sprintf(translatePluralWithContext("victory duration", "%(min)s minute", "%(min)s minutes", duration), { "min": duration }) - })); -} - -/** - * Loads available ceasefire settings. - * - * @returns {Array|undefined} - */ -function loadCeasefire() -{ - var json = Engine.ReadJSONFile(g_SettingsDirectory + "ceasefire.json"); - - if (!json || json.Default === undefined || !json.Times || !Array.isArray(json.Times)) - { - error("Could not load ceasefire.json"); - return undefined; - } - - return json.Times.map(timeout => ({ - "Duration": timeout, - "Default": timeout == json.Default, - "Title": timeout == 0 ? translateWithContext("ceasefire", "No ceasefire") : - sprintf(translatePluralWithContext("ceasefire", "%(minutes)s minute", "%(minutes)s minutes", timeout), { "minutes": timeout }) - })); -} - -/** * Hardcoded, as modding is not supported without major changes. */ function loadMapTypes() { return [ { "Name": "skirmish", "Title": translateWithContext("map", "Skirmish"), "Description": translate("A map with a predefined landscape and number of players. Freely select the other gamesettings."), "Default": true, "Path": "maps/skirmishes/", "Suffix": ".xml", "GetData": Engine.LoadMapSettings }, { "Name": "random", "Title": translateWithContext("map", "Random"), "Description": translate("Create a unique map with a different resource distribution each time. Freely select the number of players and teams."), "Path": "maps/random/", "Suffix": ".json", "GetData": mapPath => Engine.ReadJSONFile(mapPath + ".json") }, { "Name": "scenario", "Title": translateWithContext("map", "Scenario"), "Description": translate("A map with a predefined landscape and matchsettings."), "Path": "maps/scenarios/", "Suffix": ".xml", "GetData": Engine.LoadMapSettings } ]; } function loadBiomes() { return listFiles(g_BiomesDirectory, ".json", true).filter(biomeID => biomeID != "defaultbiome").map(biomeID => { let description = Engine.ReadJSONFile(g_BiomesDirectory + biomeID + ".json").Description; return { "Id": biomeID, "Title": translateWithContext("biome definition", description.Title), "Description": description.Description ? translateWithContext("biome definition", description.Description) : "", "Preview": description.Preview || undefined }; }); } /** * Loads available victoryCondtions from json files. * * @returns {Array|undefined} */ function loadVictoryConditions() { let subdir = "victory_conditions/"; let victoryConditions = listFiles(g_SettingsDirectory + subdir, ".json", false).map(victoryScriptName => { let victoryCondition = loadSettingValuesFile(subdir + victoryScriptName + ".json"); if (victoryCondition) victoryCondition.Name = victoryScriptName; return victoryCondition; }); if (victoryConditions.some(victoryCondition => victoryCondition == undefined)) return undefined; return victoryConditions.sort((a, b) => a.GUIOrder - b.GUIOrder || (a.Title > b.Title ? 1 : a.Title > b.Title ? -1 : 0)); } /** * Loads the default player settings (like civs and colors). * * @returns {Array|undefined} */ function loadPlayerDefaults() { var json = Engine.ReadJSONFile(g_SettingsDirectory + "player_defaults.json"); if (!json || !json.PlayerData) { error("Could not load player_defaults.json"); return undefined; } return json.PlayerData; } /** * Loads available population capacities. * * @returns {Array|undefined} */ function loadPopulationCapacities() { var json = Engine.ReadJSONFile(g_SettingsDirectory + "population_capacities.json"); if (!json || json.Default === undefined || !json.PopulationCapacities || !Array.isArray(json.PopulationCapacities)) { error("Could not load population_capacities.json"); return undefined; } return json.PopulationCapacities.map(population => ({ "Population": population, "Default": population == json.Default, "Title": population < 10000 ? population : translate("Unlimited") })); } /** * Creates an object with all values of that property of the given setting and * finds the index of the default value. * * This allows easy copying of setting values to dropdown lists. * * @param {Array} settingValues * @returns {Object|undefined} */ function prepareForDropdown(settingValues) { if (!settingValues) return undefined; let settings = { "Default": 0 }; for (let index in settingValues) { for (let property in settingValues[index]) { if (property == "Default") continue; if (!settings[property]) settings[property] = []; // Switch property and index settings[property][index] = settingValues[index][property]; } // Copy default value if (settingValues[index].Default) settings.Default = +index; } return deepfreeze(settings); } /** * Returns title or placeholder. * * @param {string} aiName - for example "petra" */ function translateAIName(aiName) { let description = g_Settings.AIDescriptions.find(ai => ai.id == aiName); return description ? translate(description.data.name) : translateWithContext("AI name", "Unknown"); } /** * Returns title or placeholder. * * @param {Number} index - index of AIDifficulties */ function translateAIDifficulty(index) { let difficulty = g_Settings.AIDifficulties[index]; return difficulty ? difficulty.Title : translateWithContext("AI difficulty", "Unknown"); } /** * Returns title or placeholder. * * @param {string} aiBehavior - for example "defensive" */ function translateAIBehavior(aiBehavior) { let behavior = g_Settings.AIBehaviors.find(b => b.Name == aiBehavior); return behavior ? behavior.Title : translateWithContext("AI behavior", "Default"); } /** * Returns title or placeholder. * * @param {string} mapType - for example "skirmish" * @returns {string} */ function translateMapType(mapType) { let type = g_Settings.MapTypes.find(t => t.Name == mapType); return type ? type.Title : translateWithContext("map type", "Unknown"); } /** * Returns title or placeholder "Default". * * @param {Number} mapSize - tilecount * @returns {string} */ function translateMapSize(tiles) { let mapSize = g_Settings.MapSizes.find(size => size.Tiles == +tiles); return mapSize ? mapSize.Name : translateWithContext("map size", "Default"); } /** * Returns title or placeholder. * * @param {Number} population - for example 300 * @returns {string} */ function translatePopulationCapacity(population) { let popCap = g_Settings.PopulationCapacities.find(p => p.Population == population); return popCap ? popCap.Title : translateWithContext("population capacity", "Unknown"); } /** * Returns title or placeholder. * * @param {string} victoryConditionName - For example "conquest". * @returns {string} */ function translateVictoryCondition(victoryConditionName) { let victoryCondition = g_Settings.VictoryConditions.find(condition => condition.Name == victoryConditionName); return victoryCondition ? victoryCondition.Title : translate("Unknown Victory Condition"); } Index: ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingControlDropdown.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingControlDropdown.xml (revision 23429) +++ ps/trunk/binaries/data/mods/public/gui/gamesetup/Pages/GameSetupPage/GameSettings/GameSettingControlDropdown.xml (revision 23430) @@ -1,14 +1,14 @@