Index: binaries/data/mods/public/gui/common/gamedescription.js =================================================================== --- binaries/data/mods/public/gui/common/gamedescription.js +++ binaries/data/mods/public/gui/common/gamedescription.js @@ -216,56 +216,58 @@ function getGameDescription(extended = false) { let titles = []; - - let victoryIdx = g_VictoryConditions.Name.indexOf(g_GameAttributes.settings.GameType || g_VictoryConditions.Default); - if (victoryIdx != -1) + for (let vc of clone(g_GameAttributes.settings.VictoryConditions).sort((a, b) => a > b ? 1 : a < b ? -1 : 0)) { - let title = g_VictoryConditions.Title[victoryIdx]; - if (g_VictoryConditions.Name[victoryIdx] == "wonder") - title = sprintf( - translatePluralWithContext( - "victory condition", - "Wonder (%(min)s minute)", - "Wonder (%(min)s minutes)", - g_GameAttributes.settings.WonderDuration - ), - { "min": g_GameAttributes.settings.WonderDuration } - ); - - let isCaptureTheRelic = g_VictoryConditions.Name[victoryIdx] == "capture_the_relic"; - if (isCaptureTheRelic) - title = sprintf( - translatePluralWithContext( - "victory condition", - "Capture the Relic (%(min)s minute)", - "Capture the Relic (%(min)s minutes)", - g_GameAttributes.settings.RelicDuration - ), - { "min": g_GameAttributes.settings.RelicDuration } - ); - - titles.push({ - "label": title, - "value": g_VictoryConditions.Description[victoryIdx] - }); + let victoryIdx = g_VictoryConditions.map(data => data.Name).indexOf(vc); + if (victoryIdx != -1) + { + let title = g_VictoryConditions[victoryIdx].Title; + if (vc == "wonder") + title = sprintf( + translatePluralWithContext( + "victory condition", + "Wonder (%(min)s minute)", + "Wonder (%(min)s minutes)", + g_GameAttributes.settings.WonderDuration + ), + { "min": g_GameAttributes.settings.WonderDuration } + ); + + let isCaptureTheRelic = vc == "capture_the_relic"; + if (isCaptureTheRelic) + title = sprintf( + translatePluralWithContext( + "victory condition", + "Capture the Relic (%(min)s minute)", + "Capture the Relic (%(min)s minutes)", + g_GameAttributes.settings.RelicDuration + ), + { "min": g_GameAttributes.settings.RelicDuration } + ); - if (isCaptureTheRelic) titles.push({ - "label": translate("Relic Count"), - "value": g_GameAttributes.settings.RelicCount + "label": title, + "value": g_VictoryConditions[victoryIdx].Description }); - if (g_VictoryConditions.Name[victoryIdx] == "regicide") - if (g_GameAttributes.settings.RegicideGarrison) + if (isCaptureTheRelic) 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.") + "label": translate("Relic Count"), + "value": g_GameAttributes.settings.RelicCount }); + + if (vc == "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 && Index: binaries/data/mods/public/gui/common/settings.js =================================================================== --- binaries/data/mods/public/gui/common/settings.js +++ binaries/data/mods/public/gui/common/settings.js @@ -247,7 +247,7 @@ } /** - * Loads available gametypes. + * Loads available victoryCondtions from json files. * * @returns {Array|undefined} */ @@ -428,11 +428,11 @@ /** * Returns title or placeholder. * - * @param {string} gameType - for example "conquest" + * @param {string} victoryCondition - for example "conquest" * @returns {string} */ -function translateVictoryCondition(gameType) +function translateVictoryCondition(victoryCondition) { - let victoryCondition = g_Settings.VictoryConditions.find(vc => vc.Name == gameType); - return victoryCondition ? victoryCondition.Title : translateWithContext("victory condition", "Unknown"); + let victoryConditionData = g_Settings.VictoryConditions.find(vc => vc.Name == victoryCondition); + return victoryConditionData ? victoryConditionData.Title : translateWithContext("victory condition", "Unknown"); } 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 @@ -7,8 +7,9 @@ const g_TriggerDifficulties = prepareForDropdown(g_Settings && g_Settings.TriggerDifficulties); const g_PopulationCapacities = prepareForDropdown(g_Settings && g_Settings.PopulationCapacities); const g_StartingResources = prepareForDropdown(g_Settings && g_Settings.StartingResources); -const g_VictoryConditions = prepareForDropdown(g_Settings && g_Settings.VictoryConditions); const g_VictoryDurations = prepareForDropdown(g_Settings && g_Settings.VictoryDurations); + +const g_VictoryConditions = g_Settings && g_Settings.VictoryConditions || []; var g_GameSpeeds = getGameSpeedChoices(false); /** @@ -420,7 +421,12 @@ { "label": translateWithContext("Match settings tab name", "Game Type"), "settings": [ - "victoryCondition", + "conquest", + "conquestUnit", + "conquestStructure", + "captureTheRelic", + "regicide", + "wonder", "relicCount", "relicDuration", "wonderDuration", @@ -627,22 +633,6 @@ "enabled": () => g_GameAttributes.mapType != "scenario", "initOrder": 1000 }, - "victoryCondition": { - "title": () => translate("Victory Condition"), - "tooltip": (hoverIdx) => g_VictoryConditions.Description[hoverIdx] || translate("Select victory condition."), - "labels": () => g_VictoryConditions.Title, - "ids": () => g_VictoryConditions.Name, - "default": () => g_VictoryConditions.Default, - "defined": () => g_GameAttributes.settings.GameType !== undefined, - "get": () => g_GameAttributes.settings.GameType, - "select": (itemIdx) => { - g_GameAttributes.settings.GameType = g_VictoryConditions.Name[itemIdx]; - g_GameAttributes.settings.VictoryScripts = g_VictoryConditions.Scripts[itemIdx]; - }, - "enabled": () => g_GameAttributes.mapType != "scenario", - "autocomplete": 0, - "initOrder": 1000 - }, "relicCount": { "title": () => translate("Relic Count"), "tooltip": (hoverIdx) => 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."), @@ -654,7 +644,9 @@ "select": (itemIdx) => { g_GameAttributes.settings.RelicCount = g_RelicCountList[itemIdx]; }, - "hidden": () => g_GameAttributes.settings.GameType != "capture_the_relic", + "hidden": () => + g_GameAttributes.settings.VictoryConditions && + g_GameAttributes.settings.VictoryConditions.indexOf("capture_the_relic") == -1, "enabled": () => g_GameAttributes.mapType != "scenario", "initOrder": 1000 }, @@ -669,7 +661,9 @@ "select": (itemIdx) => { g_GameAttributes.settings.RelicDuration = g_VictoryDurations.Duration[itemIdx]; }, - "hidden": () => g_GameAttributes.settings.GameType != "capture_the_relic", + "hidden": () => + g_GameAttributes.settings.VictoryConditions && + g_GameAttributes.settings.VictoryConditions.indexOf("capture_the_relic") == -1, "enabled": () => g_GameAttributes.mapType != "scenario", "initOrder": 1000 }, @@ -684,7 +678,9 @@ "select": (itemIdx) => { g_GameAttributes.settings.WonderDuration = g_VictoryDurations.Duration[itemIdx]; }, - "hidden": () => g_GameAttributes.settings.GameType != "wonder", + "hidden": () => + g_GameAttributes.settings.VictoryConditions && + g_GameAttributes.settings.VictoryConditions.indexOf("wonder") == -1, "enabled": () => g_GameAttributes.mapType != "scenario", "initOrder": 1000 }, @@ -810,6 +806,144 @@ * Contains the logic of all boolean gamesettings. */ var g_Checkboxes = { + "conquest": { + "title": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("conquest")].Title, + "tooltip": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("conquest")].Description, + "default": () => true, + "defined": () => g_GameAttributes.settings.VictoryConditions !== undefined, + "get": () => g_GameAttributes.settings.VictoryConditions.indexOf("conquest") != -1, + "set": checked => { + if (checked) + { + if (!g_GameAttributes.settings.VictoryConditions) + g_GameAttributes.settings.VictoryConditions = []; + g_GameAttributes.settings.VictoryConditions.push("conquest"); + g_Checkboxes.conquestUnit.set(false); + g_Checkboxes.conquestStructure.set(false); + } + else + { + let index = g_GameAttributes.settings.VictoryConditions.indexOf("conquest"); + if (index != -1) + g_GameAttributes.settings.VictoryConditions.splice(index, 1) + } + }, + "enabled": () => g_GameAttributes.mapType != "scenario", + }, + "conquestUnit": { + "title": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("conquest_units")].Title, + "tooltip": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("conquest_units")].Description, + "default": () => false, + "defined": () => g_GameAttributes.settings.VictoryConditions !== undefined, + "get": () => g_GameAttributes.settings.VictoryConditions.indexOf("conquest_units") != -1, + "set": checked => { + if (checked) + { + if (!g_GameAttributes.settings.VictoryConditions) + g_GameAttributes.settings.VictoryConditions = []; + g_GameAttributes.settings.VictoryConditions.push("conquest_units"); + } + else + { + let index = g_GameAttributes.settings.VictoryConditions.indexOf("conquest_units"); + if (index != -1) + g_GameAttributes.settings.VictoryConditions.splice(index, 1) + } + }, + "enabled": () => + g_GameAttributes.settings.VictoryConditions.indexOf("conquest") == -1 && + g_GameAttributes.mapType != "scenario", + }, + "conquestStructure": { + "title": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("conquest_structures")].Title, + "tooltip": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("conquest_structures")].Description, + "default": () => false, + "defined": () => g_GameAttributes.settings.VictoryConditions !== undefined, + "get": () => g_GameAttributes.settings.VictoryConditions.indexOf("conquest_structures") != -1, + "set": checked => { + if (checked) + { + if (!g_GameAttributes.settings.VictoryConditions) + g_GameAttributes.settings.VictoryConditions = []; + g_GameAttributes.settings.VictoryConditions.push("conquest_structures"); + } + else + { + let index = g_GameAttributes.settings.VictoryConditions.indexOf("conquest_structures"); + if (index != -1) + g_GameAttributes.settings.VictoryConditions.splice(index, 1) + } + }, + "enabled": () => + g_GameAttributes.settings.VictoryConditions.indexOf("conquest") == -1 && + g_GameAttributes.mapType != "scenario", + }, + "captureTheRelic": { + "title": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("capture_the_relic")].Title, + "tooltip": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("capture_the_relic")].Description, + "default": () => false, + "defined": () => g_GameAttributes.settings.VictoryConditions !== undefined, + "get": () => g_GameAttributes.settings.VictoryConditions.indexOf("capture_the_relic") != -1, + "set": checked => { + if (checked) + { + if (!g_GameAttributes.settings.VictoryConditions) + g_GameAttributes.settings.VictoryConditions = []; + g_GameAttributes.settings.VictoryConditions.push("capture_the_relic"); + } + else + { + let index = g_GameAttributes.settings.VictoryConditions.indexOf("capture_the_relic"); + if (index != -1) + g_GameAttributes.settings.VictoryConditions.splice(index, 1) + } + }, + "enabled": () => g_GameAttributes.mapType != "scenario", + }, + "wonder": { + "title": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("wonder")].Title, + "tooltip": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("wonder")].Description, + "default": () => false, + "defined": () => g_GameAttributes.settings.VictoryConditions !== undefined, + "get": () => g_GameAttributes.settings.VictoryConditions.indexOf("wonder") != -1, + "set": checked => { + if (checked) + { + if (!g_GameAttributes.settings.VictoryConditions) + g_GameAttributes.settings.VictoryConditions = []; + g_GameAttributes.settings.VictoryConditions.push("wonder"); + } + else + { + let index = g_GameAttributes.settings.VictoryConditions.indexOf("wonder"); + if (index != -1) + g_GameAttributes.settings.VictoryConditions.splice(index, 1) + } + }, + "enabled": () => g_GameAttributes.mapType != "scenario", + }, + "regicide": { + "title": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("regicide")].Title, + "tooltip": () => g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf("regicide")].Description, + "default": () => false, + "defined": () => g_GameAttributes.settings.VictoryConditions !== undefined, + "get": () => g_GameAttributes.settings.VictoryConditions.indexOf("regicide") != -1, + "set": checked => { + if (checked) + { + if (!g_GameAttributes.settings.VictoryConditions) + g_GameAttributes.settings.VictoryConditions = []; + g_GameAttributes.settings.VictoryConditions.push("regicide"); + } + else + { + let index = g_GameAttributes.settings.VictoryConditions.indexOf("regicide"); + if (index != -1) + g_GameAttributes.settings.VictoryConditions.splice(index, 1) + } + }, + "enabled": () => g_GameAttributes.mapType != "scenario", + }, "regicideGarrison": { "title": () => translate("Hero Garrison"), "tooltip": () => translate("Toggle whether heroes can be garrisoned."), @@ -819,7 +953,7 @@ "set": checked => { g_GameAttributes.settings.RegicideGarrison = checked; }, - "hidden": () => g_GameAttributes.settings.GameType != "regicide", + "hidden": () => g_GameAttributes.settings.VictoryConditions.indexOf("regicide") == -1, "enabled": () => g_GameAttributes.mapType != "scenario", "initOrder": 1000 }, @@ -1973,14 +2107,8 @@ let mapSettings = mapData && mapData.settings ? clone(mapData.settings) : {}; if (g_GameAttributes.mapType != "random") - { delete g_GameAttributes.settings.Nomad; - let victoryIdx = g_VictoryConditions.Name.indexOf(mapSettings.GameType || "") != -1 ? g_VictoryConditions.Name.indexOf(mapSettings.GameType) : g_VictoryConditions.Default; - g_GameAttributes.settings.GameType = g_VictoryConditions.Name[victoryIdx]; - g_GameAttributes.settings.VictoryScripts = g_VictoryConditions.Scripts[victoryIdx]; - } - if (g_GameAttributes.mapType == "scenario") { delete g_GameAttributes.settings.RelicDuration; @@ -2120,13 +2248,7 @@ // Select random map if (g_GameAttributes.map == "random") - { - let victoryScriptsSelected = g_GameAttributes.settings.VictoryScripts; - let gameTypeSelected = g_GameAttributes.settings.GameType; selectMap(pickRandom(g_Dropdowns.mapSelection.ids().slice(1))); - g_GameAttributes.settings.VictoryScripts = victoryScriptsSelected; - g_GameAttributes.settings.GameType = gameTypeSelected; - } if (g_GameAttributes.settings.Biome == "random") g_GameAttributes.settings.Biome = pickRandom( @@ -2134,6 +2256,11 @@ g_BiomeList.Id.slice(1).filter(biomeID => biomeID.startsWith(g_GameAttributes.settings.SupportedBiomes)) : g_GameAttributes.settings.SupportedBiomes); + let victoryScriptsSelected = []; + for (let vc of g_GameAttributes.settings.VictoryConditions) + victoryScriptsSelected = victoryScriptsSelected.concat(g_VictoryConditions[g_VictoryConditions.map(data => data.Name).indexOf(vc)].Scripts); + + g_GameAttributes.settings.VictoryScripts = victoryScriptsSelected.filter((vc, i) => victoryScriptsSelected.indexOf(vc) == i) g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts.concat(g_GameAttributes.settings.TriggerScripts || []); // Prevent reseting the readystate @@ -2264,7 +2391,6 @@ for (let name in g_MiscControls) updateGUIMiscControl(name); - updateGameDescription(); distributeSettings(); rightAlignCancelButton(); @@ -2626,7 +2752,7 @@ "niceMapName": getMapDisplayName(g_GameAttributes.map), "mapSize": g_GameAttributes.mapType == "random" ? g_GameAttributes.settings.Size : "Default", "mapType": g_GameAttributes.mapType, - "victoryCondition": g_GameAttributes.settings.GameType, + "victoryConditions": g_GameAttributes.settings.VictoryConditions.join(","), "nbp": clients.connectedPlayers, "maxnbp": g_GameAttributes.settings.PlayerData.length, "players": clients.list, Index: binaries/data/mods/public/gui/replaymenu/replay_filters.js =================================================================== --- binaries/data/mods/public/gui/replaymenu/replay_filters.js +++ binaries/data/mods/public/gui/replaymenu/replay_filters.js @@ -243,7 +243,8 @@ // Filter by victory condition let victoryConditionFilter = Engine.GetGUIObjectByName("victoryConditionFilter"); - if (victoryConditionFilter.selected > 0 && replay.attribs.settings.GameType != victoryConditionFilter.list_data[victoryConditionFilter.selected]) + if (victoryConditionFilter.selected > 0 && + replay.attribs.settings.VictoryConditions.indexOf(victoryConditionFilter.list_data[victoryConditionFilter.selected]) == -1) return false; // Filter by rating Index: binaries/data/mods/public/gui/replaymenu/replay_menu.js =================================================================== --- binaries/data/mods/public/gui/replaymenu/replay_menu.js +++ binaries/data/mods/public/gui/replaymenu/replay_menu.js @@ -109,8 +109,9 @@ g_MapNames.push(replay.attribs.settings.Name); // Extract victory conditions - if (replay.attribs.settings.GameType && g_VictoryConditions.indexOf(replay.attribs.settings.GameType) == -1) - g_VictoryConditions.push(replay.attribs.settings.GameType); + for (let vc of replay.attribs.settings.VictoryConditions) + if (g_VictoryConditions.indexOf(vc) == -1) + g_VictoryConditions.push(vc); // Extract playernames for (let playerData of replay.attribs.settings.PlayerData) @@ -182,9 +183,6 @@ if (!attribs.settings.mapType) attribs.settings.mapType = "skirmish"; - if (!attribs.settings.GameType) - attribs.settings.GameType = "conquest"; - // Remove gaia if (attribs.settings.PlayerData.length && attribs.settings.PlayerData[0] == null) attribs.settings.PlayerData.shift(); @@ -276,7 +274,8 @@ Engine.GetGUIObjectByName("sgMapName").caption = translate(replay.attribs.settings.Name); Engine.GetGUIObjectByName("sgMapSize").caption = translateMapSize(replay.attribs.settings.Size); Engine.GetGUIObjectByName("sgMapType").caption = translateMapType(replay.attribs.settings.mapType); - Engine.GetGUIObjectByName("sgVictory").caption = translateVictoryCondition(replay.attribs.settings.GameType); + Engine.GetGUIObjectByName("sgVictory").caption = replay.attribs.settings.VictoryConditions.map(vc => + translateVictoryCondition(vc)).join(", "); Engine.GetGUIObjectByName("sgNbPlayers").caption = sprintf(translate("Players: %(numberOfPlayers)s"), { "numberOfPlayers": replay.attribs.settings.PlayerData.length }); Engine.GetGUIObjectByName("replayFilename").caption = Engine.GetReplayDirectoryName(replay.directory); Index: binaries/data/mods/public/gui/replaymenu/replay_menu.xml =================================================================== --- binaries/data/mods/public/gui/replaymenu/replay_menu.xml +++ binaries/data/mods/public/gui/replaymenu/replay_menu.xml @@ -183,7 +183,7 @@ - + Index: binaries/data/mods/public/gui/session/session.js =================================================================== --- binaries/data/mods/public/gui/session/session.js +++ binaries/data/mods/public/gui/session/session.js @@ -7,8 +7,9 @@ const g_MapTypes = prepareForDropdown(g_Settings && g_Settings.MapTypes); const g_PopulationCapacities = prepareForDropdown(g_Settings && g_Settings.PopulationCapacities); const g_StartingResources = prepareForDropdown(g_Settings && g_Settings.StartingResources); -const g_VictoryConditions = prepareForDropdown(g_Settings && g_Settings.VictoryConditions); const g_VictoryDurations = prepareForDropdown(g_Settings && g_Settings.VictoryDurations); + +const g_VictoryConditions = g_Settings && g_Settings.VictoryConditions || []; var g_GameSpeeds; /** Index: binaries/data/mods/public/maps/random/wall_demo.json =================================================================== --- binaries/data/mods/public/maps/random/wall_demo.json +++ binaries/data/mods/public/maps/random/wall_demo.json @@ -1,13 +1,13 @@ { "settings" : { "Name" : "Wall Demo", - "GameType" : "endless", "Script" : "wall_demo.js", "Description" : "A demonstration of wall placement methods/code in random maps. Giant map size is recommended!", "Keywords": ["demo"], "CircularMap" : false, "TriggerScripts" : [ "random/wall_demo_triggers.js" - ] + ], + "VictoryConditions": [] } } Index: binaries/data/mods/public/maps/scripts/CaptureTheRelic.js =================================================================== --- binaries/data/mods/public/maps/scripts/CaptureTheRelic.js +++ binaries/data/mods/public/maps/scripts/CaptureTheRelic.js @@ -12,7 +12,7 @@ } let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); - let numSpawnedRelics = cmpEndGameManager.GetGameTypeSettings().relicCount; + let numSpawnedRelics = cmpEndGameManager.GetGameSettings().relicCount; this.playerRelicsCount = new Array(TriggerHelper.GetNumberOfPlayers()).fill(0, 1); this.playerRelicsCount[0] = numSpawnedRelics; @@ -122,7 +122,7 @@ let cmpPlayer = QueryOwnerInterface(this.relics[0], IID_Player); let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); - let captureTheRelicDuration = cmpEndGameManager.GetGameTypeSettings().relicDuration; + let captureTheRelicDuration = cmpEndGameManager.GetGameSettings().relicDuration; let isTeam = playerAndAllies.length > 1; this.ownRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({ Index: binaries/data/mods/public/maps/scripts/Conquest.js =================================================================== --- binaries/data/mods/public/maps/scripts/Conquest.js +++ binaries/data/mods/public/maps/scripts/Conquest.js @@ -1,5 +1,7 @@ { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); - cmpTrigger.conquestClassFilter = "ConquestCritical"; - cmpTrigger.conquestDefeatReason = markForTranslation("%(player)s has been defeated (lost all critical units and structures)."); + cmpTrigger.conquestData.push({ + "classFilter": "ConquestCritical", + "defeatReason": markForTranslation("%(player)s has been defeated (lost all critical units and structures).") + }); } Index: binaries/data/mods/public/maps/scripts/ConquestCommon.js =================================================================== --- binaries/data/mods/public/maps/scripts/ConquestCommon.js +++ binaries/data/mods/public/maps/scripts/ConquestCommon.js @@ -1,54 +1,59 @@ Trigger.prototype.ConquestOwnershipChanged = function(msg) { - if (!this.conquestDataInit || !this.conquestClassFilter) + if (!this.conquestDataInit) return; - if (!TriggerHelper.EntityMatchesClassList(msg.entity, this.conquestClassFilter)) - return; - - if (msg.to > 0) - this.conquestEntitiesByPlayer[msg.to].push(msg.entity); - - if (msg.from > 0) + for (let i = 0; i < this.conquestData.length; ++i) { - let entities = this.conquestEntitiesByPlayer[msg.from]; - let index = entities.indexOf(msg.entity); - if (index != -1) - entities.splice(index, 1); + if (!TriggerHelper.EntityMatchesClassList(msg.entity, this.conquestData[i].classFilter)) + continue; - if (!entities.length) + if (msg.to > 0) + this.conquestData[i].entitiesByPlayer[msg.to].push(msg.entity); + + if (msg.from > 0) { - let cmpPlayer = QueryPlayerIDInterface(msg.from); - if (cmpPlayer) - cmpPlayer.SetState("defeated", this.conquestDefeatReason); + let entities = this.conquestData[i].entitiesByPlayer[msg.from]; + let index = entities.indexOf(msg.entity); + if (index != -1) + entities.splice(index, 1); + + if (!entities.length) + { + let cmpPlayer = QueryPlayerIDInterface(msg.from); + if (cmpPlayer) + cmpPlayer.SetState("defeated", this.conquestData[i].defeatReason); + } } } }; Trigger.prototype.ConquestStartGameCount = function() { - if (!this.conquestClassFilter) + if (!this.conquestData.length) { - warn("ConquestStartGameCount: conquestClassFilter undefined"); + warn("ConquestStartGameCount: no conquestData set"); return; } let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - let numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers(); - for (let i = 1; i < numPlayers; ++i) - this.conquestEntitiesByPlayer[i] = - cmpRangeManager.GetEntitiesByPlayer(i).filter(ent => - TriggerHelper.EntityMatchesClassList(ent, this.conquestClassFilter)); + let entitiesByPlayer = []; + for (let playerID = 1; playerID < numPlayers; ++playerID) + entitiesByPlayer[playerID] = cmpRangeManager.GetEntitiesByPlayer(playerID); + + for (let i = 0; i < this.conquestData.length; ++i) + this.conquestData[i].entitiesByPlayer = entitiesByPlayer.map( + ents => ents.filter( + ent => TriggerHelper.EntityMatchesClassList(ent, this.conquestData[i].classFilter))); this.conquestDataInit = true; }; { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); - cmpTrigger.conquestEntitiesByPlayer = {}; cmpTrigger.conquestDataInit = false; - cmpTrigger.conquestClassFilter = ""; + cmpTrigger.conquestData = []; cmpTrigger.RegisterTrigger("OnOwnershipChanged", "ConquestOwnershipChanged", { "enabled": true }); cmpTrigger.DoAfterDelay(0, "ConquestStartGameCount", null); } Index: binaries/data/mods/public/maps/scripts/ConquestStructures.js =================================================================== --- binaries/data/mods/public/maps/scripts/ConquestStructures.js +++ binaries/data/mods/public/maps/scripts/ConquestStructures.js @@ -1,5 +1,7 @@ { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); - cmpTrigger.conquestClassFilter = "Structure"; - cmpTrigger.conquestDefeatReason = markForTranslation("%(player)s has been defeated (lost all structures)."); + cmpTrigger.conquestData.push({ + "classFilter": "Structure", + "defeatReason": markForTranslation("%(player)s has been defeated (lost all structures).") + }); } Index: binaries/data/mods/public/maps/scripts/ConquestUnits.js =================================================================== --- binaries/data/mods/public/maps/scripts/ConquestUnits.js +++ binaries/data/mods/public/maps/scripts/ConquestUnits.js @@ -1,5 +1,7 @@ { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); - cmpTrigger.conquestClassFilter = "Unit+!Animal"; - cmpTrigger.conquestDefeatReason = markForTranslation("%(player)s has been defeated (lost all units)."); + cmpTrigger.conquestData.push({ + "classFilter": "Unit+!Animal", + "defeatReason": markForTranslation("%(player)s has been defeated (lost all units).") + }); } Index: binaries/data/mods/public/maps/scripts/Regicide.js =================================================================== --- binaries/data/mods/public/maps/scripts/Regicide.js +++ binaries/data/mods/public/maps/scripts/Regicide.js @@ -9,7 +9,7 @@ Trigger.prototype.InitRegicideGame = function(msg) { let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); - let regicideGarrison = cmpEndGameManager.GetGameTypeSettings().regicideGarrison; + let regicideGarrison = cmpEndGameManager.GetGameSettings().regicideGarrison; let playersCivs = []; for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID) Index: binaries/data/mods/public/maps/scripts/WonderVictory.js =================================================================== --- binaries/data/mods/public/maps/scripts/WonderVictory.js +++ binaries/data/mods/public/maps/scripts/WonderVictory.js @@ -54,7 +54,7 @@ let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); - let wonderDuration = cmpEndGameManager.GetGameTypeSettings().wonderDuration; + let wonderDuration = cmpEndGameManager.GetGameSettings().wonderDuration; this.wonderVictoryMessages[ent] = { "playerID": player, "allies": new Set(allies), Index: binaries/data/mods/public/maps/tutorials/Introductory_Tutorial.xml =================================================================== --- binaries/data/mods/public/maps/tutorials/Introductory_Tutorial.xml +++ binaries/data/mods/public/maps/tutorials/Introductory_Tutorial.xml @@ -40,7 +40,6 @@ { "CircularMap": true, "Description": "This is a basic tutorial to get you started playing 0 A.D.", - "GameType": "endless", "Keywords": ["demo"], "LockTeams": false, "Name": "Introductory Tutorial", @@ -86,7 +85,8 @@ "scripts/TriggerHelper.js", "scripts/Tutorial.js", "tutorials/Introductory_Tutorial.js" - ] + ], + "VictoryConditions": [] } ]]> Index: binaries/data/mods/public/maps/tutorials/starting_economy_walkthrough.xml =================================================================== --- binaries/data/mods/public/maps/tutorials/starting_economy_walkthrough.xml +++ binaries/data/mods/public/maps/tutorials/starting_economy_walkthrough.xml @@ -48,7 +48,6 @@ ], "CircularMap": true, "Description": "This map will give a rough guide for starting the game effectively. Early in the game the most important thing is to gather resources as fast as possible so you are able to build enough troops later.", - "GameType": "endless", "Keywords": ["trigger"], "LockTeams": false, "Name": "Starting Economy Walkthrough", @@ -71,7 +70,8 @@ "scripts/Tutorial.js", "tutorials/starting_economy_walkthrough.js" ], - "Size": 256 + "Size": 256, + "VictoryConditions": [] } ]]> Index: binaries/data/mods/public/simulation/ai/common-api/shared.js =================================================================== --- binaries/data/mods/public/simulation/ai/common-api/shared.js +++ binaries/data/mods/public/simulation/ai/common-api/shared.js @@ -74,7 +74,7 @@ this.timeElapsed = state.timeElapsed; this.circularMap = state.circularMap; this.mapSize = state.mapSize; - this.victoryConditions = new Set([state.gameType]); + this.victoryConditions = new Set(state.victoryConditions); this.alliedVictory = state.alliedVictory; this.ceasefireActive = state.ceasefireActive; this.ceasefireTimeRemaining = state.ceasefireTimeRemaining / 1000; Index: binaries/data/mods/public/simulation/ai/petra/gameTypeManager.js =================================================================== --- binaries/data/mods/public/simulation/ai/petra/gameTypeManager.js +++ binaries/data/mods/public/simulation/ai/petra/gameTypeManager.js @@ -2,7 +2,7 @@ { /** - * Handle events that are important to specific gameTypes + * Handle events that are important to specific victory conditions. * In regicide, train and manage healer guards and military guards for the hero. */ Index: binaries/data/mods/public/simulation/components/EndGameManager.js =================================================================== --- binaries/data/mods/public/simulation/components/EndGameManager.js +++ binaries/data/mods/public/simulation/components/EndGameManager.js @@ -9,11 +9,9 @@ EndGameManager.prototype.Init = function() { - this.gameType = "conquest"; - // Contains settings specific to the victory condition, // for example wonder victory duration. - this.gameTypeSettings = {}; + this.gameSettings = {}; // Allied victory means allied players can win if victory conditions are met for each of them // False for a "last man standing" game @@ -28,24 +26,23 @@ this.endlessGame = false; }; -EndGameManager.prototype.GetGameType = function() +EndGameManager.prototype.GetGameSettings = function() { - return this.gameType; + return this.gameSettings; }; -EndGameManager.prototype.GetGameTypeSettings = function() +EndGameManager.prototype.GetVictoryConditions = function() { - return this.gameTypeSettings; + return this.gameSettings.victoryConditions; }; -EndGameManager.prototype.SetGameType = function(newGameType, newSettings = {}) +EndGameManager.prototype.SetGameSettings = function(newSettings = {}) { - this.gameType = newGameType; - this.gameTypeSettings = newSettings; + this.gameSettings = newSettings; this.skipAlliedVictoryCheck = false; - this.endlessGame = newGameType == "endless"; + this.endlessGame = !this.gameSettings.victoryConditions.length; - Engine.BroadcastMessage(MT_GameTypeChanged, {}); + Engine.BroadcastMessage(MT_VictoryConditionsChanged, {}); }; /** Index: binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/GuiInterface.js +++ binaries/data/mods/public/simulation/components/GuiInterface.js @@ -154,7 +154,7 @@ // Add the game type and allied victory let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); - ret.gameType = cmpEndGameManager.GetGameType(); + ret.victoryConditions = cmpEndGameManager.GetVictoryConditions(); ret.alliedVictory = cmpEndGameManager.GetAlliedVictory(); // Add basic statistics to each player Index: binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js =================================================================== --- binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js +++ binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js @@ -4,4 +4,4 @@ * Message of the form {} * sent from EndGameManager component. */ -Engine.RegisterMessageType("GameTypeChanged"); +Engine.RegisterMessageType("VictoryConditionsChanged"); Index: binaries/data/mods/public/simulation/components/tests/test_EndGameManager.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_EndGameManager.js +++ binaries/data/mods/public/simulation/components/tests/test_EndGameManager.js @@ -23,7 +23,7 @@ TS_ASSERT_EQUALS(cmpEndGameManager.skipAlliedVictoryCheck, true); cmpEndGameManager.SetAlliedVictory(true); TS_ASSERT_EQUALS(cmpEndGameManager.GetAlliedVictory(), true); -cmpEndGameManager.SetGameType("wonder", { "wonderDuration": wonderDuration }); +cmpEndGameManager.SetGameSettings({ "victoryConditions": ["wonder"], "wonderDuration": wonderDuration }); TS_ASSERT_EQUALS(cmpEndGameManager.skipAlliedVictoryCheck, false); -TS_ASSERT(cmpEndGameManager.GetGameType() == "wonder"); -TS_ASSERT_EQUALS(cmpEndGameManager.GetGameTypeSettings().wonderDuration, wonderDuration); +TS_ASSERT_UNEVAL_EQUALS(cmpEndGameManager.GetVictoryConditions(), ["wonder"]); +TS_ASSERT_EQUALS(cmpEndGameManager.GetGameSettings().wonderDuration, wonderDuration); Index: binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js +++ binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js @@ -66,7 +66,7 @@ }); AddMock(SYSTEM_ENTITY, IID_EndGameManager, { - GetGameType: function() { return "conquest"; }, + GetVictoryConditions: function() { return ["conquest", "wonder"]; }, GetAlliedVictory: function() { return false; } }); @@ -366,7 +366,7 @@ ], circularMap: false, timeElapsed: 0, - gameType: "conquest", + victoryConditions: ["conquest", "wonder"], alliedVictory: false }); @@ -519,7 +519,7 @@ ], "circularMap": false, "timeElapsed": 0, - "gameType": "conquest", + "victoryConditions": ["conquest", "wonder"], "alliedVictory": false }); Index: binaries/data/mods/public/simulation/data/settings/victory_conditions/capture_the_relic.json =================================================================== --- binaries/data/mods/public/simulation/data/settings/victory_conditions/capture_the_relic.json +++ binaries/data/mods/public/simulation/data/settings/victory_conditions/capture_the_relic.json @@ -7,8 +7,6 @@ "Scripts": [ "scripts/TriggerHelper.js", - "scripts/ConquestCommon.js", - "scripts/Conquest.js", "scripts/CaptureTheRelic.js" ] } Index: binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest.json =================================================================== --- binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest.json +++ binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest.json @@ -3,7 +3,7 @@ "Data": { "Title": "Conquest", - "Description": "Defeat all opponents to win.", + "Description": "Defeat opponents by killing all their units and destroying all their buildings.", "Scripts": [ "scripts/TriggerHelper.js", Index: binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest_structures.json =================================================================== --- binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest_structures.json +++ binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest_structures.json @@ -3,7 +3,7 @@ "Data": { "Title": "Conquest Structures", - "Description": "Destroy all enemy structures to win.", + "Description": "Defeat opponents by destroying all their structures.", "Scripts": [ "scripts/TriggerHelper.js", Index: binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest_units.json =================================================================== --- binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest_units.json +++ binaries/data/mods/public/simulation/data/settings/victory_conditions/conquest_units.json @@ -3,7 +3,7 @@ "Data": { "Title": "Conquest Units", - "Description": "Kill all enemy units to win.", + "Description": "Defeat opponents by killing all their units.", "Scripts": [ "scripts/TriggerHelper.js", Index: binaries/data/mods/public/simulation/data/settings/victory_conditions/regicide.json =================================================================== --- binaries/data/mods/public/simulation/data/settings/victory_conditions/regicide.json +++ binaries/data/mods/public/simulation/data/settings/victory_conditions/regicide.json @@ -7,8 +7,6 @@ "Scripts": [ "scripts/TriggerHelper.js", - "scripts/ConquestCommon.js", - "scripts/Conquest.js", "scripts/Regicide.js" ] } Index: binaries/data/mods/public/simulation/data/settings/victory_conditions/wonder.json =================================================================== --- binaries/data/mods/public/simulation/data/settings/victory_conditions/wonder.json +++ binaries/data/mods/public/simulation/data/settings/victory_conditions/wonder.json @@ -7,8 +7,6 @@ "Scripts": [ "scripts/TriggerHelper.js", - "scripts/ConquestCommon.js", - "scripts/Conquest.js", "scripts/WonderVictory.js" ] } Index: binaries/data/mods/public/simulation/helpers/Setup.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Setup.js +++ binaries/data/mods/public/simulation/helpers/Setup.js @@ -53,17 +53,19 @@ } let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); - let gameTypeSettings = {}; - if (settings.GameType && settings.GameType == "capture_the_relic") - gameTypeSettings.relicCount = settings.RelicCount; - if (settings.GameType && settings.GameType == "capture_the_relic") - gameTypeSettings.relicDuration = settings.RelicDuration * 60 * 1000; - if (settings.GameType && settings.GameType == "wonder") - gameTypeSettings.wonderDuration = settings.WonderDuration * 60 * 1000; - if (settings.GameType && settings.GameType == "regicide") - gameTypeSettings.regicideGarrison = settings.RegicideGarrison; - if (settings.GameType) - cmpEndGameManager.SetGameType(settings.GameType, gameTypeSettings); + let gameSettings = {}; + gameSettings.victoryConditions = settings.VictoryConditions || ["conquest"]; + + if (gameSettings.victoryConditions.indexOf("capture_the_relic") != -1) + { + gameSettings.relicCount = settings.RelicCount; + gameSettings.relicDuration = settings.RelicDuration * 60 * 1000; + } + if (gameSettings.victoryConditions.indexOf("wonder") != -1) + gameSettings.wonderDuration = settings.WonderDuration * 60 * 1000; + if (gameSettings.victoryConditions.indexOf("regicide") != -1) + gameSettings.regicideGarrison = settings.RegicideGarrison; + cmpEndGameManager.SetGameSettings(gameSettings); cmpEndGameManager.SetAlliedVictory(settings.LockTeams || !settings.LastManStanding); if (settings.LockTeams && settings.LastManStanding) Index: source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp =================================================================== --- source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp +++ source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -37,6 +37,12 @@ ID_MapTeams, ID_MapKW_Demo, ID_MapKW_Naval, + ID_VC_Conquest, + ID_VC_ConquestUnits, + ID_VC_ConquestStructures, + ID_VC_CaptureTheRelic, + ID_VC_Wonder, + ID_VC_Regicide, ID_RandomScript, ID_RandomSize, ID_RandomSeed, @@ -92,13 +98,17 @@ AtObj UpdateSettingsObject(); private: void SendToEngine(); + void OnConquestChanged(); - void OnEdit(wxCommandEvent& WXUNUSED(evt)) + void OnEdit(wxCommandEvent& evt) { SendToEngine(); + if (evt.GetId() == ID_VC_Conquest) + OnConquestChanged(); } std::set m_MapSettingsKeywords; + std::set m_MapSettingsVictoryConditions; std::vector m_PlayerCivChoices; Observable& m_MapSettings; @@ -141,16 +151,6 @@ sizer->AddSpacer(5); - // TODO: replace by filenames in binaries/data/mods/public/simulation/data/settings/victory_conditions/ - wxArrayString gameTypes; - gameTypes.Add(_T("conquest")); - gameTypes.Add(_T("conquest_structures")); - gameTypes.Add(_T("conquest_units")); - gameTypes.Add(_T("wonder")); - gameTypes.Add(_T("endless")); - gameTypes.Add(_T("regicide")); - gameTypes.Add(_T("capture_the_relic")); - wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5); gridSizer->AddGrowableCol(1); // TODO: have preview selector tool? @@ -160,9 +160,6 @@ gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Reveal map")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); gridSizer->Add(Tooltipped(new wxCheckBox(this, ID_MapReveal, wxEmptyString), _("If checked, players won't need to explore"))); - gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Game type")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); - gridSizer->Add(Tooltipped(new wxChoice(this, ID_MapType, wxDefaultPosition, wxDefaultSize, gameTypes), - _("Select the game type (or victory condition)")), wxSizerFlags().Expand()); gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Lock teams")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); gridSizer->Add(Tooltipped(new wxCheckBox(this, ID_MapTeams, wxEmptyString), _("If checked, teams will be locked"))); @@ -170,6 +167,33 @@ sizer->AddSpacer(5); + // TODO: replace by names in binaries/data/mods/public/simulation/data/settings/victory_conditions/ + wxStaticBoxSizer* victoryConditionSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Victory Conditions")); + wxFlexGridSizer* vcGridSizer = new wxFlexGridSizer(2, 5, 5); + vcGridSizer->AddGrowableCol(1); + vcGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Conquest")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); + vcGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_VC_Conquest, wxEmptyString), + _("Select Conquest victory condition"))); + vcGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Conquest Units")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); + vcGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_VC_ConquestUnits, wxEmptyString), + _("Select Conquest Units victory condition"))); + vcGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Conquest Structures")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); + vcGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_VC_ConquestStructures, wxEmptyString), + _("Select Conquest Structures victory condition"))); + vcGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Capture the Relic")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); + vcGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_VC_CaptureTheRelic, wxEmptyString), + _("Select Capture the Relic victory condition"))); + vcGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Wonder")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); + vcGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_VC_Wonder, wxEmptyString), + _("Select Wonder victory condition"))); + vcGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Regicide")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); + vcGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_VC_Regicide, wxEmptyString), + _("Select Regicide victory condition"))); + victoryConditionSizer->Add(vcGridSizer); + sizer->Add(victoryConditionSizer, wxSizerFlags().Expand()); + + sizer->AddSpacer(5); + wxStaticBoxSizer* keywordsSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Keywords")); wxFlexGridSizer* kwGridSizer = new wxFlexGridSizer(4, 5, 5); kwGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Demo")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT)); @@ -204,11 +228,20 @@ // reveal map wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->SetValue(wxString(m_MapSettings["RevealMap"]) == L"true"); - // game type / victory conditions - if (m_MapSettings["GameType"].defined()) - wxDynamicCast(FindWindow(ID_MapType), wxChoice)->SetStringSelection(wxString(m_MapSettings["GameType"])); - else - wxDynamicCast(FindWindow(ID_MapType), wxChoice)->SetSelection(0); + // victory conditions + { + m_MapSettingsVictoryConditions.clear(); + for (AtIter victoryCondition = m_MapSettings["VictoryConditions"]["item"]; victoryCondition.defined(); ++victoryCondition) + m_MapSettingsVictoryConditions.insert(std::wstring(victoryCondition)); + + wxDynamicCast(FindWindow(ID_VC_Conquest), wxCheckBox)->SetValue(m_MapSettingsVictoryConditions.count(L"conquest") != 0); + wxDynamicCast(FindWindow(ID_VC_ConquestUnits), wxCheckBox)->SetValue(m_MapSettingsVictoryConditions.count(L"conquest_units") != 0); + wxDynamicCast(FindWindow(ID_VC_ConquestStructures), wxCheckBox)->SetValue(m_MapSettingsVictoryConditions.count(L"conquest_structures") != 0); + wxDynamicCast(FindWindow(ID_VC_CaptureTheRelic), wxCheckBox)->SetValue(m_MapSettingsVictoryConditions.count(L"capture_the_relic") != 0); + wxDynamicCast(FindWindow(ID_VC_Wonder), wxCheckBox)->SetValue(m_MapSettingsVictoryConditions.count(L"wonder") != 0); + wxDynamicCast(FindWindow(ID_VC_Regicide), wxCheckBox)->SetValue(m_MapSettingsVictoryConditions.count(L"regicide") != 0); + OnConquestChanged(); + } // lock teams wxDynamicCast(FindWindow(ID_MapTeams), wxCheckBox)->SetValue(wxString(m_MapSettings["LockTeams"]) == L"true"); @@ -232,6 +265,21 @@ SendToEngine(); } +void MapSettingsControl::OnConquestChanged() +{ + bool conqestEnabled = wxDynamicCast(FindWindow(ID_VC_Conquest), wxCheckBox)->GetValue(); + + wxCheckBox* conquestUnitsCheckbox = wxDynamicCast(FindWindow(ID_VC_ConquestUnits), wxCheckBox); + conquestUnitsCheckbox->Enable(!conqestEnabled); + wxCheckBox* conquestStructuresCheckbox = wxDynamicCast(FindWindow(ID_VC_ConquestStructures), wxCheckBox); + conquestStructuresCheckbox->Enable(!conqestEnabled); + if (conqestEnabled) + { + conquestUnitsCheckbox->SetValue(false); + conquestStructuresCheckbox->SetValue(false); + } +} + AtObj MapSettingsControl::UpdateSettingsObject() { // map name @@ -246,8 +294,44 @@ // reveal map m_MapSettings.setBool("RevealMap", wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->GetValue()); - // game type / victory conditions - m_MapSettings.set("GameType", wxDynamicCast(FindWindow(ID_MapType), wxChoice)->GetStringSelection()); + // victory conditions + { + if (wxDynamicCast(FindWindow(ID_VC_Conquest), wxCheckBox)->GetValue()) + m_MapSettingsVictoryConditions.insert(L"conquest"); + else + m_MapSettingsVictoryConditions.erase(L"conquest"); + + if (wxDynamicCast(FindWindow(ID_VC_ConquestUnits), wxCheckBox)->GetValue()) + m_MapSettingsVictoryConditions.insert(L"conquest_units"); + else + m_MapSettingsVictoryConditions.erase(L"conquest_units"); + + if (wxDynamicCast(FindWindow(ID_VC_ConquestStructures), wxCheckBox)->GetValue()) + m_MapSettingsVictoryConditions.insert(L"conquest_structures"); + else + m_MapSettingsVictoryConditions.erase(L"conquest_structures"); + + if (wxDynamicCast(FindWindow(ID_VC_CaptureTheRelic), wxCheckBox)->GetValue()) + m_MapSettingsVictoryConditions.insert(L"capture_the_relic"); + else + m_MapSettingsVictoryConditions.erase(L"capture_the_relic"); + + if (wxDynamicCast(FindWindow(ID_VC_Wonder), wxCheckBox)->GetValue()) + m_MapSettingsVictoryConditions.insert(L"wonder"); + else + m_MapSettingsVictoryConditions.erase(L"wonder"); + + if (wxDynamicCast(FindWindow(ID_VC_Regicide), wxCheckBox)->GetValue()) + m_MapSettingsVictoryConditions.insert(L"regicide"); + else + m_MapSettingsVictoryConditions.erase(L"regicide"); + + AtObj victoryConditions; + victoryConditions.set("@array", L""); + for (std::set::iterator it = m_MapSettingsVictoryConditions.begin(); it != m_MapSettingsVictoryConditions.end(); ++it) + victoryConditions.add("item", it->c_str()); + m_MapSettings.set("VictoryConditions", victoryConditions); + } // keywords {