Implements skirmish maps, based on patch by sanderd17, fixes #1198. Skirmish maps are like scenarios, except the player can choose their civ during match setup. To create a skirmish map: place some skirmish entities for each player in Atlas (see templates/skirmish/* for examples), uncheck the player's civ in Atlas' player panel if desired, and save in the maps/skirmishes directory. The map will appear in match setup under the "Skirmish" match type.
Implements custom, VFS-based map load/save dialogs for Atlas (replaces broken native file dialogs), fixes #631, #889. Fixes map loading/saving to handle arbitrary subdirectories for better organization. Adds default settings to Atlas player panel, fixes #1872. Each setting now has a checkbox to choose whether it should be saved with the map (avoids writing lots of useless default data for each map). Adds map preview setting to Atlas, refs #1745. Cleans up and simplifies some duplicate code. Fixes optional serialization performance test. This was SVN commit r13938.
This commit is contained in:
parent
5c35690309
commit
7901ed51d4
@ -107,8 +107,8 @@ function initMain()
|
||||
|
||||
// Init map types
|
||||
var mapTypes = getGUIObjectByName("mapTypeSelection");
|
||||
mapTypes.list = ["Scenario","Random"];
|
||||
mapTypes.list_data = ["scenario","random"];
|
||||
mapTypes.list = ["Scenario","Skirmish","Random"];
|
||||
mapTypes.list_data = ["scenario","skirmish","random"];
|
||||
|
||||
// Setup map filters - will appear in order they are added
|
||||
addFilter("Default", function(settings) { return settings && !keywordTestOR(settings.Keywords, ["naval", "demo", "hidden"]); });
|
||||
@ -471,6 +471,7 @@ function initMapNameList()
|
||||
switch (g_GameAttributes.mapType)
|
||||
{
|
||||
case "scenario":
|
||||
case "skirmish":
|
||||
mapFiles = getXMLFileList(g_GameAttributes.mapPath);
|
||||
break;
|
||||
|
||||
@ -487,7 +488,7 @@ function initMapNameList()
|
||||
var mapList = [];
|
||||
for (var i = 0; i < mapFiles.length; ++i)
|
||||
{
|
||||
var file = mapFiles[i];
|
||||
var file = g_GameAttributes.mapPath + mapFiles[i];
|
||||
var mapData = loadMapData(file);
|
||||
|
||||
if (g_GameAttributes.mapFilter && mapData && testFilter(g_GameAttributes.mapFilter, mapData.settings))
|
||||
@ -521,22 +522,20 @@ function loadMapData(name)
|
||||
if (!name)
|
||||
return undefined;
|
||||
|
||||
if (name == "random")
|
||||
{
|
||||
g_MapData[name] = {settings : {"Name" : "Random", "Description" : "Randomly selects a map from the list"}};
|
||||
return g_MapData[name];
|
||||
}
|
||||
|
||||
if (!g_MapData[name])
|
||||
{
|
||||
switch (g_GameAttributes.mapType)
|
||||
{
|
||||
case "scenario":
|
||||
g_MapData[name] = Engine.LoadMapSettings(g_GameAttributes.mapPath+name);
|
||||
case "skirmish":
|
||||
g_MapData[name] = Engine.LoadMapSettings(name);
|
||||
break;
|
||||
|
||||
case "random":
|
||||
g_MapData[name] = parseJSONData(g_GameAttributes.mapPath+name+".json");
|
||||
if (name == "random")
|
||||
g_MapData[name] = {settings : {"Name" : "Random", "Description" : "Randomly selects a map from the list"}};
|
||||
else
|
||||
g_MapData[name] = parseJSONData(name+".json");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -652,8 +651,17 @@ function selectMapType(type)
|
||||
case "scenario":
|
||||
// Set a default map
|
||||
// TODO: This should be remembered from the last session
|
||||
g_GameAttributes.map = (g_IsNetworked ? DEFAULT_NETWORKED_MAP : DEFAULT_OFFLINE_MAP);
|
||||
g_GameAttributes.mapPath = "maps/scenarios/";
|
||||
g_GameAttributes.map = g_GameAttributes.mapPath + (g_IsNetworked ? DEFAULT_NETWORKED_MAP : DEFAULT_OFFLINE_MAP);
|
||||
break;
|
||||
|
||||
case "skirmish":
|
||||
g_GameAttributes.mapPath = "maps/skirmishes/";
|
||||
g_GameAttributes.settings = {
|
||||
PlayerData: g_DefaultPlayerData.slice(0, 4),
|
||||
Seed: Math.floor(Math.random() * 65536),
|
||||
CheatsEnabled: g_GameAttributes.settings.CheatsEnabled
|
||||
};
|
||||
break;
|
||||
|
||||
case "random":
|
||||
@ -800,7 +808,7 @@ function launchGame()
|
||||
else
|
||||
var chosenName = civAINames[Math.floor(Math.random() * civAINames.length)];
|
||||
for (var j = 0; j < numPlayers; ++j)
|
||||
if (g_GameAttributes.settings.PlayerData[j].Name.indexOf(chosenName) !== -1)
|
||||
if (g_GameAttributes.settings.PlayerData[j].Name && g_GameAttributes.settings.PlayerData[j].Name.indexOf(chosenName) !== -1)
|
||||
usedName++;
|
||||
|
||||
// Assign civ specific names to AI players
|
||||
@ -899,12 +907,16 @@ function onGameAttributesChange()
|
||||
startingResources.selected = (STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) != -1 ? STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) : STARTING_RESOURCES_DEFAULTIDX);
|
||||
startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];
|
||||
|
||||
// Update map preview
|
||||
getGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
|
||||
|
||||
// Handle map type specific logic
|
||||
switch (g_GameAttributes.mapType)
|
||||
{
|
||||
case "random":
|
||||
if (g_IsController)
|
||||
{ //Host
|
||||
{
|
||||
//Host
|
||||
numPlayersSelection.selected = numPlayers - 1;
|
||||
numPlayersSelection.hidden = false;
|
||||
mapSize.hidden = false;
|
||||
@ -922,9 +934,6 @@ function onGameAttributesChange()
|
||||
populationCapText.hidden = true;
|
||||
startingResourcesText.hidden = true;
|
||||
|
||||
// Update map preview
|
||||
getGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
|
||||
|
||||
mapSizeText.caption = "Map size:";
|
||||
mapSize.selected = sizeIdx;
|
||||
revealMapText.caption = "Reveal map:";
|
||||
@ -947,8 +956,6 @@ function onGameAttributesChange()
|
||||
populationCapText.hidden = false;
|
||||
startingResources.hidden = true;
|
||||
startingResourcesText.hidden = false;
|
||||
// Update map preview
|
||||
getGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
|
||||
|
||||
numPlayersText.caption = numPlayers;
|
||||
mapSizeText.caption = g_MapSizes.names[sizeIdx];
|
||||
@ -959,6 +966,57 @@ function onGameAttributesChange()
|
||||
|
||||
break;
|
||||
|
||||
case "skirmish":
|
||||
mapSizeText.caption = "Default";
|
||||
numPlayersText.caption = numPlayers;
|
||||
numPlayersSelection.hidden = true;
|
||||
mapSize.hidden = true;
|
||||
if (g_IsController)
|
||||
{
|
||||
//Host
|
||||
revealMap.hidden = false;
|
||||
victoryCondition.hidden = false;
|
||||
lockTeams.hidden = false;
|
||||
populationCap.hidden = false;
|
||||
startingResources.hidden = false;
|
||||
|
||||
numPlayersText.hidden = false;
|
||||
mapSizeText.hidden = false;
|
||||
revealMapText.hidden = true;
|
||||
victoryConditionText.hidden = true;
|
||||
lockTeamsText.hidden = true;
|
||||
populationCapText.hidden = true;
|
||||
startingResourcesText.hidden = true;
|
||||
|
||||
revealMapText.caption = "Reveal map:";
|
||||
revealMap.checked = (mapSettings.RevealMap ? true : false);
|
||||
|
||||
victoryConditionText.caption = "Victory condition:";
|
||||
victoryCondition.selected = victoryIdx;
|
||||
lockTeamsText.caption = "Teams locked:";
|
||||
lockTeams.checked = (mapSettings.LockTeams ? true : false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Client
|
||||
numPlayersText.hidden = false;
|
||||
mapSizeText.hidden = false;
|
||||
revealMapText.hidden = false;
|
||||
victoryConditionText.hidden = false;
|
||||
lockTeamsText.hidden = false;
|
||||
populationCap.hidden = true;
|
||||
populationCapText.hidden = false;
|
||||
startingResources.hidden = true;
|
||||
startingResourcesText.hidden = false;
|
||||
|
||||
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
|
||||
victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
|
||||
lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case "scenario":
|
||||
// For scenario just reflect settings for the current map
|
||||
numPlayersSelection.hidden = true;
|
||||
@ -976,8 +1034,6 @@ function onGameAttributesChange()
|
||||
startingResources.hidden = true;
|
||||
startingResourcesText.hidden = false;
|
||||
|
||||
// Update map preview
|
||||
getGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
|
||||
numPlayersText.caption = numPlayers;
|
||||
mapSizeText.caption = "Default";
|
||||
revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
|
||||
@ -1046,7 +1102,7 @@ function onGameAttributesChange()
|
||||
pCivText.caption = g_CivData[civ].Name;
|
||||
pTeamText.caption = (team !== undefined && team >= 0) ? team+1 : "-";
|
||||
}
|
||||
else if (g_GameAttributes.mapType == "random")
|
||||
else if (g_GameAttributes.mapType != "scenario")
|
||||
{
|
||||
pCivText.hidden = true;
|
||||
pCiv.hidden = false;
|
||||
|
@ -46,6 +46,7 @@ function init(data)
|
||||
var mapName = data.attribs.settings.Name;
|
||||
switch (data.attribs.mapType)
|
||||
{
|
||||
case "skirmish":
|
||||
case "scenario":
|
||||
loadingMapName.caption = "Loading \"" + mapName + "\"";
|
||||
break;
|
||||
|
@ -0,0 +1,63 @@
|
||||
const civList = ["general", "athen", "brit", "cart", "celt", "gaul", "hele", "iber", "mace", "maur", "pers", "rome", "spart"];
|
||||
|
||||
function SkirmishReplacer() {}
|
||||
|
||||
|
||||
SkirmishReplacer.prototype.Schema = "";
|
||||
for each (var civ in civList)
|
||||
SkirmishReplacer.prototype.Schema +=
|
||||
"<optional>" +
|
||||
"<element name='"+civ+"' a:help='Replacement template for this civ. If this element is not present, the \"general\" element (with {civ} replaced by the civ code) is taken. If this element is empty, or not defined, and also no general element, this entity is just deleted.'>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"</optional>";
|
||||
|
||||
|
||||
|
||||
SkirmishReplacer.prototype.Init = function()
|
||||
{
|
||||
};
|
||||
|
||||
SkirmishReplacer.prototype.OnOwnershipChanged = function(msg)
|
||||
{
|
||||
if (msg.to == 0)
|
||||
warn("Skirmish map elements can only be owned by regular players. Please delete entity "+this.entity+" or change the ownership to a non-gaia player.");
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace this entity with a civ-specific entity on the first turn
|
||||
*/
|
||||
SkirmishReplacer.prototype.OnUpdate = function(msg)
|
||||
{
|
||||
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
|
||||
var civ = cmpPlayer.GetCiv();
|
||||
|
||||
var templateName = "";
|
||||
if (civ in this.template)
|
||||
templateName = this.template[civ];
|
||||
else if ("general" in this.template)
|
||||
templateName = this.template.general;
|
||||
|
||||
if (!templateName || civ == "gaia")
|
||||
{
|
||||
Engine.DestroyEntity(this.entity);
|
||||
return;
|
||||
}
|
||||
|
||||
templateName = templateName.replace(/\{civ\}/g, civ);
|
||||
|
||||
var cmpCurPosition = Engine.QueryInterface(this.entity, IID_Position);
|
||||
var replacement = Engine.AddEntity(templateName);
|
||||
var cmpReplacementPosition = Engine.QueryInterface(replacement, IID_Position)
|
||||
var pos = cmpCurPosition.GetPosition2D();
|
||||
cmpReplacementPosition.JumpTo(pos.x, pos.y);
|
||||
var rot = cmpCurPosition.GetRotation();
|
||||
cmpReplacementPosition.SetYRotation(rot.y);
|
||||
var cmpCurOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
|
||||
var cmpReplacementOwnership = Engine.QueryInterface(replacement, IID_Ownership);
|
||||
cmpReplacementOwnership.SetOwner(cmpCurOwnership.GetOwner());
|
||||
|
||||
Engine.DestroyEntity(this.entity);
|
||||
};
|
||||
|
||||
Engine.RegisterComponentType(IID_SkirmishReplacer, "SkirmishReplacer", SkirmishReplacer);
|
@ -0,0 +1 @@
|
||||
Engine.RegisterInterface("SkirmishReplacer");
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_civic_civil_centre">
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<SkirmishReplacer>
|
||||
<general>structures/{civ}_civil_centre</general>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/athenians/civic_centre_new.xml</Actor>
|
||||
</VisualActor>
|
||||
</Entity>
|
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_gate">
|
||||
<Footprint>
|
||||
<Square width="39.0" depth="8.0"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Obstructions>
|
||||
<Right width="12" depth="6.5" x="12.5" z="0"/>
|
||||
<Left width="12" depth="6.5" x="-12.5" z="0"/>
|
||||
<Door width="13" depth="6.5" x="0" z="0"/>
|
||||
</Obstructions>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<general>structures/{civ}_wall_gate</general>
|
||||
<spart/>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/hellenes/wall_gate.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>38.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_long">
|
||||
<Footprint>
|
||||
<Square width="37" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="36.0" depth="8"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<general>structures/{civ}_wall_long</general>
|
||||
<spart/>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/hellenes/wall_long.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>36.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_medium">
|
||||
<Footprint>
|
||||
<Square width="25" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="24.0" depth="8"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<general>structures/{civ}_wall_medium</general>
|
||||
<spart/>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/hellenes/wall_medium.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>24.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_short">
|
||||
<Footprint>
|
||||
<Square width="13" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="12.0" depth="8"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<general>structures/{civ}_wall_short</general>
|
||||
<spart/>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/hellenes/wall_short.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>12.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_tower">
|
||||
<Footprint replace="">
|
||||
<Circle radius="6.2"/>
|
||||
<Height>15.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="10" depth="10"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<general>structures/{civ}_wall_tower</general>
|
||||
<spart/>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/hellenes/wall_tower.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>10</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_gate">
|
||||
<Footprint>
|
||||
<Square width="37.0" depth="9.5"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Obstructions>
|
||||
<Right width="10" depth="8.5" x="13" z="0"/>
|
||||
<Left width="10" depth="8.5" x="-13" z="0"/>
|
||||
<Door width="16.0" depth="8.5" x="0" z="0"/>
|
||||
</Obstructions>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<iber>structures/iber_wall_gate</iber>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/iberians/wall_gate.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>36.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_long">
|
||||
<Footprint>
|
||||
<Square width="37" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="36.0" depth="8"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<iber>structures/iber_wall_long</iber>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/iberians/wall_long.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>36.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_medium">
|
||||
<Footprint>
|
||||
<Square width="25" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="24.0" depth="8"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<iber>structures/iber_wall_medium</iber>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/iberians/wall_medium.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>24.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_short">
|
||||
<Footprint>
|
||||
<Square width="13" depth="9"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="12.0" depth="8"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<iber>structures/iber_wall_short</iber>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/iberians/wall_short.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>12.0</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_structure_defense_wall_tower">
|
||||
<Footprint replace="">
|
||||
<Circle radius="6.2"/>
|
||||
<Height>15.0</Height>
|
||||
</Footprint>
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Obstruction>
|
||||
<Static width="10" depth="10"/>
|
||||
</Obstruction>
|
||||
<SkirmishReplacer>
|
||||
<iber>structures/iber_wall_tower</iber>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>structures/iberians/wall_tower.xml</Actor>
|
||||
</VisualActor>
|
||||
<WallPiece>
|
||||
<Length>10</Length>
|
||||
</WallPiece>
|
||||
</Entity>
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_unit_cavalry">
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Promotion disable=""/>
|
||||
<SkirmishReplacer>
|
||||
<general>units/{civ}_cavalry_javelinist_b</general>
|
||||
<celt>units/celt_cavalry_swordsman_b</celt>
|
||||
<gaul>units/gaul_cavalry_swordsman_b</gaul>
|
||||
<hele>units/hele_cavalry_swordsman_b</hele>
|
||||
<iber>units/iber_cavalry_spearman_b</iber>
|
||||
<maur>units/maur_support_elephant</maur>
|
||||
<rome>units/rome_cavalry_spearman_b</rome>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>units/athenians/cavalry_javelinist_b.xml</Actor>
|
||||
</VisualActor>
|
||||
</Entity>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_unit_infantry_melee">
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Promotion disable=""/>
|
||||
<SkirmishReplacer>
|
||||
<general>units/{civ}_infantry_spearman_b</general>
|
||||
<rome>units/rome_infantry_swordsman_b</rome>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>units/athenians/infantry_spearman_b.xml</Actor>
|
||||
</VisualActor>
|
||||
</Entity>
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_unit_infantry_ranged">
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<Promotion disable=""/>
|
||||
<SkirmishReplacer>
|
||||
<general>units/{civ}_infantry_javelinist_b</general>
|
||||
<athen>units/athen_infantry_slinger_b</athen>
|
||||
<brit>units/brit_infantry_slinger_b</brit>
|
||||
<cart>units/cart_infantry_archer_b</cart>
|
||||
<maur>units/maur_infantry_archer_b</maur>
|
||||
<pers>units/pers_infantry_archer_b</pers>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>units/athenians/infantry_slinger_b.xml</Actor>
|
||||
</VisualActor>
|
||||
</Entity>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity parent="template_unit_support_female_citizen">
|
||||
<Identity>
|
||||
<Civ>skirm</Civ>
|
||||
</Identity>
|
||||
<SkirmishReplacer>
|
||||
<general>units/{civ}_support_female_citizen</general>
|
||||
</SkirmishReplacer>
|
||||
<VisualActor>
|
||||
<Actor>units/athenians/female_citizen.xml</Actor>
|
||||
</VisualActor>
|
||||
</Entity>
|
@ -951,6 +951,7 @@ function setup_atlas_projects()
|
||||
"CustomControls/EditableListCtrl",
|
||||
"CustomControls/FileHistory",
|
||||
"CustomControls/HighResTimer",
|
||||
"CustomControls/MapDialog",
|
||||
"CustomControls/SnapSplitterWindow",
|
||||
"CustomControls/VirtualDirTreeCtrl",
|
||||
"CustomControls/Windows",
|
||||
|
@ -64,7 +64,7 @@ CMapReader::CMapReader()
|
||||
}
|
||||
|
||||
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
|
||||
void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_,
|
||||
void CMapReader::LoadMap(const VfsPath& pathname, const CScriptValRooted& settings, CTerrain *pTerrain_,
|
||||
WaterManager* pWaterMan_, SkyManager* pSkyMan_,
|
||||
CLightEnv *pLightEnv_, CGameView *pGameView_, CCinemaManager* pCinema_, CTriggerManager* pTrigMan_, CPostprocManager* pPostproc_,
|
||||
CSimulation2 *pSimulation2_, const CSimContext* pSimContext_, int playerID_, bool skipEntities)
|
||||
@ -83,6 +83,7 @@ void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_,
|
||||
m_PlayerID = playerID_;
|
||||
m_SkipEntities = skipEntities;
|
||||
m_StartingCameraTarget = INVALID_ENTITY;
|
||||
m_ScriptSettings = settings;
|
||||
|
||||
filename_xml = pathname.ChangeExtension(L".xml");
|
||||
|
||||
@ -116,8 +117,11 @@ void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_,
|
||||
if (pPostproc)
|
||||
pPostproc->SetPostEffect(L"default");
|
||||
|
||||
// load map settings script
|
||||
// load map or script settings script
|
||||
if (settings.undefined())
|
||||
RegMemFun(this, &CMapReader::LoadScriptSettings, L"CMapReader::LoadScriptSettings", 50);
|
||||
else
|
||||
RegMemFun(this, &CMapReader::LoadRMSettings, L"CMapReader::LoadRMSettings", 50);
|
||||
|
||||
// load player settings script (must be done before reading map)
|
||||
RegMemFun(this, &CMapReader::LoadPlayerSettings, L"CMapReader::LoadPlayerSettings", 50);
|
||||
@ -138,7 +142,6 @@ void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_,
|
||||
RegMemFun(this, &CMapReader::DelayLoadFinished, L"CMapReader::DelayLoadFinished", 5);
|
||||
}
|
||||
|
||||
|
||||
// LoadRandomMap: try to load the map data; reinitialise the scene to new data if successful
|
||||
void CMapReader::LoadRandomMap(const CStrW& scriptFile, const CScriptValRooted& settings, CTerrain *pTerrain_,
|
||||
WaterManager* pWaterMan_, SkyManager* pSkyMan_,
|
||||
@ -1196,6 +1199,7 @@ int CMapReader::DelayLoadFinished()
|
||||
int CMapReader::LoadRMSettings()
|
||||
{
|
||||
// copy random map settings over to sim
|
||||
ENSURE(pSimulation2);
|
||||
pSimulation2->SetMapSettings(m_ScriptSettings);
|
||||
|
||||
return 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -53,7 +53,7 @@ public:
|
||||
~CMapReader();
|
||||
|
||||
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
|
||||
void LoadMap(const VfsPath& pathname, CTerrain*, WaterManager*, SkyManager*, CLightEnv*, CGameView*,
|
||||
void LoadMap(const VfsPath& pathname, const CScriptValRooted& settings, CTerrain*, WaterManager*, SkyManager*, CLightEnv*, CGameView*,
|
||||
CCinemaManager*, CTriggerManager*, CPostprocManager* pPostproc, CSimulation2*, const CSimContext*,
|
||||
int playerID, bool skipEntities);
|
||||
|
||||
|
@ -421,7 +421,7 @@ CScriptVal LoadMapSettings(void* cbdata, VfsPath pathname)
|
||||
|
||||
CMapSummaryReader reader;
|
||||
|
||||
if (reader.LoadMap(pathname.ChangeExtension(L".xml")) != PSRETURN_OK)
|
||||
if (reader.LoadMap(pathname) != PSRETURN_OK)
|
||||
return CScriptVal();
|
||||
|
||||
return reader.GetMapSettings(guiManager->GetScriptInterface()).get();
|
||||
|
@ -142,15 +142,7 @@ void CGame::RegisterInit(const CScriptValRooted& attribs, const std::string& sav
|
||||
if (m_GameView)
|
||||
m_GameView->RegisterInit();
|
||||
|
||||
if (mapType == "scenario")
|
||||
{
|
||||
// Load scenario attributes
|
||||
std::wstring mapFile;
|
||||
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "map", mapFile);
|
||||
|
||||
m_World->RegisterInit(mapFile, m_PlayerID);
|
||||
}
|
||||
else if (mapType == "random")
|
||||
if (mapType == "random")
|
||||
{
|
||||
// Load random map attributes
|
||||
std::wstring scriptFile;
|
||||
@ -161,6 +153,16 @@ void CGame::RegisterInit(const CScriptValRooted& attribs, const std::string& sav
|
||||
|
||||
m_World->RegisterInitRMS(scriptFile, settings, m_PlayerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring mapFile;
|
||||
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "map", mapFile);
|
||||
CScriptValRooted settings;
|
||||
if (mapType == "skirmish")
|
||||
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "settings", settings);
|
||||
|
||||
m_World->RegisterInit(mapFile, settings, m_PlayerID);
|
||||
}
|
||||
|
||||
if (m_IsSavedGame)
|
||||
RegMemFun(this, &CGame::LoadInitialState, L"Loading game", 1000);
|
||||
|
@ -1081,6 +1081,7 @@ bool Autostart(const CmdLineArgs& args)
|
||||
* -autostart-ip=127.0.0.1 -- multiplayer connect to 127.0.0.1
|
||||
* -autostart-random=104 -- random map, optional seed value = 104 (default is 0, random is -1)
|
||||
* -autostart-size=192 -- random map size in tiles = 192 (default is 192)
|
||||
* -autostart-civ=1:hele -- set player #1 civ to "hele"
|
||||
*
|
||||
* Examples:
|
||||
* -autostart=Acropolis -autostart-host -autostart-players=2 -- Host game on Acropolis map, 2 players
|
||||
@ -1131,8 +1132,7 @@ bool Autostart(const CmdLineArgs& args)
|
||||
}
|
||||
|
||||
// Random map definition will be loaded from JSON file, so we need to parse it
|
||||
std::wstring mapPath = L"maps/random/";
|
||||
std::wstring scriptPath = mapPath + autoStartName.FromUTF8() + L".json";
|
||||
std::wstring scriptPath = L"maps/random/" + autoStartName.FromUTF8() + L".json";
|
||||
CScriptValRooted scriptData = scriptInterface.ReadJSONFile(scriptPath);
|
||||
if (!scriptData.undefined() && scriptInterface.GetProperty(scriptData.get(), "settings", settings))
|
||||
{
|
||||
@ -1157,7 +1157,6 @@ bool Autostart(const CmdLineArgs& args)
|
||||
}
|
||||
|
||||
scriptInterface.SetProperty(attrs.get(), "map", std::string(autoStartName));
|
||||
scriptInterface.SetProperty(attrs.get(), "mapPath", mapPath);
|
||||
scriptInterface.SetProperty(attrs.get(), "mapType", std::string("random"));
|
||||
scriptInterface.SetProperty(settings.get(), "Seed", seed); // Random seed
|
||||
scriptInterface.SetProperty(settings.get(), "Size", mapSize); // Random map size (in patches)
|
||||
@ -1184,7 +1183,9 @@ bool Autostart(const CmdLineArgs& args)
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptInterface.SetProperty(attrs.get(), "map", std::string(autoStartName));
|
||||
// TODO: support akirmish maps
|
||||
std::string mapFile = "maps/scenarios/" + autoStartName;
|
||||
scriptInterface.SetProperty(attrs.get(), "map", mapFile);
|
||||
scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario"));
|
||||
}
|
||||
|
||||
|
@ -65,19 +65,19 @@ CWorld::CWorld(CGame *pGame):
|
||||
/**
|
||||
* Initializes the game world with the attributes provided.
|
||||
**/
|
||||
void CWorld::RegisterInit(const CStrW& mapFile, int playerID)
|
||||
void CWorld::RegisterInit(const CStrW& mapFile, const CScriptValRooted& settings, int playerID)
|
||||
{
|
||||
// Load the map, if one was specified
|
||||
if (mapFile.length())
|
||||
{
|
||||
VfsPath mapfilename(VfsPath("maps/scenarios") / (mapFile + L".pmp"));
|
||||
VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
|
||||
CMapReader* reader = 0;
|
||||
|
||||
try
|
||||
{
|
||||
reader = new CMapReader;
|
||||
CTriggerManager* pTriggerManager = NULL;
|
||||
reader->LoadMap(mapfilename, m_Terrain,
|
||||
reader->LoadMap(mapfilename, settings, m_Terrain,
|
||||
CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL,
|
||||
CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL,
|
||||
&g_LightEnv, m_pGame->GetView(),
|
||||
@ -89,8 +89,8 @@ void CWorld::RegisterInit(const CStrW& mapFile, int playerID)
|
||||
catch (PSERROR_File& err)
|
||||
{
|
||||
delete reader;
|
||||
LOGERROR(L"Failed to load scenario %ls: %hs", mapfilename.string().c_str(), err.what());
|
||||
throw PSERROR_Game_World_MapLoadFailed("Failed to load scenario.\nCheck application log for details.");
|
||||
LOGERROR(L"Failed to load map %ls: %hs", mapfilename.string().c_str(), err.what());
|
||||
throw PSERROR_Game_World_MapLoadFailed("Failed to load map.\nCheck application log for details.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -73,7 +73,7 @@ public:
|
||||
/*
|
||||
Initialize the World - load the map and all objects
|
||||
*/
|
||||
void RegisterInit(const CStrW& mapFile, int playerID);
|
||||
void RegisterInit(const CStrW& mapFile, const CScriptValRooted& settings, int playerID);
|
||||
|
||||
/*
|
||||
Initialize the World - generate and load the random map
|
||||
|
@ -387,22 +387,20 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
|
||||
// TODO: this duplicates CWorld::RegisterInit and could probably be cleaned up a bit
|
||||
std::string mapType;
|
||||
m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "mapType", mapType);
|
||||
if (mapType == "scenario")
|
||||
{
|
||||
// Load scenario attributes
|
||||
std::wstring mapFile;
|
||||
m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "map", mapFile);
|
||||
|
||||
VfsPath mapfilename(VfsPath("maps/scenarios") / (mapFile + L".pmp"));
|
||||
mapReader->LoadMap(mapfilename, &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure
|
||||
}
|
||||
else
|
||||
if (mapType == "random")
|
||||
{
|
||||
// TODO: support random map scripts
|
||||
debug_warn(L"Serialization test mode only supports scenarios");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring mapFile;
|
||||
m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes.get(), "map", mapFile);
|
||||
|
||||
VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
|
||||
mapReader->LoadMap(mapfilename, CScriptValRooted(), &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure
|
||||
}
|
||||
LDR_EndRegistering();
|
||||
ENSURE(LDR_NonprogressiveLoad() == INFO::OK);
|
||||
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
CMapReader* mapReader = new CMapReader(); // it'll call "delete this" itself
|
||||
|
||||
LDR_BeginRegistering();
|
||||
mapReader->LoadMap(L"maps/scenarios/Median Oasis 01.pmp", &terrain, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
mapReader->LoadMap(L"maps/scenarios/Median Oasis 01.pmp", CScriptValRooted(), &terrain, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&sim2, &sim2.GetSimContext(), -1, false);
|
||||
LDR_EndRegistering();
|
||||
TS_ASSERT_OK(LDR_NonprogressiveLoad());
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "graphics/MapReader.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TerrainTextureManager.h"
|
||||
#include "lib/timer.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Filesystem.h"
|
||||
@ -635,6 +636,12 @@ public:
|
||||
TS_ASSERT_OK(g_VFS->Mount(L"", DataDir()/"mods"/"public", VFS_MOUNT_MUST_EXIST));
|
||||
TS_ASSERT_OK(g_VFS->Mount(L"cache/", DataDir()/"cache"));
|
||||
|
||||
// Need some stuff for terrain movement costs:
|
||||
// (TODO: this ought to be independent of any graphics code)
|
||||
tex_codec_register_all();
|
||||
new CTerrainTextureManager;
|
||||
g_TexMan.LoadTerrainTextures();
|
||||
|
||||
CTerrain terrain;
|
||||
|
||||
CSimulation2 sim2(NULL, &terrain);
|
||||
@ -644,7 +651,7 @@ public:
|
||||
CMapReader* mapReader = new CMapReader(); // it'll call "delete this" itself
|
||||
|
||||
LDR_BeginRegistering();
|
||||
mapReader->LoadMap(L"maps/scenarios/Latium.pmp", &terrain, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
mapReader->LoadMap(L"maps/scenarios/Acropolis 01.pmp", CScriptValRooted(), &terrain, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&sim2, &sim2.GetSimContext(), -1, false);
|
||||
LDR_EndRegistering();
|
||||
TS_ASSERT_OK(LDR_NonprogressiveLoad());
|
||||
@ -677,6 +684,8 @@ public:
|
||||
debug_printf(L"# time = %f (%f/%d)\n", t/reps, t, (int)reps);
|
||||
|
||||
// Shut down the world
|
||||
delete &g_TexMan;
|
||||
tex_codec_unregister_all();
|
||||
g_VFS.reset();
|
||||
CXeromyces::Terminate();
|
||||
}
|
||||
|
@ -0,0 +1,214 @@
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "MapDialog.h"
|
||||
|
||||
#include "GameInterface/MessagePasser.h"
|
||||
#include "GameInterface/Messages.h"
|
||||
|
||||
enum {
|
||||
ID_MapDialogFilename = 1,
|
||||
ID_MapDialogNotebook,
|
||||
ID_ScenarioPage,
|
||||
ID_SkirmishPage
|
||||
};
|
||||
|
||||
static const wxString scenarioPath(L"maps/scenarios/");
|
||||
static const wxString skirmishPath(L"maps/skirmishes/");
|
||||
|
||||
MapDialog::MapDialog(wxWindow* parent, MapDialogType type)
|
||||
: wxDialog(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(600,400), wxCAPTION|wxRESIZE_BORDER|wxCLOSE_BOX|wxSYSTEM_MENU), m_Type(type)
|
||||
{
|
||||
Freeze();
|
||||
|
||||
SetIcon(wxIcon(_T("ICON_ScenarioEditor"))); // load from atlas.rc
|
||||
|
||||
if (m_Type == MAPDIALOG_OPEN)
|
||||
SetTitle(_("Choose map to open"));
|
||||
else // MAPDIALOG_SAVE
|
||||
SetTitle(_("Choose map to save"));
|
||||
|
||||
AtlasMessage::qGetMapList qry;
|
||||
qry.Post();
|
||||
|
||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxNotebook* notebook = new wxNotebook(this, ID_MapDialogNotebook);
|
||||
{
|
||||
wxPanel* page = new wxPanel(notebook, ID_ScenarioPage);
|
||||
wxSizer* pageSizer = new wxBoxSizer(wxVERTICAL);
|
||||
// TODO: Should display something nicer than raw VFS paths
|
||||
wxListBox* listBox = new wxListBox(page, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL);
|
||||
const std::vector<std::wstring>& scenarioFilenames = *qry.scenarioFilenames;
|
||||
for (size_t i = 0; i < scenarioFilenames.size(); ++i)
|
||||
{
|
||||
wxString name = scenarioFilenames[i].substr(scenarioPath.Length());
|
||||
listBox->Append(name, new wxStringClientData(scenarioFilenames[i]));
|
||||
}
|
||||
|
||||
pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand().Align(wxBOTTOM));
|
||||
page->SetSizer(pageSizer);
|
||||
notebook->AddPage(page, _("Scenarios"));
|
||||
}
|
||||
{
|
||||
wxPanel* page = new wxPanel(notebook, ID_SkirmishPage);
|
||||
wxSizer* pageSizer = new wxBoxSizer(wxVERTICAL);
|
||||
// TODO: Should display something nicer than raw VFS paths
|
||||
wxListBox* listBox = new wxListBox(page, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL);
|
||||
const std::vector<std::wstring>& skirmishFilenames = *qry.skirmishFilenames;
|
||||
for (size_t i = 0; i < skirmishFilenames.size(); ++i)
|
||||
{
|
||||
wxString name = skirmishFilenames[i].substr(skirmishPath.Length());
|
||||
listBox->Append(name, new wxStringClientData(skirmishFilenames[i]));
|
||||
}
|
||||
|
||||
pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand());
|
||||
page->SetSizer(pageSizer);
|
||||
notebook->AddPage(page, _("Skirmishes"));
|
||||
}
|
||||
|
||||
notebook->SetSelection(0);
|
||||
|
||||
sizer->Add(notebook, wxSizerFlags().Proportion(1).Expand());
|
||||
|
||||
sizer->AddSpacer(5);
|
||||
|
||||
wxSizer* filenameSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
filenameSizer->AddSpacer(10);
|
||||
filenameSizer->Add(new wxStaticText(this, wxID_ANY, _("Map name: ")), wxSizerFlags().Align(wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL));
|
||||
wxTextCtrl* filename = new wxTextCtrl(this, ID_MapDialogFilename, wxEmptyString);
|
||||
if (m_Type == MAPDIALOG_OPEN)
|
||||
filename->Disable();
|
||||
filenameSizer->Add(filename, wxSizerFlags().Proportion(1).Expand());
|
||||
sizer->Add(filenameSizer, wxSizerFlags().Expand());
|
||||
|
||||
sizer->AddSpacer(20);
|
||||
|
||||
wxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
if (m_Type == MAPDIALOG_OPEN)
|
||||
buttonSizer->Add(new wxButton(this, wxID_OPEN, _("Open")));
|
||||
else // MAPDIALOG_SAVE
|
||||
buttonSizer->Add(new wxButton(this, wxID_SAVE, _("Save")));
|
||||
buttonSizer->AddSpacer(5);
|
||||
buttonSizer->Add(new wxButton(this, wxID_CANCEL, _("Cancel")));
|
||||
|
||||
sizer->Add(buttonSizer, wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxRIGHT|wxBOTTOM, 10));
|
||||
|
||||
SetSizer(sizer);
|
||||
|
||||
Layout();
|
||||
Thaw();
|
||||
}
|
||||
|
||||
wxString MapDialog::GetFilename() const
|
||||
{
|
||||
wxFileName filename(m_Filename, wxPATH_UNIX);
|
||||
filename.SetExt(L"xml");
|
||||
if (m_SelectedPage == 0)
|
||||
return scenarioPath + filename.GetFullPath(wxPATH_UNIX);
|
||||
else if (m_SelectedPage == 1)
|
||||
return skirmishPath + filename.GetFullPath(wxPATH_UNIX);
|
||||
else
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
void MapDialog::OnListBox(wxCommandEvent& evt)
|
||||
{
|
||||
if (evt.GetInt() < 0)
|
||||
m_Filename = wxEmptyString;
|
||||
else
|
||||
m_Filename = evt.GetString();
|
||||
|
||||
wxDynamicCast(FindWindow(ID_MapDialogFilename), wxTextCtrl)->ChangeValue(m_Filename);
|
||||
|
||||
if (evt.GetEventType() == wxEVT_COMMAND_LISTBOX_DOUBLECLICKED)
|
||||
{
|
||||
if (m_Type == MAPDIALOG_OPEN)
|
||||
OpenFile();
|
||||
else
|
||||
SaveFile();
|
||||
}
|
||||
}
|
||||
|
||||
void MapDialog::OnCancel(wxCommandEvent& WXUNUSED(evt))
|
||||
{
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
void MapDialog::OnOpen(wxCommandEvent& WXUNUSED(evt))
|
||||
{
|
||||
OpenFile();
|
||||
}
|
||||
|
||||
void MapDialog::OnSave(wxCommandEvent& WXUNUSED(evt))
|
||||
{
|
||||
SaveFile();
|
||||
}
|
||||
|
||||
void MapDialog::OnFilename(wxCommandEvent& evt)
|
||||
{
|
||||
m_Filename = evt.GetString();
|
||||
}
|
||||
|
||||
void MapDialog::OnNotebookChanged(wxNotebookEvent& evt)
|
||||
{
|
||||
m_SelectedPage = evt.GetSelection();
|
||||
}
|
||||
|
||||
void MapDialog::OpenFile()
|
||||
{
|
||||
wxString filename = GetFilename();
|
||||
if (filename.empty())
|
||||
return;
|
||||
|
||||
AtlasMessage::qVFSFileExists qry(filename.wc_str());
|
||||
qry.Post();
|
||||
if (!qry.exists)
|
||||
return;
|
||||
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void MapDialog::SaveFile()
|
||||
{
|
||||
wxString filename = GetFilename();
|
||||
if (filename.empty())
|
||||
return;
|
||||
|
||||
// TODO: this test would work better outside the VFS
|
||||
AtlasMessage::qVFSFileExists qry(filename.wc_str());
|
||||
qry.Post();
|
||||
if (qry.exists)
|
||||
{
|
||||
if (wxMessageBox(_("WARNING: '") + filename + _("' already exists, it may be overwritten. Continue?"), _("Overwrite map confirmation"), wxICON_EXCLAMATION | wxYES_NO) != wxYES)
|
||||
return;
|
||||
}
|
||||
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(MapDialog, wxDialog)
|
||||
EVT_BUTTON (wxID_CANCEL, MapDialog::OnCancel)
|
||||
EVT_BUTTON (wxID_OPEN, MapDialog::OnOpen)
|
||||
EVT_BUTTON (wxID_SAVE, MapDialog::OnSave)
|
||||
EVT_LISTBOX (wxID_ANY, MapDialog::OnListBox)
|
||||
EVT_LISTBOX_DCLICK (wxID_ANY, MapDialog::OnListBox)
|
||||
EVT_TEXT (ID_MapDialogFilename, MapDialog::OnFilename)
|
||||
EVT_NOTEBOOK_PAGE_CHANGED (ID_MapDialogNotebook, MapDialog::OnNotebookChanged)
|
||||
END_EVENT_TABLE()
|
@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_MAPDIALOG
|
||||
#define INCLUDED_MAPDIALOG
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
enum MapDialogType { MAPDIALOG_OPEN, MAPDIALOG_SAVE };
|
||||
|
||||
class MapDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
MapDialog(wxWindow* parent, MapDialogType type);
|
||||
|
||||
/**
|
||||
* Returns VFS path of selected map with .xml extension, else empty string
|
||||
*/
|
||||
wxString GetFilename() const;
|
||||
|
||||
private:
|
||||
|
||||
void OnCancel(wxCommandEvent& evt);
|
||||
void OnOpen(wxCommandEvent& evt);
|
||||
void OnSave(wxCommandEvent& evt);
|
||||
void OnListBox(wxCommandEvent& evt);
|
||||
void OnFilename(wxCommandEvent& evt);
|
||||
void OnNotebookChanged(wxNotebookEvent& evt);
|
||||
|
||||
void OpenFile();
|
||||
void SaveFile();
|
||||
|
||||
wxArrayString m_MapFilenames;
|
||||
wxString m_Filename;
|
||||
MapDialogType m_Type;
|
||||
int m_SelectedPage;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
#endif // INCLUDED_MAPDIALOG
|
@ -35,6 +35,7 @@
|
||||
#include "CustomControls/Buttons/ToolButton.h"
|
||||
#include "CustomControls/Canvas/Canvas.h"
|
||||
#include "CustomControls/HighResTimer/HighResTimer.h"
|
||||
#include "CustomControls/MapDialog/MapDialog.h"
|
||||
|
||||
#include "GameInterface/MessagePasser.h"
|
||||
#include "GameInterface/Messages.h"
|
||||
@ -521,7 +522,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac
|
||||
|
||||
// Start with a blank map (so that the editor can assume there's always
|
||||
// a valid map loaded)
|
||||
POST_MESSAGE(LoadMap, (_T("_default")));
|
||||
POST_MESSAGE(LoadMap, (_T("maps/scenarios/_default.xml")));
|
||||
POST_MESSAGE(SimPlay, (0.f, false));
|
||||
|
||||
// Select the initial sidebar (after the map has loaded)
|
||||
@ -626,7 +627,7 @@ void ScenarioEditor::OnRedo(wxCommandEvent&)
|
||||
void ScenarioEditor::OnNew(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (wxMessageBox(_("Discard current map and start blank new map?"), _("New map"), wxOK|wxCANCEL|wxICON_QUESTION, this) == wxOK)
|
||||
OpenFile(_T("_default"), _T(""));
|
||||
OpenFile(_T(""), _T("maps/scenarios/_default.xml"));
|
||||
}
|
||||
|
||||
bool ScenarioEditor::OpenFile(const wxString& name, const wxString& filename)
|
||||
@ -634,48 +635,20 @@ bool ScenarioEditor::OpenFile(const wxString& name, const wxString& filename)
|
||||
wxBusyInfo busy(_("Loading ") + name);
|
||||
wxBusyCursor busyc;
|
||||
|
||||
wxString mapPath(_T("maps/scenarios/"));
|
||||
wxFileName fullFilename(filename);
|
||||
|
||||
// For compatibility it's still possible to load xml maps but in that case,
|
||||
// we want a blank filename so that we're forced to Save As
|
||||
if (filename.IsEmpty() || fullFilename.GetExt().IsSameAs(_T("xml"), false))
|
||||
{
|
||||
fullFilename = _T("");
|
||||
}
|
||||
else
|
||||
{ // force extension to pmp
|
||||
fullFilename.SetExt(_T("pmp"));
|
||||
|
||||
// check if pmp exists
|
||||
qVFSFileExists qry(std::wstring((mapPath + fullFilename.GetFullName()).wc_str()));
|
||||
AtlasMessage::qVFSFileExists qry(filename.wc_str());
|
||||
qry.Post();
|
||||
if (!qry.exists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Every map requires an xml file, so check that it exists
|
||||
wxFileName xmlName(name);
|
||||
xmlName.SetExt(_T("xml"));
|
||||
qVFSFileExists qry(std::wstring((mapPath + xmlName.GetFullName()).wc_str()));
|
||||
qry.Post();
|
||||
if (!qry.exists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deactivate tools, so they don't carry forwards into the new CWorld
|
||||
// and crash.
|
||||
m_ToolManager.SetCurrentTool(_T(""));
|
||||
// TODO: clear the undo buffer, etc
|
||||
|
||||
// TODO: Work when the map is not in .../maps/scenarios/
|
||||
std::wstring map(name.wc_str());
|
||||
std::wstring map(filename.wc_str());
|
||||
POST_MESSAGE(LoadMap, (map));
|
||||
|
||||
SetOpenFilename(fullFilename.GetFullName());
|
||||
SetOpenFilename(name);
|
||||
|
||||
{ // Wait for it to load, while the wxBusyInfo is telling the user that we're doing that
|
||||
qPing qry;
|
||||
@ -692,27 +665,12 @@ bool ScenarioEditor::OpenFile(const wxString& name, const wxString& filename)
|
||||
|
||||
void ScenarioEditor::OnOpen(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFileDialog dlg (NULL, wxFileSelectorPromptStr,
|
||||
Datafile::GetDataDirectory() + _T("/mods/public/maps/scenarios"), m_OpenFilename,
|
||||
_T("PMP files (*.pmp)|*.pmp|All files (*.*)|*.*"),
|
||||
wxFD_OPEN);
|
||||
// Set default filter
|
||||
dlg.SetFilterIndex(0);
|
||||
|
||||
wxString cwd = wxFileName::GetCwd();
|
||||
|
||||
MapDialog dlg (NULL, MAPDIALOG_OPEN);
|
||||
if (dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
// TODO: Handle maps in subdirectories of maps/scenarios
|
||||
wxFileName filename(dlg.GetFilename());
|
||||
if (!OpenFile(filename.GetName(), filename.GetFullName()))
|
||||
{
|
||||
wxLogError(_("Map '%ls' does not exist"), filename.GetName().c_str());
|
||||
}
|
||||
|
||||
// paranoia - MSDN says OFN_NOCHANGEDIR (used when we don't give wxCHANGE_DIR)
|
||||
// "is ineffective for GetOpenFileName", but it seems to work anyway
|
||||
wxCHECK_RET(cwd == wxFileName::GetCwd(), _T("cwd changed"));
|
||||
wxString filename = dlg.GetFilename();
|
||||
if (!OpenFile(filename, filename))
|
||||
wxLogError(_("Map '%ls' does not exist"), filename.c_str());
|
||||
}
|
||||
|
||||
// TODO: Make this a non-undoable command
|
||||
@ -727,12 +685,10 @@ void ScenarioEditor::OnImportHeightmap(wxCommandEvent& WXUNUSED(event))
|
||||
// Set default filter
|
||||
dlg.SetFilterIndex(0);
|
||||
|
||||
wxString cwd = wxFileName::GetCwd();
|
||||
|
||||
if (dlg.ShowModal() != wxID_OK)
|
||||
return;
|
||||
|
||||
OpenFile(_T("_default"), _T(""));
|
||||
OpenFile(_T(""), _T("maps/scenarios/_default.xml"));
|
||||
|
||||
std::wstring image(dlg.GetPath().wc_str());
|
||||
POST_MESSAGE(ImportHeightmap, (image));
|
||||
@ -744,8 +700,16 @@ void ScenarioEditor::OnMRUFile(wxCommandEvent& event)
|
||||
{
|
||||
wxString filename(m_FileHistory.GetHistoryFile(event.GetId() - wxID_FILE1));
|
||||
|
||||
// Handle old MRU filenames
|
||||
if (filename.Mid(0, 5) != _T("maps/"))
|
||||
{
|
||||
filename = L"maps/scenarios/" + filename;
|
||||
m_FileHistory.RemoveFileFromHistory(event.GetId() - wxID_FILE1);
|
||||
}
|
||||
|
||||
if (!OpenFile(filename, filename))
|
||||
{ // Missing or invalid - warn and remove from MRU
|
||||
{
|
||||
// Missing or invalid - warn and remove from MRU
|
||||
wxLogError(_("Map '%ls' does not exist"), filename.c_str());
|
||||
m_FileHistory.RemoveFileFromHistory(event.GetId() - wxID_FILE1);
|
||||
}
|
||||
@ -767,7 +731,6 @@ void ScenarioEditor::OnSave(wxCommandEvent& event)
|
||||
// the preview units.)
|
||||
m_ToolManager.SetCurrentTool(_T(""));
|
||||
|
||||
// TODO: Handle maps in subdirectories of maps/scenarios
|
||||
std::wstring map(m_OpenFilename.wc_str());
|
||||
POST_MESSAGE(SaveMap, (map));
|
||||
|
||||
@ -779,35 +742,19 @@ void ScenarioEditor::OnSave(wxCommandEvent& event)
|
||||
|
||||
void ScenarioEditor::OnSaveAs(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFileDialog dlg (NULL, wxFileSelectorPromptStr,
|
||||
Datafile::GetDataDirectory() + _T("/mods/public/maps/scenarios"), m_OpenFilename,
|
||||
_T("PMP files (*.pmp)|*.pmp|All files (*.*)|*.*"),
|
||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||
// Set default filter
|
||||
dlg.SetFilterIndex(0);
|
||||
|
||||
MapDialog dlg(NULL, MAPDIALOG_SAVE);
|
||||
if (dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
// On wxMSW the extension is automatically set to pmp if that filter is selected
|
||||
// but not on wxGTK or wxOSX. Set it explicitly since it's the only possible format.
|
||||
wxFileName filename(dlg.GetFilename());
|
||||
filename.SetExt(_T("pmp"));
|
||||
if (!filename.IsOk())
|
||||
{ // Shouldn't happen
|
||||
wxLogError(_("Invalid filename '%ls'"), filename.GetFullName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
wxBusyInfo busy(_("Saving ") + filename.GetFullName());
|
||||
wxString filename(dlg.GetFilename());
|
||||
wxBusyInfo busy(_("Saving ") + filename);
|
||||
wxBusyCursor busyc;
|
||||
|
||||
m_ToolManager.SetCurrentTool(_T(""));
|
||||
|
||||
// TODO: Handle maps in subdirectories of maps/scenarios
|
||||
std::wstring map(filename.GetFullName().wc_str());
|
||||
std::wstring map(filename.wc_str());
|
||||
POST_MESSAGE(SaveMap, (map));
|
||||
|
||||
SetOpenFilename(filename.GetFullName());
|
||||
SetOpenFilename(filename);
|
||||
|
||||
// Wait for it to finish saving
|
||||
qPing qry;
|
||||
|
@ -34,9 +34,10 @@ enum
|
||||
ID_MapDescription,
|
||||
ID_MapReveal,
|
||||
ID_MapType,
|
||||
ID_MapPreview,
|
||||
ID_MapTeams,
|
||||
ID_MapKW_Demo,
|
||||
ID_MapKW_Hidden,
|
||||
ID_MapKW_Naval,
|
||||
ID_RandomScript,
|
||||
ID_RandomSize,
|
||||
ID_RandomSeed,
|
||||
@ -109,6 +110,7 @@ private:
|
||||
BEGIN_EVENT_TABLE(MapSettingsControl, wxPanel)
|
||||
EVT_TEXT(ID_MapName, MapSettingsControl::OnEdit)
|
||||
EVT_TEXT(ID_MapDescription, MapSettingsControl::OnEdit)
|
||||
EVT_TEXT(ID_MapPreview, MapSettingsControl::OnEdit)
|
||||
EVT_CHECKBOX(wxID_ANY, MapSettingsControl::OnEdit)
|
||||
EVT_CHOICE(wxID_ANY, MapSettingsControl::OnEdit)
|
||||
END_EVENT_TABLE();
|
||||
@ -147,6 +149,10 @@ void MapSettingsControl::CreateWidgets()
|
||||
|
||||
wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
gridSizer->AddGrowableCol(1);
|
||||
// TODO: have preview selector tool?
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Preview")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(new wxTextCtrl(this, ID_MapPreview, wxEmptyString),
|
||||
_("Texture used for map preview")), wxSizerFlags().Expand());
|
||||
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")));
|
||||
@ -161,12 +167,12 @@ void MapSettingsControl::CreateWidgets()
|
||||
sizer->AddSpacer(5);
|
||||
|
||||
wxStaticBoxSizer* keywordsSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Keywords"));
|
||||
wxFlexGridSizer* kwGridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
wxFlexGridSizer* kwGridSizer = new wxFlexGridSizer(4, 5, 5);
|
||||
kwGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Demo")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
kwGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_MapKW_Demo, wxEmptyString),
|
||||
_("If checked, map will only be visible using filters in game setup")));
|
||||
kwGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Hidden")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
kwGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_MapKW_Hidden, wxEmptyString),
|
||||
kwGridSizer->Add(new wxStaticText(this, wxID_ANY, _("Naval")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
kwGridSizer->Add(Tooltipped(new wxCheckBox(this, ID_MapKW_Naval, wxEmptyString),
|
||||
_("If checked, map will only be visible using filters in game setup")));
|
||||
keywordsSizer->Add(kwGridSizer);
|
||||
sizer->Add(keywordsSizer, wxSizerFlags().Expand());
|
||||
@ -188,6 +194,9 @@ void MapSettingsControl::ReadFromEngine()
|
||||
// map description
|
||||
wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Description"]));
|
||||
|
||||
// map preview
|
||||
wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->ChangeValue(wxString(m_MapSettings["Preview"]));
|
||||
|
||||
// reveal map
|
||||
wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->SetValue(wxString(m_MapSettings["RevealMap"]) == L"true");
|
||||
|
||||
@ -207,7 +216,7 @@ void MapSettingsControl::ReadFromEngine()
|
||||
m_MapSettingsKeywords.insert(std::wstring(keyword));
|
||||
|
||||
wxDynamicCast(FindWindow(ID_MapKW_Demo), wxCheckBox)->SetValue(m_MapSettingsKeywords.count(L"demo") != 0);
|
||||
wxDynamicCast(FindWindow(ID_MapKW_Hidden), wxCheckBox)->SetValue(m_MapSettingsKeywords.count(L"hidden") != 0);
|
||||
wxDynamicCast(FindWindow(ID_MapKW_Naval), wxCheckBox)->SetValue(m_MapSettingsKeywords.count(L"naval") != 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,6 +236,9 @@ AtObj MapSettingsControl::UpdateSettingsObject()
|
||||
// map description
|
||||
m_MapSettings.set("Description", wxDynamicCast(FindWindow(ID_MapDescription), wxTextCtrl)->GetValue());
|
||||
|
||||
// map preview
|
||||
m_MapSettings.set("Preview", wxDynamicCast(FindWindow(ID_MapPreview), wxTextCtrl)->GetValue());
|
||||
|
||||
// reveal map
|
||||
m_MapSettings.setBool("RevealMap", wxDynamicCast(FindWindow(ID_MapReveal), wxCheckBox)->GetValue());
|
||||
|
||||
@ -240,10 +252,10 @@ AtObj MapSettingsControl::UpdateSettingsObject()
|
||||
else
|
||||
m_MapSettingsKeywords.erase(L"demo");
|
||||
|
||||
if (wxDynamicCast(FindWindow(ID_MapKW_Hidden), wxCheckBox)->GetValue())
|
||||
m_MapSettingsKeywords.insert(L"hidden");
|
||||
if (wxDynamicCast(FindWindow(ID_MapKW_Naval), wxCheckBox)->GetValue())
|
||||
m_MapSettingsKeywords.insert(L"naval");
|
||||
else
|
||||
m_MapSettingsKeywords.erase(L"hidden");
|
||||
m_MapSettingsKeywords.erase(L"naval");
|
||||
|
||||
AtObj keywords;
|
||||
keywords.set("@array", L"");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -35,8 +35,18 @@ enum
|
||||
ID_PlayerStone,
|
||||
ID_PlayerPop,
|
||||
ID_PlayerColour,
|
||||
ID_PlayerHuman,
|
||||
ID_PlayerAI,
|
||||
|
||||
ID_DefaultName,
|
||||
ID_DefaultCiv,
|
||||
ID_DefaultColour,
|
||||
ID_DefaultAI,
|
||||
ID_DefaultFood,
|
||||
ID_DefaultWood,
|
||||
ID_DefaultMetal,
|
||||
ID_DefaultStone,
|
||||
ID_DefaultPop,
|
||||
ID_DefaultTeam,
|
||||
|
||||
ID_CameraSet,
|
||||
ID_CameraView,
|
||||
ID_CameraClear
|
||||
@ -54,6 +64,39 @@ static wxWindow* Tooltipped(wxWindow* window, const wxString& tip)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DefaultCheckbox : public wxCheckBox
|
||||
{
|
||||
public:
|
||||
DefaultCheckbox(wxWindow* parent, wxWindowID id, wxWindow* control, bool initialValue = false)
|
||||
: wxCheckBox(parent, id, wxEmptyString), m_Control(control)
|
||||
{
|
||||
SetValue(initialValue);
|
||||
}
|
||||
|
||||
virtual void SetValue(bool value)
|
||||
{
|
||||
m_Control->Enable(value);
|
||||
wxCheckBox::SetValue(value);
|
||||
}
|
||||
|
||||
void OnChecked(wxCommandEvent& evt)
|
||||
{
|
||||
m_Control->Enable(evt.IsChecked());
|
||||
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
private:
|
||||
wxWindow* m_Control;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(DefaultCheckbox, wxCheckBox)
|
||||
EVT_CHECKBOX(wxID_ANY, DefaultCheckbox::OnChecked)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
|
||||
class PlayerNotebookPage : public wxPanel
|
||||
{
|
||||
|
||||
@ -73,25 +116,33 @@ public:
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Player Info
|
||||
wxStaticBoxSizer* playerInfoSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Player info"));
|
||||
wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
gridSizer->AddGrowableCol(1);
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Name")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
wxFlexGridSizer* gridSizer = new wxFlexGridSizer(3, 5, 5);
|
||||
gridSizer->AddGrowableCol(2);
|
||||
|
||||
wxTextCtrl* nameCtrl = new wxTextCtrl(this, wxID_ANY);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultName, nameCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Name")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(nameCtrl, wxSizerFlags(1).Expand().Align(wxALIGN_RIGHT));
|
||||
m_Controls.name = nameCtrl;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Civilisation")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxChoice* civChoice = new wxChoice(this, wxID_ANY);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultCiv, civChoice), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Civilisation")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(civChoice, wxSizerFlags(1).Expand().Align(wxALIGN_RIGHT));
|
||||
m_Controls.civ = civChoice;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Colour")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxButton* colourButton = new wxButton(this, ID_PlayerColour);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultColour, colourButton), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Colour")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(colourButton,
|
||||
_("Set player colour")), wxSizerFlags(1).Expand().Align(wxALIGN_RIGHT));
|
||||
m_Controls.colour = colourButton;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Default AI")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxChoice* aiChoice = new wxChoice(this, wxID_ANY);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultAI, aiChoice), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("AI")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(aiChoice,
|
||||
_("Select default AI")), wxSizerFlags(1).Expand().Align(wxALIGN_RIGHT));
|
||||
_("Select AI")), wxSizerFlags(1).Expand().Align(wxALIGN_RIGHT));
|
||||
m_Controls.ai = aiChoice;
|
||||
|
||||
playerInfoSizer->Add(gridSizer, wxSizerFlags(1).Expand());
|
||||
@ -102,30 +153,40 @@ public:
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Resources
|
||||
wxStaticBoxSizer* resourceSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Resources"));
|
||||
wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
gridSizer->AddGrowableCol(1);
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Food")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
wxFlexGridSizer* gridSizer = new wxFlexGridSizer(3, 5, 5);
|
||||
gridSizer->AddGrowableCol(2);
|
||||
|
||||
wxSpinCtrl* foodCtrl = new wxSpinCtrl(this, ID_PlayerFood, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, INT_MAX);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultFood, foodCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Food")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(foodCtrl,
|
||||
_("Initial value of food resource")), wxSizerFlags().Expand());
|
||||
m_Controls.food = foodCtrl;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Wood")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxSpinCtrl* woodCtrl = new wxSpinCtrl(this, ID_PlayerWood, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, INT_MAX);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultWood, woodCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Wood")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(woodCtrl,
|
||||
_("Initial value of wood resource")), wxSizerFlags().Expand());
|
||||
m_Controls.wood = woodCtrl;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Metal")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxSpinCtrl* metalCtrl = new wxSpinCtrl(this, ID_PlayerMetal, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, INT_MAX);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultMetal, metalCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Metal")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(metalCtrl,
|
||||
_("Initial value of metal resource")), wxSizerFlags().Expand());
|
||||
m_Controls.metal = metalCtrl;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Stone")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxSpinCtrl* stoneCtrl = new wxSpinCtrl(this, ID_PlayerStone, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, INT_MAX);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultStone, stoneCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Stone")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(stoneCtrl,
|
||||
_("Initial value of stone resource")), wxSizerFlags().Expand());
|
||||
m_Controls.stone = stoneCtrl;
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Pop limit")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
|
||||
wxSpinCtrl* popCtrl = new wxSpinCtrl(this, ID_PlayerPop, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, INT_MAX);
|
||||
gridSizer->Add(new DefaultCheckbox(this, ID_DefaultPop, popCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Pop limit")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
gridSizer->Add(Tooltipped(popCtrl,
|
||||
_("Population limit for this player")), wxSizerFlags().Expand());
|
||||
m_Controls.pop = popCtrl;
|
||||
@ -138,8 +199,11 @@ public:
|
||||
// Diplomacy
|
||||
wxStaticBoxSizer* diplomacySizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Diplomacy"));
|
||||
wxBoxSizer* boxSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
boxSizer->Add(new wxStaticText(this, wxID_ANY, _("Team")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
wxChoice* teamCtrl = new wxChoice(this, wxID_ANY);
|
||||
boxSizer->Add(new DefaultCheckbox(this, ID_DefaultTeam, teamCtrl), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
boxSizer->AddSpacer(5);
|
||||
boxSizer->Add(new wxStaticText(this, wxID_ANY, _("Team")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT));
|
||||
boxSizer->AddSpacer(5);
|
||||
teamCtrl->Append(_("None"));
|
||||
teamCtrl->Append(_T("1"));
|
||||
teamCtrl->Append(_T("2"));
|
||||
@ -479,6 +543,7 @@ BEGIN_EVENT_TABLE(PlayerSettingsControl, wxPanel)
|
||||
EVT_BUTTON(ID_PlayerColour, PlayerSettingsControl::OnPlayerColour)
|
||||
EVT_BUTTON(ID_CameraSet, PlayerSettingsControl::OnEdit)
|
||||
EVT_BUTTON(ID_CameraClear, PlayerSettingsControl::OnEdit)
|
||||
EVT_CHECKBOX(wxID_ANY, PlayerSettingsControl::OnEdit)
|
||||
EVT_CHOICE(wxID_ANY, PlayerSettingsControl::OnEdit)
|
||||
EVT_TEXT(ID_NumPlayers, PlayerSettingsControl::OnNumPlayersText)
|
||||
EVT_TEXT(wxID_ANY, PlayerSettingsControl::OnEdit)
|
||||
@ -596,7 +661,8 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
m_MapSettings = AtlasObject::LoadFromJSON(m_ScenarioEditor.GetScriptInterface().GetContext(), *qry.settings);
|
||||
}
|
||||
else
|
||||
{ // Use blank object, it will be created next
|
||||
{
|
||||
// Use blank object, it will be created next
|
||||
m_MapSettings = AtObj();
|
||||
}
|
||||
|
||||
@ -607,9 +673,7 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
m_NumPlayers = MAX_NUM_PLAYERS;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NumPlayers = player.count();
|
||||
}
|
||||
|
||||
wxASSERT(m_NumPlayers <= MAX_NUM_PLAYERS && m_NumPlayers != 0);
|
||||
|
||||
@ -628,21 +692,24 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
|
||||
for (size_t i = 0; i < MAX_NUM_PLAYERS; ++i)
|
||||
{
|
||||
PlayerPageControls controls = m_PlayerControls[i];
|
||||
const PlayerPageControls& controls = m_PlayerControls[i];
|
||||
|
||||
// name
|
||||
wxString name(_("Unknown"));
|
||||
if (player["Name"].defined())
|
||||
bool defined = player["Name"].defined();
|
||||
if (defined)
|
||||
name = wxString(player["Name"]);
|
||||
else if (playerDefs["Name"].defined())
|
||||
name = wxString(playerDefs["Name"]);
|
||||
|
||||
controls.name->SetValue(name);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultName, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// civ
|
||||
wxChoice* choice = controls.civ;
|
||||
wxString civCode;
|
||||
if (player["Civ"].defined())
|
||||
defined = player["Civ"].defined();
|
||||
if (defined)
|
||||
civCode = wxString(player["Civ"]);
|
||||
else
|
||||
civCode = wxString(playerDefs["Civ"]);
|
||||
@ -656,31 +723,30 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
break;
|
||||
}
|
||||
}
|
||||
wxDynamicCast(FindWindowById(ID_DefaultCiv, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// colour
|
||||
wxColour colour;
|
||||
AtObj clrObj = *player["Colour"];
|
||||
if (clrObj.defined())
|
||||
{
|
||||
colour = wxColor((*clrObj["r"]).getInt(), (*clrObj["g"]).getInt(), (*clrObj["b"]).getInt());
|
||||
}
|
||||
else
|
||||
{
|
||||
defined = clrObj.defined();
|
||||
if (!defined)
|
||||
clrObj = *playerDefs["Colour"];
|
||||
colour = wxColor((*clrObj["r"]).getInt(), (*clrObj["g"]).getInt(), (*clrObj["b"]).getInt());
|
||||
}
|
||||
controls.colour->SetBackgroundColour(colour);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultColour, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// player type
|
||||
wxString aiID;
|
||||
if (player["AI"].defined())
|
||||
defined = player["AI"].defined();
|
||||
if (defined)
|
||||
aiID = wxString(player["AI"]);
|
||||
else
|
||||
aiID = wxString(playerDefs["AI"]);
|
||||
|
||||
choice = controls.ai;
|
||||
if (!aiID.empty())
|
||||
{ // AI
|
||||
{
|
||||
// AI
|
||||
for (size_t j = 0; j < choice->GetCount(); ++j)
|
||||
{
|
||||
wxStringClientData* str = dynamic_cast<wxStringClientData*>(choice->GetClientObject(j));
|
||||
@ -691,44 +757,55 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Human
|
||||
else // Human
|
||||
choice->SetSelection(0);
|
||||
}
|
||||
wxDynamicCast(FindWindowById(ID_DefaultAI, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// resources
|
||||
AtObj resObj = *player["Resources"];
|
||||
if (resObj.defined() && resObj["food"].defined())
|
||||
defined = resObj.defined() && resObj["food"].defined();
|
||||
if (defined)
|
||||
controls.food->SetValue(wxString(resObj["food"]));
|
||||
else
|
||||
controls.food->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultFood, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
if (resObj.defined() && resObj["wood"].defined())
|
||||
defined = resObj.defined() && resObj["wood"].defined();
|
||||
if (defined)
|
||||
controls.wood->SetValue(wxString(resObj["wood"]));
|
||||
else
|
||||
controls.wood->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultWood, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
if (resObj.defined() && resObj["metal"].defined())
|
||||
defined = resObj.defined() && resObj["metal"].defined();
|
||||
if (defined)
|
||||
controls.metal->SetValue(wxString(resObj["metal"]));
|
||||
else
|
||||
controls.metal->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultMetal, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
if (resObj.defined() && resObj["stone"].defined())
|
||||
defined = resObj.defined() && resObj["stone"].defined();
|
||||
if (defined)
|
||||
controls.stone->SetValue(wxString(resObj["stone"]));
|
||||
else
|
||||
controls.stone->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultStone, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// population limit
|
||||
if (player["PopulationLimit"].defined())
|
||||
defined = player["PopulationLimit"].defined();
|
||||
if (defined)
|
||||
controls.pop->SetValue(wxString(player["PopulationLimit"]));
|
||||
else
|
||||
controls.pop->SetValue(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultPop, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// team
|
||||
if (player["Team"].defined())
|
||||
defined = player["Team"].defined();
|
||||
if (defined)
|
||||
controls.team->SetSelection((*player["Team"]).getInt() + 1);
|
||||
else
|
||||
controls.team->SetSelection(0);
|
||||
wxDynamicCast(FindWindowById(ID_DefaultTeam, controls.page), DefaultCheckbox)->SetValue(defined);
|
||||
|
||||
// camera
|
||||
if (player["StartingCamera"].defined())
|
||||
@ -767,7 +844,6 @@ void PlayerSettingsControl::ReadFromEngine()
|
||||
AtObj PlayerSettingsControl::UpdateSettingsObject()
|
||||
{
|
||||
// Update player data in the map settings
|
||||
AtIter oldPlayer = m_MapSettings["PlayerData"]["item"];
|
||||
AtObj players;
|
||||
players.set("@array", L"");
|
||||
|
||||
@ -777,66 +853,67 @@ AtObj PlayerSettingsControl::UpdateSettingsObject()
|
||||
{
|
||||
PlayerPageControls controls = m_PlayerControls[i];
|
||||
|
||||
AtObj player = *oldPlayer;
|
||||
AtObj player;
|
||||
|
||||
// name
|
||||
wxTextCtrl* text = controls.name;
|
||||
if (!text->GetValue().empty())
|
||||
{
|
||||
if (text->IsEnabled())
|
||||
player.set("Name", text->GetValue());
|
||||
}
|
||||
|
||||
// civ
|
||||
wxChoice* choice = controls.civ;
|
||||
if (choice->GetSelection() >= 0)
|
||||
if (choice->IsEnabled() && choice->GetSelection() >= 0)
|
||||
{
|
||||
wxStringClientData* str = dynamic_cast<wxStringClientData*>(choice->GetClientObject(choice->GetSelection()));
|
||||
player.set("Civ", str->GetData());
|
||||
}
|
||||
|
||||
// colour
|
||||
if (controls.colour->IsEnabled())
|
||||
{
|
||||
wxColour colour = controls.colour->GetBackgroundColour();
|
||||
AtObj clrObj;
|
||||
clrObj.setInt("r", (int)colour.Red());
|
||||
clrObj.setInt("g", (int)colour.Green());
|
||||
clrObj.setInt("b", (int)colour.Blue());
|
||||
player.set("Colour", clrObj);
|
||||
}
|
||||
|
||||
// player type
|
||||
choice = controls.ai;
|
||||
if (choice->IsEnabled())
|
||||
{
|
||||
if (choice->GetSelection() > 0)
|
||||
{ // ai - get id
|
||||
{
|
||||
// ai - get id
|
||||
wxStringClientData* str = dynamic_cast<wxStringClientData*>(choice->GetClientObject(choice->GetSelection()));
|
||||
player.set("AI", str->GetData());
|
||||
}
|
||||
else
|
||||
{ // human
|
||||
else // human
|
||||
player.set("AI", _T(""));
|
||||
}
|
||||
|
||||
// resources
|
||||
AtObj resObj;
|
||||
if (controls.food->GetValue() > 0)
|
||||
if (controls.food->IsEnabled())
|
||||
resObj.setInt("food", controls.food->GetValue());
|
||||
if (controls.wood->GetValue() > 0)
|
||||
if (controls.wood->IsEnabled())
|
||||
resObj.setInt("wood", controls.wood->GetValue());
|
||||
if (controls.metal->GetValue() > 0)
|
||||
if (controls.metal->IsEnabled())
|
||||
resObj.setInt("metal", controls.metal->GetValue());
|
||||
if (controls.stone->GetValue() > 0)
|
||||
if (controls.stone->IsEnabled())
|
||||
resObj.setInt("stone", controls.stone->GetValue());
|
||||
if (resObj.defined())
|
||||
player.set("Resources", resObj);
|
||||
|
||||
// population limit
|
||||
if (controls.pop->GetValue() > 0)
|
||||
if (controls.pop->IsEnabled())
|
||||
player.setInt("PopulationLimit", controls.pop->GetValue());
|
||||
|
||||
// team
|
||||
choice = controls.team;
|
||||
if (choice->GetSelection() >= 0)
|
||||
{ // valid selection
|
||||
if (choice->IsEnabled() && choice->GetSelection() >= 0)
|
||||
player.setInt("Team", choice->GetSelection() - 1);
|
||||
}
|
||||
|
||||
// camera
|
||||
AtObj camObj;
|
||||
@ -858,8 +935,6 @@ AtObj PlayerSettingsControl::UpdateSettingsObject()
|
||||
player.set("StartingCamera", camObj);
|
||||
|
||||
players.add("item", player);
|
||||
if (oldPlayer.defined())
|
||||
++oldPlayer;
|
||||
}
|
||||
|
||||
m_MapSettings.set("PlayerData", players);
|
||||
|
@ -116,7 +116,7 @@ QUERYHANDLER(GenerateMap)
|
||||
CScriptValRooted atts;
|
||||
si.Eval("({})", atts);
|
||||
si.SetProperty(atts.get(), "mapType", std::string("scenario"));
|
||||
si.SetProperty(atts.get(), "map", std::wstring(L"_default"));
|
||||
si.SetProperty(atts.get(), "map", std::wstring(L"maps/scenarios/_default"));
|
||||
StartGame(atts);
|
||||
|
||||
msg->status = -1;
|
||||
@ -226,7 +226,7 @@ MESSAGEHANDLER(ImportHeightmap)
|
||||
MESSAGEHANDLER(SaveMap)
|
||||
{
|
||||
CMapWriter writer;
|
||||
const VfsPath pathname = VfsPath("maps/scenarios") / *msg->filename;
|
||||
VfsPath pathname = VfsPath(*msg->filename).ChangeExtension(L".pmp");
|
||||
writer.SaveMap(pathname,
|
||||
g_Game->GetWorld()->GetTerrain(),
|
||||
g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(),
|
||||
@ -352,4 +352,22 @@ QUERYHANDLER(VFSFileExists)
|
||||
msg->exists = VfsFileExists(*msg->path);
|
||||
}
|
||||
|
||||
static Status AddToFilenames(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
|
||||
{
|
||||
std::vector<std::wstring>& filenames = *(std::vector<std::wstring>*)cbData;
|
||||
filenames.push_back(pathname.string().c_str());
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
QUERYHANDLER(GetMapList)
|
||||
{
|
||||
std::vector<std::wstring> scenarioFilenames;
|
||||
vfs::ForEachFile(g_VFS, L"maps/scenarios/", AddToFilenames, (uintptr_t)&scenarioFilenames, L"*.xml", vfs::DIR_RECURSIVE);
|
||||
msg->scenarioFilenames = scenarioFilenames;
|
||||
|
||||
std::vector<std::wstring> skirmishFilenames;
|
||||
vfs::ForEachFile(g_VFS, L"maps/skirmishes/", AddToFilenames, (uintptr_t)&skirmishFilenames, L"*.xml", vfs::DIR_RECURSIVE);
|
||||
msg->skirmishFilenames = skirmishFilenames;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -159,6 +159,12 @@ MESSAGE(SaveMap,
|
||||
((std::wstring, filename))
|
||||
);
|
||||
|
||||
QUERY(GetMapList,
|
||||
,
|
||||
((std::vector<std::wstring>, scenarioFilenames))
|
||||
((std::vector<std::wstring>, skirmishFilenames))
|
||||
);
|
||||
|
||||
QUERY(GetMapSettings,
|
||||
,
|
||||
((std::string, settings))
|
||||
|
Loading…
Reference in New Issue
Block a user