Merge pull request #10963 from pchote/map-load-save
Rework map data load/save.
This commit is contained in:
@@ -15,6 +15,7 @@ using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using OpenRA.FileSystem;
|
||||
@@ -66,28 +67,185 @@ namespace OpenRA
|
||||
MissionSelector = 4
|
||||
}
|
||||
|
||||
class MapField
|
||||
{
|
||||
enum Type { Normal, NodeList, MiniYaml }
|
||||
readonly FieldInfo field;
|
||||
readonly PropertyInfo property;
|
||||
readonly Type type;
|
||||
|
||||
readonly string key;
|
||||
readonly string fieldName;
|
||||
readonly bool required;
|
||||
readonly string ignoreIfValue;
|
||||
|
||||
public MapField(string key, string fieldName = null, bool required = true, string ignoreIfValue = null)
|
||||
{
|
||||
this.key = key;
|
||||
this.fieldName = fieldName ?? key;
|
||||
this.required = required;
|
||||
this.ignoreIfValue = ignoreIfValue;
|
||||
|
||||
field = typeof(Map).GetField(this.fieldName);
|
||||
property = typeof(Map).GetProperty(this.fieldName);
|
||||
if (field == null && property == null)
|
||||
throw new InvalidOperationException("Map does not have a field/property " + fieldName);
|
||||
|
||||
var t = field != null ? field.FieldType : property.PropertyType;
|
||||
type = t == typeof(List<MiniYamlNode>) ? Type.NodeList :
|
||||
t == typeof(MiniYaml) ? Type.MiniYaml : Type.Normal;
|
||||
}
|
||||
|
||||
public void Deserialize(Map map, List<MiniYamlNode> nodes)
|
||||
{
|
||||
var node = nodes.FirstOrDefault(n => n.Key == key);
|
||||
if (node == null)
|
||||
{
|
||||
if (required)
|
||||
throw new YamlException("Required field `{0}` not found in map.yaml".F(key));
|
||||
return;
|
||||
}
|
||||
|
||||
if (field != null)
|
||||
{
|
||||
if (type == Type.NodeList)
|
||||
field.SetValue(map, node.Value.Nodes);
|
||||
else if (type == Type.MiniYaml)
|
||||
field.SetValue(map, node.Value);
|
||||
else
|
||||
FieldLoader.LoadField(map, fieldName, node.Value.Value);
|
||||
}
|
||||
|
||||
if (property != null)
|
||||
{
|
||||
if (type == Type.NodeList)
|
||||
property.SetValue(map, node.Value.Nodes, null);
|
||||
else if (type == Type.MiniYaml)
|
||||
property.SetValue(map, node.Value, null);
|
||||
else
|
||||
FieldLoader.LoadField(map, fieldName, node.Value.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(Map map, List<MiniYamlNode> nodes)
|
||||
{
|
||||
var value = field != null ? field.GetValue(map) : property.GetValue(map, null);
|
||||
if (type == Type.NodeList)
|
||||
{
|
||||
var listValue = (List<MiniYamlNode>)value;
|
||||
if (required || listValue.Any())
|
||||
nodes.Add(new MiniYamlNode(key, null, listValue));
|
||||
}
|
||||
else if (type == Type.MiniYaml)
|
||||
{
|
||||
var yamlValue = (MiniYaml)value;
|
||||
if (required || (yamlValue != null && (yamlValue.Value != null || yamlValue.Nodes.Any())))
|
||||
nodes.Add(new MiniYamlNode(key, yamlValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
var formattedValue = FieldSaver.FormatValue(value);
|
||||
if (required || formattedValue != ignoreIfValue)
|
||||
nodes.Add(new MiniYamlNode(key, formattedValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Map : IReadOnlyFileSystem
|
||||
{
|
||||
public const int SupportedMapFormat = 10;
|
||||
|
||||
public readonly MapGrid Grid;
|
||||
readonly ModData modData;
|
||||
/// <summary>Defines the order of the fields in map.yaml</summary>
|
||||
static readonly MapField[] YamlFields =
|
||||
{
|
||||
new MapField("MapFormat"),
|
||||
new MapField("RequiresMod"),
|
||||
new MapField("Title"),
|
||||
new MapField("Author"),
|
||||
new MapField("Tileset"),
|
||||
new MapField("MapSize"),
|
||||
new MapField("Bounds"),
|
||||
new MapField("Visibility"),
|
||||
new MapField("Type"),
|
||||
new MapField("LockPreview", required: false, ignoreIfValue: "False"),
|
||||
new MapField("Players", "PlayerDefinitions"),
|
||||
new MapField("Actors", "ActorDefinitions"),
|
||||
new MapField("Rules", "RuleDefinitions", required: false),
|
||||
new MapField("Sequences", "SequenceDefinitions", required: false),
|
||||
new MapField("VoxelSequences", "VoxelSequenceDefinitions", required: false),
|
||||
new MapField("Weapons", "WeaponDefinitions", required: false),
|
||||
new MapField("Voices", "VoiceDefinitions", required: false),
|
||||
new MapField("Music", "MusicDefinitions", required: false),
|
||||
new MapField("Notifications", "NotificationDefinitions", required: false),
|
||||
new MapField("Translations", "TranslationDefinitions", required: false)
|
||||
};
|
||||
|
||||
public IReadOnlyPackage Package { get; private set; }
|
||||
// Format versions
|
||||
public int MapFormat { get; private set; }
|
||||
public readonly byte TileFormat = 2;
|
||||
|
||||
// Yaml map data
|
||||
public string Uid { get; private set; }
|
||||
public int MapFormat;
|
||||
public MapVisibility Visibility = MapVisibility.Lobby;
|
||||
// Standard yaml metadata
|
||||
public string RequiresMod;
|
||||
|
||||
public string Title;
|
||||
public string Type = "Conquest";
|
||||
public string Author;
|
||||
public string Tileset;
|
||||
public bool LockPreview;
|
||||
public Rectangle Bounds;
|
||||
public MapVisibility Visibility = MapVisibility.Lobby;
|
||||
public string Type = "Conquest";
|
||||
|
||||
public int2 MapSize { get; private set; }
|
||||
|
||||
// Player and actor yaml. Public for access by the map importers and lint checks.
|
||||
public List<MiniYamlNode> PlayerDefinitions = new List<MiniYamlNode>();
|
||||
public List<MiniYamlNode> ActorDefinitions = new List<MiniYamlNode>();
|
||||
|
||||
// Custom map yaml. Public for access by the map importers and lint checks
|
||||
public readonly MiniYaml RuleDefinitions;
|
||||
public readonly MiniYaml SequenceDefinitions;
|
||||
public readonly MiniYaml VoxelSequenceDefinitions;
|
||||
public readonly MiniYaml WeaponDefinitions;
|
||||
public readonly MiniYaml VoiceDefinitions;
|
||||
public readonly MiniYaml MusicDefinitions;
|
||||
public readonly MiniYaml NotificationDefinitions;
|
||||
public readonly MiniYaml TranslationDefinitions;
|
||||
|
||||
// Generated data
|
||||
public readonly MapGrid Grid;
|
||||
public IReadOnlyPackage Package { get; private set; }
|
||||
public string Uid { get; private set; }
|
||||
|
||||
public Ruleset Rules { get; private set; }
|
||||
public bool InvalidCustomRules { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The top-left of the playable area in projected world coordinates
|
||||
/// This is a hacky workaround for legacy functionality. Do not use for new code.
|
||||
/// </summary>
|
||||
public WPos ProjectedTopLeft { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The bottom-right of the playable area in projected world coordinates
|
||||
/// This is a hacky workaround for legacy functionality. Do not use for new code.
|
||||
/// </summary>
|
||||
public WPos ProjectedBottomRight { get; private set; }
|
||||
|
||||
public CellLayer<TerrainTile> Tiles { get; private set; }
|
||||
public CellLayer<ResourceTile> Resources { get; private set; }
|
||||
public CellLayer<byte> Height { get; private set; }
|
||||
public CellLayer<byte> CustomTerrain { get; private set; }
|
||||
|
||||
public ProjectedCellRegion ProjectedCellBounds { get; private set; }
|
||||
public CellRegion AllCells { get; private set; }
|
||||
public List<CPos> AllEdgeCells { get; private set; }
|
||||
|
||||
// Internal data
|
||||
readonly ModData modData;
|
||||
CellLayer<short> cachedTerrainIndexes;
|
||||
bool initializedCellProjection;
|
||||
CellLayer<PPos[]> cellProjection;
|
||||
CellLayer<List<MPos>> inverseCellProjection;
|
||||
|
||||
public static string ComputeUID(IReadOnlyPackage package)
|
||||
{
|
||||
// UID is calculated by taking an SHA1 of the yaml and binary data
|
||||
@@ -111,55 +269,6 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle Bounds;
|
||||
|
||||
/// <summary>
|
||||
/// The top-left of the playable area in projected world coordinates
|
||||
/// This is a hacky workaround for legacy functionality. Do not use for new code.
|
||||
/// </summary>
|
||||
public WPos ProjectedTopLeft;
|
||||
|
||||
/// <summary>
|
||||
/// The bottom-right of the playable area in projected world coordinates
|
||||
/// This is a hacky workaround for legacy functionality. Do not use for new code.
|
||||
/// </summary>
|
||||
public WPos ProjectedBottomRight;
|
||||
|
||||
// Yaml map data
|
||||
[FieldLoader.Ignore] public readonly MiniYaml RuleDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml SequenceDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml VoxelSequenceDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml WeaponDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml VoiceDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml MusicDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml NotificationDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml TranslationDefinitions;
|
||||
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> PlayerDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> ActorDefinitions = new List<MiniYamlNode>();
|
||||
|
||||
// Binary map data
|
||||
[FieldLoader.Ignore] public byte TileFormat = 2;
|
||||
|
||||
public int2 MapSize;
|
||||
|
||||
[FieldLoader.Ignore] public CellLayer<TerrainTile> Tiles;
|
||||
[FieldLoader.Ignore] public CellLayer<ResourceTile> Resources;
|
||||
[FieldLoader.Ignore] public CellLayer<byte> Height;
|
||||
|
||||
[FieldLoader.Ignore] public CellLayer<byte> CustomTerrain;
|
||||
[FieldLoader.Ignore] CellLayer<short> cachedTerrainIndexes;
|
||||
|
||||
[FieldLoader.Ignore] bool initializedCellProjection;
|
||||
[FieldLoader.Ignore] CellLayer<PPos[]> cellProjection;
|
||||
[FieldLoader.Ignore] CellLayer<List<MPos>> inverseCellProjection;
|
||||
|
||||
public Ruleset Rules { get; private set; }
|
||||
|
||||
[FieldLoader.Ignore] public ProjectedCellRegion ProjectedCellBounds;
|
||||
[FieldLoader.Ignore] public CellRegion AllCells;
|
||||
public List<CPos> AllEdgeCells { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new map created by the editor or importer.
|
||||
/// The map will not receive a valid UID until after it has been saved and reloaded.
|
||||
@@ -204,20 +313,12 @@ namespace OpenRA
|
||||
throw new InvalidDataException("Not a valid map\n File: {1}".F(package.Name));
|
||||
|
||||
var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));
|
||||
FieldLoader.Load(this, yaml);
|
||||
foreach (var field in YamlFields)
|
||||
field.Deserialize(this, yaml.Nodes);
|
||||
|
||||
if (MapFormat != SupportedMapFormat)
|
||||
throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));
|
||||
|
||||
RuleDefinitions = LoadRuleSection(yaml, "Rules");
|
||||
SequenceDefinitions = LoadRuleSection(yaml, "Sequences");
|
||||
VoxelSequenceDefinitions = LoadRuleSection(yaml, "VoxelSequences");
|
||||
WeaponDefinitions = LoadRuleSection(yaml, "Weapons");
|
||||
VoiceDefinitions = LoadRuleSection(yaml, "Voices");
|
||||
MusicDefinitions = LoadRuleSection(yaml, "Music");
|
||||
NotificationDefinitions = LoadRuleSection(yaml, "Notifications");
|
||||
TranslationDefinitions = LoadRuleSection(yaml, "Translations");
|
||||
|
||||
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
|
||||
ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");
|
||||
|
||||
@@ -284,12 +385,6 @@ namespace OpenRA
|
||||
Uid = ComputeUID(Package);
|
||||
}
|
||||
|
||||
MiniYaml LoadRuleSection(MiniYaml yaml, string section)
|
||||
{
|
||||
var node = yaml.Nodes.FirstOrDefault(n => n.Key == section);
|
||||
return node != null ? node.Value : null;
|
||||
}
|
||||
|
||||
void PostInit()
|
||||
{
|
||||
try
|
||||
@@ -417,49 +512,8 @@ namespace OpenRA
|
||||
MapFormat = SupportedMapFormat;
|
||||
|
||||
var root = new List<MiniYamlNode>();
|
||||
var fields = new[]
|
||||
{
|
||||
"MapFormat",
|
||||
"RequiresMod",
|
||||
"Title",
|
||||
"Author",
|
||||
"Tileset",
|
||||
"MapSize",
|
||||
"Bounds",
|
||||
"Visibility",
|
||||
"Type",
|
||||
};
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
var f = GetType().GetField(field);
|
||||
if (f.GetValue(this) == null)
|
||||
continue;
|
||||
root.Add(new MiniYamlNode(field, FieldSaver.FormatValue(this, f)));
|
||||
}
|
||||
|
||||
// Save LockPreview field only if it's set
|
||||
if (LockPreview)
|
||||
root.Add(new MiniYamlNode("LockPreview", "True"));
|
||||
|
||||
root.Add(new MiniYamlNode("Players", null, PlayerDefinitions));
|
||||
root.Add(new MiniYamlNode("Actors", null, ActorDefinitions));
|
||||
|
||||
var ruleSections = new[]
|
||||
{
|
||||
new MiniYamlNode("Rules", RuleDefinitions),
|
||||
new MiniYamlNode("Sequences", SequenceDefinitions),
|
||||
new MiniYamlNode("VoxelSequences", VoxelSequenceDefinitions),
|
||||
new MiniYamlNode("Weapons", WeaponDefinitions),
|
||||
new MiniYamlNode("Voices", VoiceDefinitions),
|
||||
new MiniYamlNode("Music", MusicDefinitions),
|
||||
new MiniYamlNode("Notifications", NotificationDefinitions),
|
||||
new MiniYamlNode("Translations", TranslationDefinitions)
|
||||
};
|
||||
|
||||
foreach (var section in ruleSections)
|
||||
if (section.Value != null && (section.Value.Value != null || section.Value.Nodes.Any()))
|
||||
root.Add(section);
|
||||
foreach (var field in YamlFields)
|
||||
field.Serialize(this, root);
|
||||
|
||||
// Saving to a new package: copy over all the content from the map
|
||||
if (Package != null && toPackage != Package)
|
||||
|
||||
@@ -23,16 +23,8 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
{
|
||||
class ImportTSMapCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--import-ts-map"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
int2 fullSize;
|
||||
int actorCount = 0;
|
||||
int spawnCount = 0;
|
||||
string IUtilityCommand.Name { get { return "--import-ts-map"; } }
|
||||
bool IUtilityCommand.ValidateArguments(string[] args) { return args.Length >= 2; }
|
||||
|
||||
static readonly Dictionary<byte, string> OverlayToActor = new Dictionary<byte, string>()
|
||||
{
|
||||
@@ -150,31 +142,46 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
{ 0x03, new byte[] { 0x7E } }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, string> DeployableActors = new Dictionary<string, string>()
|
||||
static readonly Dictionary<string, string> DeployableActors = new Dictionary<string, string>()
|
||||
{
|
||||
{ "gadpsa", "lpst" },
|
||||
{ "gatick", "ttnk" }
|
||||
};
|
||||
|
||||
[Desc("FILENAME", "Convert a Tiberian Sun map to the OpenRA format.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(ModData modData, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
|
||||
var filename = args[1];
|
||||
var file = new IniFile(File.Open(args[1], FileMode.Open));
|
||||
var map = GenerateMapHeader(filename, file, modData);
|
||||
var basic = file.GetSection("Basic");
|
||||
var mapSection = file.GetSection("Map");
|
||||
var tileset = mapSection.GetValue("Theater", "");
|
||||
var iniSize = mapSection.GetValue("Size", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray();
|
||||
var iniBounds = mapSection.GetValue("LocalSize", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray();
|
||||
var size = new Size(iniSize[2], 2 * iniSize[3]);
|
||||
|
||||
ReadTiles(map, file);
|
||||
ReadActors(map, file, "Structures");
|
||||
ReadActors(map, file, "Units");
|
||||
ReadActors(map, file, "Infantry");
|
||||
ReadTerrainActors(map, file);
|
||||
ReadWaypoints(map, file);
|
||||
ReadOverlay(map, file);
|
||||
var map = new Map(Game.ModData, modData.DefaultTileSets[tileset], size.Width, size.Height)
|
||||
{
|
||||
Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
|
||||
Author = "Westwood Studios",
|
||||
Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]),
|
||||
RequiresMod = modData.Manifest.Mod.Id
|
||||
};
|
||||
|
||||
var fullSize = new int2(iniSize[2], iniSize[3]);
|
||||
ReadTiles(map, file, fullSize);
|
||||
ReadActors(map, file, "Structures", fullSize);
|
||||
ReadActors(map, file, "Units", fullSize);
|
||||
ReadActors(map, file, "Infantry", fullSize);
|
||||
ReadTerrainActors(map, file, fullSize);
|
||||
ReadWaypoints(map, file, fullSize);
|
||||
ReadOverlay(map, file, fullSize);
|
||||
ReadLighting(map, file);
|
||||
|
||||
var spawnCount = map.ActorDefinitions.Count(n => n.Value.Value == "mpspawn");
|
||||
var mapPlayers = new MapPlayers(map.Rules, spawnCount);
|
||||
map.PlayerDefinitions = mapPlayers.ToMiniYaml();
|
||||
|
||||
@@ -184,7 +191,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
Console.WriteLine(dest + " saved.");
|
||||
}
|
||||
|
||||
void UnpackLZO(byte[] src, byte[] dest)
|
||||
static void UnpackLZO(byte[] src, byte[] dest)
|
||||
{
|
||||
var srcOffset = 0U;
|
||||
var destOffset = 0U;
|
||||
@@ -200,7 +207,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
}
|
||||
}
|
||||
|
||||
void UnpackLCW(byte[] src, byte[] dest, byte[] temp)
|
||||
static void UnpackLCW(byte[] src, byte[] dest, byte[] temp)
|
||||
{
|
||||
var srcOffset = 0;
|
||||
var destOffset = 0;
|
||||
@@ -217,31 +224,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
}
|
||||
}
|
||||
|
||||
Map GenerateMapHeader(string filename, IniFile file, ModData modData)
|
||||
{
|
||||
var basic = file.GetSection("Basic");
|
||||
var mapSection = file.GetSection("Map");
|
||||
var tileset = mapSection.GetValue("Theater", "");
|
||||
var iniSize = mapSection.GetValue("Size", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray();
|
||||
var iniBounds = mapSection.GetValue("LocalSize", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray();
|
||||
var size = new Size(iniSize[2], 2 * iniSize[3]);
|
||||
|
||||
fullSize = new int2(iniSize[2], iniSize[3]);
|
||||
|
||||
var map = new Map(Game.ModData, modData.DefaultTileSets[tileset], size.Width, size.Height);
|
||||
map.Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename));
|
||||
map.Author = "Westwood Studios";
|
||||
map.Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]);
|
||||
map.Resources = new CellLayer<ResourceTile>(map.Grid.Type, size);
|
||||
map.Tiles = new CellLayer<TerrainTile>(map.Grid.Type, size);
|
||||
map.Height = new CellLayer<byte>(map.Grid.Type, size);
|
||||
|
||||
map.RequiresMod = modData.Manifest.Mod.Id;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void ReadTiles(Map map, IniFile file)
|
||||
static void ReadTiles(Map map, IniFile file, int2 fullSize)
|
||||
{
|
||||
var tileset = Game.ModData.DefaultTileSets[map.Tileset];
|
||||
var mapSection = file.GetSection("IsoMapPack5");
|
||||
@@ -279,7 +262,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOverlay(Map map, IniFile file)
|
||||
static void ReadOverlay(Map map, IniFile file, int2 fullSize)
|
||||
{
|
||||
var overlaySection = file.GetSection("OverlayPack");
|
||||
var overlayCompressed = Convert.FromBase64String(overlaySection.Aggregate(string.Empty, (a, b) => a + b.Value));
|
||||
@@ -320,7 +303,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
new OwnerInit("Neutral")
|
||||
};
|
||||
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -340,7 +323,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
}
|
||||
}
|
||||
|
||||
void ReadWaypoints(Map map, IniFile file)
|
||||
static void ReadWaypoints(Map map, IniFile file, int2 fullSize)
|
||||
{
|
||||
var waypointsSection = file.GetSection("Waypoints", true);
|
||||
foreach (var kv in waypointsSection)
|
||||
@@ -357,14 +340,11 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
ar.Add(new LocationInit(cell));
|
||||
ar.Add(new OwnerInit("Neutral"));
|
||||
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
|
||||
|
||||
if (ar.Type == "mpspawn")
|
||||
spawnCount++;
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
|
||||
}
|
||||
}
|
||||
|
||||
void ReadTerrainActors(Map map, IniFile file)
|
||||
static void ReadTerrainActors(Map map, IniFile file, int2 fullSize)
|
||||
{
|
||||
var terrainSection = file.GetSection("Terrain", true);
|
||||
foreach (var kv in terrainSection)
|
||||
@@ -384,11 +364,11 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
if (!map.Rules.Actors.ContainsKey(name))
|
||||
Console.WriteLine("Ignoring unknown actor type: `{0}`".F(name));
|
||||
else
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
|
||||
}
|
||||
}
|
||||
|
||||
void ReadActors(Map map, IniFile file, string type)
|
||||
static void ReadActors(Map map, IniFile file, string type, int2 fullSize)
|
||||
{
|
||||
var structuresSection = file.GetSection(type, true);
|
||||
foreach (var kv in structuresSection)
|
||||
@@ -427,11 +407,11 @@ namespace OpenRA.Mods.TS.UtilityCommands
|
||||
if (!map.Rules.Actors.ContainsKey(name))
|
||||
Console.WriteLine("Ignoring unknown actor type: `{0}`".F(name));
|
||||
else
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
|
||||
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
|
||||
}
|
||||
}
|
||||
|
||||
void ReadLighting(Map map, IniFile file)
|
||||
static void ReadLighting(Map map, IniFile file)
|
||||
{
|
||||
var lightingTypes = new[] { "Red", "Green", "Blue", "Ambient" };
|
||||
var lightingSection = file.GetSection("Lighting");
|
||||
|
||||
Reference in New Issue
Block a user