|
|
|
@@ -113,12 +113,14 @@ namespace OpenRA
|
|
|
|
|
|
|
|
|
|
|
|
public const int MaxTilesInCircleRange = 50;
|
|
|
|
public const int MaxTilesInCircleRange = 50;
|
|
|
|
public readonly MapGrid Grid;
|
|
|
|
public readonly MapGrid Grid;
|
|
|
|
|
|
|
|
readonly ModData modData;
|
|
|
|
|
|
|
|
|
|
|
|
[FieldLoader.Ignore] public readonly WVec[] SubCellOffsets;
|
|
|
|
[FieldLoader.Ignore] public readonly WVec[] SubCellOffsets;
|
|
|
|
public readonly SubCell DefaultSubCell;
|
|
|
|
public readonly SubCell DefaultSubCell;
|
|
|
|
public readonly SubCell LastSubCell;
|
|
|
|
public readonly SubCell LastSubCell;
|
|
|
|
[FieldLoader.Ignore] public IReadWritePackage Container;
|
|
|
|
|
|
|
|
public string Path { get; private set; }
|
|
|
|
public IReadOnlyPackage Package { get; private set; }
|
|
|
|
|
|
|
|
public string Path { get { return Package.Name; } }
|
|
|
|
|
|
|
|
|
|
|
|
// Yaml map data
|
|
|
|
// Yaml map data
|
|
|
|
public string Uid { get; private set; }
|
|
|
|
public string Uid { get; private set; }
|
|
|
|
@@ -251,7 +253,7 @@ namespace OpenRA
|
|
|
|
|
|
|
|
|
|
|
|
void AssertExists(string filename)
|
|
|
|
void AssertExists(string filename)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
using (var s = Container.GetStream(filename))
|
|
|
|
using (var s = Package.GetStream(filename))
|
|
|
|
if (s == null)
|
|
|
|
if (s == null)
|
|
|
|
throw new InvalidOperationException("Required file {0} not present in this map".F(filename));
|
|
|
|
throw new InvalidOperationException("Required file {0} not present in this map".F(filename));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -260,10 +262,11 @@ namespace OpenRA
|
|
|
|
/// Initializes a new map created by the editor or importer.
|
|
|
|
/// 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.
|
|
|
|
/// The map will not receive a valid UID until after it has been saved and reloaded.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public Map(TileSet tileset, int width, int height)
|
|
|
|
public Map(ModData modData, TileSet tileset, int width, int height)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
this.modData = modData;
|
|
|
|
var size = new Size(width, height);
|
|
|
|
var size = new Size(width, height);
|
|
|
|
Grid = Game.ModData.Manifest.Get<MapGrid>();
|
|
|
|
Grid = modData.Manifest.Get<MapGrid>();
|
|
|
|
var tileRef = new TerrainTile(tileset.Templates.First().Key, 0);
|
|
|
|
var tileRef = new TerrainTile(tileset.Templates.First().Key, 0);
|
|
|
|
|
|
|
|
|
|
|
|
Title = "Name your map here";
|
|
|
|
Title = "Name your map here";
|
|
|
|
@@ -302,18 +305,21 @@ namespace OpenRA
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>Initializes a map loaded from disk.</summary>
|
|
|
|
/// <summary>Initializes a map loaded from disk.</summary>
|
|
|
|
public Map(string path)
|
|
|
|
public Map(string path)
|
|
|
|
|
|
|
|
: this(Game.ModData, Game.ModData.ModFiles.OpenPackage(path)) { }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Map(ModData modData, IReadOnlyPackage package)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Path = path;
|
|
|
|
this.modData = modData;
|
|
|
|
Container = Game.ModData.ModFiles.OpenWritablePackage(path);
|
|
|
|
Package = package;
|
|
|
|
|
|
|
|
|
|
|
|
AssertExists("map.yaml");
|
|
|
|
AssertExists("map.yaml");
|
|
|
|
AssertExists("map.bin");
|
|
|
|
AssertExists("map.bin");
|
|
|
|
|
|
|
|
|
|
|
|
var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetStream("map.yaml"), path));
|
|
|
|
var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));
|
|
|
|
FieldLoader.Load(this, yaml);
|
|
|
|
FieldLoader.Load(this, yaml);
|
|
|
|
|
|
|
|
|
|
|
|
if (MapFormat != SupportedMapFormat)
|
|
|
|
if (MapFormat != SupportedMapFormat)
|
|
|
|
throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
|
|
|
|
throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));
|
|
|
|
|
|
|
|
|
|
|
|
SpawnPoints = Exts.Lazy(() =>
|
|
|
|
SpawnPoints = Exts.Lazy(() =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -345,19 +351,19 @@ namespace OpenRA
|
|
|
|
MapResources = Exts.Lazy(LoadResourceTiles);
|
|
|
|
MapResources = Exts.Lazy(LoadResourceTiles);
|
|
|
|
MapHeight = Exts.Lazy(LoadMapHeight);
|
|
|
|
MapHeight = Exts.Lazy(LoadMapHeight);
|
|
|
|
|
|
|
|
|
|
|
|
Grid = Game.ModData.Manifest.Get<MapGrid>();
|
|
|
|
Grid = modData.Manifest.Get<MapGrid>();
|
|
|
|
|
|
|
|
|
|
|
|
SubCellOffsets = Grid.SubCellOffsets;
|
|
|
|
SubCellOffsets = Grid.SubCellOffsets;
|
|
|
|
LastSubCell = (SubCell)(SubCellOffsets.Length - 1);
|
|
|
|
LastSubCell = (SubCell)(SubCellOffsets.Length - 1);
|
|
|
|
DefaultSubCell = (SubCell)Grid.SubCellDefaultIndex;
|
|
|
|
DefaultSubCell = (SubCell)Grid.SubCellDefaultIndex;
|
|
|
|
|
|
|
|
|
|
|
|
if (Container.Contains("map.png"))
|
|
|
|
if (Package.Contains("map.png"))
|
|
|
|
using (var dataStream = Container.GetStream("map.png"))
|
|
|
|
using (var dataStream = Package.GetStream("map.png"))
|
|
|
|
CustomPreview = new Bitmap(dataStream);
|
|
|
|
CustomPreview = new Bitmap(dataStream);
|
|
|
|
|
|
|
|
|
|
|
|
PostInit();
|
|
|
|
PostInit();
|
|
|
|
|
|
|
|
|
|
|
|
Uid = ComputeUID(Container);
|
|
|
|
Uid = ComputeUID(Package);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PostInit()
|
|
|
|
void PostInit()
|
|
|
|
@@ -366,7 +372,7 @@ namespace OpenRA
|
|
|
|
{
|
|
|
|
{
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return Game.ModData.RulesetCache.Load(this, this);
|
|
|
|
return modData.RulesetCache.Load(this, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -374,7 +380,7 @@ namespace OpenRA
|
|
|
|
Log.Write("debug", "Failed to load rules for {0} with error {1}", Title, e.Message);
|
|
|
|
Log.Write("debug", "Failed to load rules for {0} with error {1}", Title, e.Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Game.ModData.DefaultRules;
|
|
|
|
return modData.DefaultRules;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);
|
|
|
|
cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);
|
|
|
|
@@ -489,6 +495,11 @@ namespace OpenRA
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Save(string toPath)
|
|
|
|
public void Save(string toPath)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Save(modData.ModFiles.CreatePackage(toPath, new Dictionary<string, byte[]>()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Save(IReadWritePackage toContainer)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MapFormat = 8;
|
|
|
|
MapFormat = 8;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -538,37 +549,31 @@ namespace OpenRA
|
|
|
|
entries.Add("map.yaml", Encoding.UTF8.GetBytes(s));
|
|
|
|
entries.Add("map.yaml", Encoding.UTF8.GetBytes(s));
|
|
|
|
|
|
|
|
|
|
|
|
// Add any custom assets
|
|
|
|
// Add any custom assets
|
|
|
|
if (Container != null)
|
|
|
|
if (Package != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
foreach (var file in Container.Contents)
|
|
|
|
foreach (var file in Package.Contents)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (file == "map.bin" || file == "map.yaml")
|
|
|
|
if (file == "map.bin" || file == "map.yaml")
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
entries.Add(file, Container.GetStream(file).ReadAllBytes());
|
|
|
|
entries.Add(file, Package.GetStream(file).ReadAllBytes());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Saving the map to a new location
|
|
|
|
// Saving the map to a new location
|
|
|
|
if (toPath != Path || Container == null)
|
|
|
|
Package = toContainer;
|
|
|
|
{
|
|
|
|
|
|
|
|
Path = toPath;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create a new map package
|
|
|
|
|
|
|
|
Container = Game.ModData.ModFiles.CreatePackage(Path, entries);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update existing package
|
|
|
|
// Update existing package
|
|
|
|
Container.Write(entries);
|
|
|
|
toContainer.Write(entries);
|
|
|
|
|
|
|
|
|
|
|
|
// Update UID to match the newly saved data
|
|
|
|
// Update UID to match the newly saved data
|
|
|
|
Uid = ComputeUID(Container);
|
|
|
|
Uid = ComputeUID(toContainer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CellLayer<TerrainTile> LoadMapTiles()
|
|
|
|
public CellLayer<TerrainTile> LoadMapTiles()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var tiles = new CellLayer<TerrainTile>(this);
|
|
|
|
var tiles = new CellLayer<TerrainTile>(this);
|
|
|
|
using (var s = Container.GetStream("map.bin"))
|
|
|
|
using (var s = Package.GetStream("map.bin"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var header = new BinaryDataHeader(s, MapSize);
|
|
|
|
var header = new BinaryDataHeader(s, MapSize);
|
|
|
|
if (header.TilesOffset > 0)
|
|
|
|
if (header.TilesOffset > 0)
|
|
|
|
@@ -600,7 +605,7 @@ namespace OpenRA
|
|
|
|
public CellLayer<byte> LoadMapHeight()
|
|
|
|
public CellLayer<byte> LoadMapHeight()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var tiles = new CellLayer<byte>(this);
|
|
|
|
var tiles = new CellLayer<byte>(this);
|
|
|
|
using (var s = Container.GetStream("map.bin"))
|
|
|
|
using (var s = Package.GetStream("map.bin"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var header = new BinaryDataHeader(s, MapSize);
|
|
|
|
var header = new BinaryDataHeader(s, MapSize);
|
|
|
|
if (header.HeightsOffset > 0)
|
|
|
|
if (header.HeightsOffset > 0)
|
|
|
|
@@ -622,7 +627,7 @@ namespace OpenRA
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var resources = new CellLayer<ResourceTile>(this);
|
|
|
|
var resources = new CellLayer<ResourceTile>(this);
|
|
|
|
|
|
|
|
|
|
|
|
using (var s = Container.GetStream("map.bin"))
|
|
|
|
using (var s = Package.GetStream("map.bin"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var header = new BinaryDataHeader(s, MapSize);
|
|
|
|
var header = new BinaryDataHeader(s, MapSize);
|
|
|
|
if (header.ResourcesOffset > 0)
|
|
|
|
if (header.ResourcesOffset > 0)
|
|
|
|
@@ -1173,16 +1178,16 @@ namespace OpenRA
|
|
|
|
public Stream Open(string filename)
|
|
|
|
public Stream Open(string filename)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Explicit package paths never refer to a map
|
|
|
|
// Explicit package paths never refer to a map
|
|
|
|
if (!filename.Contains("|") && Container.Contains(filename))
|
|
|
|
if (!filename.Contains("|") && Package.Contains(filename))
|
|
|
|
return Container.GetStream(filename);
|
|
|
|
return Package.GetStream(filename);
|
|
|
|
|
|
|
|
|
|
|
|
return Game.ModData.DefaultFileSystem.Open(filename);
|
|
|
|
return modData.DefaultFileSystem.Open(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool TryGetPackageContaining(string path, out IReadOnlyPackage package, out string filename)
|
|
|
|
public bool TryGetPackageContaining(string path, out IReadOnlyPackage package, out string filename)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Packages aren't supported inside maps
|
|
|
|
// Packages aren't supported inside maps
|
|
|
|
return Game.ModData.DefaultFileSystem.TryGetPackageContaining(path, out package, out filename);
|
|
|
|
return modData.DefaultFileSystem.TryGetPackageContaining(path, out package, out filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool TryOpen(string filename, out Stream s)
|
|
|
|
public bool TryOpen(string filename, out Stream s)
|
|
|
|
@@ -1190,21 +1195,21 @@ namespace OpenRA
|
|
|
|
// Explicit package paths never refer to a map
|
|
|
|
// Explicit package paths never refer to a map
|
|
|
|
if (!filename.Contains("|"))
|
|
|
|
if (!filename.Contains("|"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
s = Container.GetStream(filename);
|
|
|
|
s = Package.GetStream(filename);
|
|
|
|
if (s != null)
|
|
|
|
if (s != null)
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Game.ModData.DefaultFileSystem.TryOpen(filename, out s);
|
|
|
|
return modData.DefaultFileSystem.TryOpen(filename, out s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool Exists(string filename)
|
|
|
|
public bool Exists(string filename)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Explicit package paths never refer to a map
|
|
|
|
// Explicit package paths never refer to a map
|
|
|
|
if (!filename.Contains("|") && Container.Contains(filename))
|
|
|
|
if (!filename.Contains("|") && Package.Contains(filename))
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
return Game.ModData.DefaultFileSystem.Exists(filename);
|
|
|
|
return modData.DefaultFileSystem.Exists(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|