Merge pull request #10942 from pchote/remove-map-lazyness

Remove map lazyness.
This commit is contained in:
Matthias Mailänder
2016-03-21 20:23:47 +01:00
28 changed files with 195 additions and 256 deletions

View File

@@ -20,15 +20,11 @@ namespace OpenRA.Graphics
readonly Map map; readonly Map map;
readonly Dictionary<string, TerrainSpriteLayer> spriteLayers = new Dictionary<string, TerrainSpriteLayer>(); readonly Dictionary<string, TerrainSpriteLayer> spriteLayers = new Dictionary<string, TerrainSpriteLayer>();
readonly Theater theater; readonly Theater theater;
readonly CellLayer<TerrainTile> mapTiles;
readonly CellLayer<byte> mapHeight;
public TerrainRenderer(World world, WorldRenderer wr) public TerrainRenderer(World world, WorldRenderer wr)
{ {
map = world.Map; map = world.Map;
theater = wr.Theater; theater = wr.Theater;
mapTiles = map.MapTiles.Value;
mapHeight = map.MapHeight.Value;
foreach (var template in map.Rules.TileSet.Templates) foreach (var template in map.Rules.TileSet.Templates)
{ {
@@ -40,13 +36,13 @@ namespace OpenRA.Graphics
foreach (var cell in map.AllCells) foreach (var cell in map.AllCells)
UpdateCell(cell); UpdateCell(cell);
mapTiles.CellEntryChanged += UpdateCell; map.Tiles.CellEntryChanged += UpdateCell;
mapHeight.CellEntryChanged += UpdateCell; map.Height.CellEntryChanged += UpdateCell;
} }
public void UpdateCell(CPos cell) public void UpdateCell(CPos cell)
{ {
var tile = mapTiles[cell]; var tile = map.Tiles[cell];
var palette = TileSet.TerrainPaletteInternalName; var palette = TileSet.TerrainPaletteInternalName;
if (map.Rules.TileSet.Templates.ContainsKey(tile.Type)) if (map.Rules.TileSet.Templates.ContainsKey(tile.Type))
palette = map.Rules.TileSet.Templates[tile.Type].Palette ?? palette; palette = map.Rules.TileSet.Templates[tile.Type].Palette ?? palette;
@@ -67,8 +63,8 @@ namespace OpenRA.Graphics
public void Dispose() public void Dispose()
{ {
mapTiles.CellEntryChanged -= UpdateCell; map.Tiles.CellEntryChanged -= UpdateCell;
mapHeight.CellEntryChanged -= UpdateCell; map.Height.CellEntryChanged -= UpdateCell;
foreach (var kv in spriteLayers.Values) foreach (var kv in spriteLayers.Values)
kv.Dispose(); kv.Dispose();

View File

@@ -161,8 +161,7 @@ namespace OpenRA.Graphics
var ramp = 0; var ramp = 0;
if (map.Contains(uv)) if (map.Contains(uv))
{ {
var tile = map.MapTiles.Value[uv]; var ti = tileSet.GetTileInfo(map.Tiles[uv]);
var ti = tileSet.GetTileInfo(tile);
if (ti != null) if (ti != null)
ramp = ti.RampType; ramp = ti.RampType;
} }

View File

@@ -125,8 +125,6 @@ namespace OpenRA
/// </summary> /// </summary>
public WPos ProjectedBottomRight; public WPos ProjectedBottomRight;
public Lazy<CPos[]> SpawnPoints;
// Yaml map data // Yaml map data
[FieldLoader.Ignore] public readonly MiniYaml RuleDefinitions; [FieldLoader.Ignore] public readonly MiniYaml RuleDefinitions;
[FieldLoader.Ignore] public readonly MiniYaml SequenceDefinitions; [FieldLoader.Ignore] public readonly MiniYaml SequenceDefinitions;
@@ -145,9 +143,9 @@ namespace OpenRA
public int2 MapSize; public int2 MapSize;
[FieldLoader.Ignore] public Lazy<CellLayer<TerrainTile>> MapTiles; [FieldLoader.Ignore] public CellLayer<TerrainTile> Tiles;
[FieldLoader.Ignore] public Lazy<CellLayer<ResourceTile>> MapResources; [FieldLoader.Ignore] public CellLayer<ResourceTile> Resources;
[FieldLoader.Ignore] public Lazy<CellLayer<byte>> MapHeight; [FieldLoader.Ignore] public CellLayer<byte> Height;
[FieldLoader.Ignore] public CellLayer<byte> CustomTerrain; [FieldLoader.Ignore] public CellLayer<byte> CustomTerrain;
[FieldLoader.Ignore] CellLayer<short> cachedTerrainIndexes; [FieldLoader.Ignore] CellLayer<short> cachedTerrainIndexes;
@@ -156,20 +154,12 @@ namespace OpenRA
[FieldLoader.Ignore] CellLayer<PPos[]> cellProjection; [FieldLoader.Ignore] CellLayer<PPos[]> cellProjection;
[FieldLoader.Ignore] CellLayer<List<MPos>> inverseCellProjection; [FieldLoader.Ignore] CellLayer<List<MPos>> inverseCellProjection;
[FieldLoader.Ignore] Lazy<Ruleset> rules; public Ruleset Rules { get; private set; }
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
[FieldLoader.Ignore] public ProjectedCellRegion ProjectedCellBounds; [FieldLoader.Ignore] public ProjectedCellRegion ProjectedCellBounds;
[FieldLoader.Ignore] public CellRegion AllCells; [FieldLoader.Ignore] public CellRegion AllCells;
public List<CPos> AllEdgeCells { get; private set; } public List<CPos> AllEdgeCells { get; private set; }
void AssertExists(string filename)
{
using (var s = Package.GetStream(filename))
if (s == null)
throw new InvalidOperationException("Required file {0} not present in this map".F(filename));
}
/// <summary> /// <summary>
/// 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.
@@ -191,27 +181,16 @@ namespace OpenRA
// Will be dropped on save if nothing is added to it // Will be dropped on save if nothing is added to it
RuleDefinitions = new MiniYaml(""); RuleDefinitions = new MiniYaml("");
MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(Grid.Type, size)); Tiles = new CellLayer<TerrainTile>(Grid.Type, size);
Resources = new CellLayer<ResourceTile>(Grid.Type, size);
MapTiles = Exts.Lazy(() => Height = new CellLayer<byte>(Grid.Type, size);
if (Grid.MaximumTerrainHeight > 0)
{ {
var ret = new CellLayer<TerrainTile>(Grid.Type, size); Height.CellEntryChanged += UpdateProjection;
ret.Clear(tileRef); Tiles.CellEntryChanged += UpdateProjection;
if (Grid.MaximumTerrainHeight > 0) }
ret.CellEntryChanged += UpdateProjection;
return ret;
});
MapHeight = Exts.Lazy(() => Tiles.Clear(tileRef);
{
var ret = new CellLayer<byte>(Grid.Type, size);
ret.Clear(0);
if (Grid.MaximumTerrainHeight > 0)
ret.CellEntryChanged += UpdateProjection;
return ret;
});
SpawnPoints = Exts.Lazy(() => new CPos[0]);
PostInit(); PostInit();
} }
@@ -221,8 +200,8 @@ namespace OpenRA
this.modData = modData; this.modData = modData;
Package = package; Package = package;
AssertExists("map.yaml"); if (!Package.Contains("map.yaml") || !Package.Contains("map.bin"))
AssertExists("map.bin"); 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)); var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));
FieldLoader.Load(this, yaml); FieldLoader.Load(this, yaml);
@@ -230,19 +209,6 @@ namespace OpenRA
if (MapFormat != SupportedMapFormat) if (MapFormat != SupportedMapFormat)
throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name)); throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));
SpawnPoints = Exts.Lazy(() =>
{
var spawns = new List<CPos>();
foreach (var kv in ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
{
var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
}
return spawns.ToArray();
});
RuleDefinitions = LoadRuleSection(yaml, "Rules"); RuleDefinitions = LoadRuleSection(yaml, "Rules");
SequenceDefinitions = LoadRuleSection(yaml, "Sequences"); SequenceDefinitions = LoadRuleSection(yaml, "Sequences");
VoxelSequenceDefinitions = LoadRuleSection(yaml, "VoxelSequences"); VoxelSequenceDefinitions = LoadRuleSection(yaml, "VoxelSequences");
@@ -255,12 +221,64 @@ namespace OpenRA
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players"); PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors"); ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");
MapTiles = Exts.Lazy(LoadMapTiles);
MapResources = Exts.Lazy(LoadResourceTiles);
MapHeight = Exts.Lazy(LoadMapHeight);
Grid = modData.Manifest.Get<MapGrid>(); Grid = modData.Manifest.Get<MapGrid>();
var size = new Size(MapSize.X, MapSize.Y);
Tiles = new CellLayer<TerrainTile>(Grid.Type, size);
Resources = new CellLayer<ResourceTile>(Grid.Type, size);
Height = new CellLayer<byte>(Grid.Type, size);
using (var s = Package.GetStream("map.bin"))
{
var header = new BinaryDataHeader(s, MapSize);
if (header.TilesOffset > 0)
{
s.Position = header.TilesOffset;
for (var i = 0; i < MapSize.X; i++)
{
for (var j = 0; j < MapSize.Y; j++)
{
var tile = s.ReadUInt16();
var index = s.ReadUInt8();
// TODO: Remember to remove this when rewriting tile variants / PickAny
if (index == byte.MaxValue)
index = (byte)(i % 4 + (j % 4) * 4);
Tiles[new MPos(i, j)] = new TerrainTile(tile, index);
}
}
}
if (header.ResourcesOffset > 0)
{
s.Position = header.ResourcesOffset;
for (var i = 0; i < MapSize.X; i++)
{
for (var j = 0; j < MapSize.Y; j++)
{
var type = s.ReadUInt8();
var density = s.ReadUInt8();
Resources[new MPos(i, j)] = new ResourceTile(type, density);
}
}
}
if (header.HeightsOffset > 0)
{
s.Position = header.HeightsOffset;
for (var i = 0; i < MapSize.X; i++)
for (var j = 0; j < MapSize.Y; j++)
Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
}
}
if (Grid.MaximumTerrainHeight > 0)
{
Tiles.CellEntryChanged += UpdateProjection;
Height.CellEntryChanged += UpdateProjection;
}
PostInit(); PostInit();
Uid = ComputeUID(Package); Uid = ComputeUID(Package);
@@ -274,21 +292,19 @@ namespace OpenRA
void PostInit() void PostInit()
{ {
rules = Exts.Lazy(() => try
{ {
try Rules = Ruleset.Load(modData, this, Tileset, RuleDefinitions, WeaponDefinitions,
{ VoiceDefinitions, NotificationDefinitions, MusicDefinitions, SequenceDefinitions);
return Ruleset.Load(modData, this, Tileset, RuleDefinitions, WeaponDefinitions, }
VoiceDefinitions, NotificationDefinitions, MusicDefinitions, SequenceDefinitions); catch (Exception e)
} {
catch (Exception e) InvalidCustomRules = true;
{ Rules = Ruleset.LoadDefaultsForTileSet(modData, Tileset);
InvalidCustomRules = true; 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 Ruleset.LoadDefaultsForTileSet(modData, Tileset); Rules.Sequences.Preload();
});
var tl = new MPos(0, 0).ToCPos(this); var tl = new MPos(0, 0).ToCPos(this);
var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this); var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);
@@ -360,7 +376,7 @@ namespace OpenRA
PPos[] ProjectCellInner(MPos uv) PPos[] ProjectCellInner(MPos uv)
{ {
var mapHeight = MapHeight.Value; var mapHeight = Height;
if (!mapHeight.Contains(uv)) if (!mapHeight.Contains(uv))
return NoProjectedCells; return NoProjectedCells;
@@ -371,7 +387,7 @@ namespace OpenRA
// Odd-height ramps get bumped up a level to the next even height layer // Odd-height ramps get bumped up a level to the next even height layer
if ((height & 1) == 1) if ((height & 1) == 1)
{ {
var ti = Rules.TileSet.GetTileInfo(MapTiles.Value[uv]); var ti = Rules.TileSet.GetTileInfo(Tiles[uv]);
if (ti != null && ti.RampType != 0) if (ti != null && ti.RampType != 0)
height += 1; height += 1;
} }
@@ -396,11 +412,6 @@ namespace OpenRA
return candidates.Where(c => mapHeight.Contains((MPos)c)).ToArray(); return candidates.Where(c => mapHeight.Contains((MPos)c)).ToArray();
} }
public Ruleset PreloadRules()
{
return rules.Value;
}
public void Save(IReadWritePackage toPackage) public void Save(IReadWritePackage toPackage)
{ {
MapFormat = SupportedMapFormat; MapFormat = SupportedMapFormat;
@@ -468,84 +479,6 @@ namespace OpenRA
Uid = ComputeUID(toPackage); Uid = ComputeUID(toPackage);
} }
public CellLayer<TerrainTile> LoadMapTiles()
{
var tiles = new CellLayer<TerrainTile>(this);
using (var s = Package.GetStream("map.bin"))
{
var header = new BinaryDataHeader(s, MapSize);
if (header.TilesOffset > 0)
{
s.Position = header.TilesOffset;
for (var i = 0; i < MapSize.X; i++)
{
for (var j = 0; j < MapSize.Y; j++)
{
var tile = s.ReadUInt16();
var index = s.ReadUInt8();
// TODO: Remember to remove this when rewriting tile variants / PickAny
if (index == byte.MaxValue)
index = (byte)(i % 4 + (j % 4) * 4);
tiles[new MPos(i, j)] = new TerrainTile(tile, index);
}
}
}
}
if (Grid.MaximumTerrainHeight > 0)
tiles.CellEntryChanged += UpdateProjection;
return tiles;
}
public CellLayer<byte> LoadMapHeight()
{
var tiles = new CellLayer<byte>(this);
using (var s = Package.GetStream("map.bin"))
{
var header = new BinaryDataHeader(s, MapSize);
if (header.HeightsOffset > 0)
{
s.Position = header.HeightsOffset;
for (var i = 0; i < MapSize.X; i++)
for (var j = 0; j < MapSize.Y; j++)
tiles[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
}
}
if (Grid.MaximumTerrainHeight > 0)
tiles.CellEntryChanged += UpdateProjection;
return tiles;
}
public CellLayer<ResourceTile> LoadResourceTiles()
{
var resources = new CellLayer<ResourceTile>(this);
using (var s = Package.GetStream("map.bin"))
{
var header = new BinaryDataHeader(s, MapSize);
if (header.ResourcesOffset > 0)
{
s.Position = header.ResourcesOffset;
for (var i = 0; i < MapSize.X; i++)
{
for (var j = 0; j < MapSize.Y; j++)
{
var type = s.ReadUInt8();
var density = s.ReadUInt8();
resources[new MPos(i, j)] = new ResourceTile(type, density);
}
}
}
}
return resources;
}
public byte[] SaveBinaryData() public byte[] SaveBinaryData()
{ {
var dataStream = new MemoryStream(); var dataStream = new MemoryStream();
@@ -574,7 +507,7 @@ namespace OpenRA
{ {
for (var j = 0; j < MapSize.Y; j++) for (var j = 0; j < MapSize.Y; j++)
{ {
var tile = MapTiles.Value[new MPos(i, j)]; var tile = Tiles[new MPos(i, j)];
writer.Write(tile.Type); writer.Write(tile.Type);
writer.Write(tile.Index); writer.Write(tile.Index);
} }
@@ -585,7 +518,7 @@ namespace OpenRA
if (heightsOffset != 0) if (heightsOffset != 0)
for (var i = 0; i < MapSize.X; i++) for (var i = 0; i < MapSize.X; i++)
for (var j = 0; j < MapSize.Y; j++) for (var j = 0; j < MapSize.Y; j++)
writer.Write(MapHeight.Value[new MPos(i, j)]); writer.Write(Height[new MPos(i, j)]);
// Resource data // Resource data
if (resourcesOffset != 0) if (resourcesOffset != 0)
@@ -594,7 +527,7 @@ namespace OpenRA
{ {
for (var j = 0; j < MapSize.Y; j++) for (var j = 0; j < MapSize.Y; j++)
{ {
var tile = MapResources.Value[new MPos(i, j)]; var tile = Resources[new MPos(i, j)];
writer.Write(tile.Type); writer.Write(tile.Type);
writer.Write(tile.Index); writer.Write(tile.Index);
} }
@@ -641,7 +574,7 @@ namespace OpenRA
for (var x = 0; x < width; x++) for (var x = 0; x < width; x++)
{ {
var uv = new MPos(x + Bounds.Left, y + Bounds.Top); var uv = new MPos(x + Bounds.Left, y + Bounds.Top);
var resourceType = MapResources.Value[uv].Type; var resourceType = Resources[uv].Type;
if (resourceType != 0) if (resourceType != 0)
{ {
// Cell contains resources // Cell contains resources
@@ -654,7 +587,7 @@ namespace OpenRA
else else
{ {
// Cell contains terrain // Cell contains terrain
var type = tileset.GetTileInfo(MapTiles.Value[uv]); var type = tileset.GetTileInfo(Tiles[uv]);
leftColor = type != null ? type.LeftColor : Color.Black; leftColor = type != null ? type.LeftColor : Color.Black;
rightColor = type != null ? type.RightColor : Color.Black; rightColor = type != null ? type.RightColor : Color.Black;
} }
@@ -698,7 +631,7 @@ namespace OpenRA
{ {
// The first check ensures that the cell is within the valid map region, avoiding // The first check ensures that the cell is within the valid map region, avoiding
// potential crashes in deeper code. All CellLayers have the same geometry, and // potential crashes in deeper code. All CellLayers have the same geometry, and
// CustomTerrain is convenient (cellProjection may be null and others are Lazy). // CustomTerrain is convenient.
return CustomTerrain.Contains(uv) && ContainsAllProjectedCellsCovering(uv); return CustomTerrain.Contains(uv) && ContainsAllProjectedCellsCovering(uv);
} }
@@ -736,7 +669,7 @@ namespace OpenRA
// (b) Therefore: // (b) Therefore:
// - ax + by adds (a - b) * 512 + 512 to u // - ax + by adds (a - b) * 512 + 512 to u
// - ax + by adds (a + b) * 512 + 512 to v // - ax + by adds (a + b) * 512 + 512 to v
var z = MapHeight.Value.Contains(cell) ? 512 * MapHeight.Value[cell] : 0; var z = Height.Contains(cell) ? 512 * Height[cell] : 0;
return new WPos(512 * (cell.X - cell.Y + 1), 512 * (cell.X + cell.Y + 1), z); return new WPos(512 * (cell.X - cell.Y + 1), 512 * (cell.X + cell.Y + 1), z);
} }
@@ -815,14 +748,14 @@ namespace OpenRA
public void Resize(int width, int height) public void Resize(int width, int height)
{ {
var oldMapTiles = MapTiles.Value; var oldMapTiles = Tiles;
var oldMapResources = MapResources.Value; var oldMapResources = Resources;
var oldMapHeight = MapHeight.Value; var oldMapHeight = Height;
var newSize = new Size(width, height); var newSize = new Size(width, height);
MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero])); Tiles = CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]);
MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero])); Resources = CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]);
MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero])); Height = CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]);
MapSize = new int2(newSize); MapSize = new int2(newSize);
var tl = new MPos(0, 0); var tl = new MPos(0, 0);
@@ -864,8 +797,8 @@ namespace OpenRA
{ {
for (var i = Bounds.Left; i < Bounds.Right; i++) for (var i = Bounds.Left; i < Bounds.Right; i++)
{ {
var type = MapTiles.Value[new MPos(i, j)].Type; var type = Tiles[new MPos(i, j)].Type;
var index = MapTiles.Value[new MPos(i, j)].Index; var index = Tiles[new MPos(i, j)].Index;
if (!tileset.Templates.ContainsKey(type)) if (!tileset.Templates.ContainsKey(type))
{ {
Console.WriteLine("Unknown Tile ID {0}".F(type)); Console.WriteLine("Unknown Tile ID {0}".F(type));
@@ -877,7 +810,7 @@ namespace OpenRA
continue; continue;
index = (byte)r.Next(0, template.TilesCount); index = (byte)r.Next(0, template.TilesCount);
MapTiles.Value[new MPos(i, j)] = new TerrainTile(type, index); Tiles[new MPos(i, j)] = new TerrainTile(type, index);
} }
} }
} }
@@ -895,7 +828,7 @@ namespace OpenRA
// Invalidate the entry for a cell if anything could cause the terrain index to change. // Invalidate the entry for a cell if anything could cause the terrain index to change.
Action<CPos> invalidateTerrainIndex = c => cachedTerrainIndexes[c] = InvalidCachedTerrainIndex; Action<CPos> invalidateTerrainIndex = c => cachedTerrainIndexes[c] = InvalidCachedTerrainIndex;
CustomTerrain.CellEntryChanged += invalidateTerrainIndex; CustomTerrain.CellEntryChanged += invalidateTerrainIndex;
MapTiles.Value.CellEntryChanged += invalidateTerrainIndex; Tiles.CellEntryChanged += invalidateTerrainIndex;
} }
var uv = cell.ToMPos(this); var uv = cell.ToMPos(this);
@@ -906,7 +839,7 @@ namespace OpenRA
{ {
var custom = CustomTerrain[uv]; var custom = CustomTerrain[uv];
terrainIndex = cachedTerrainIndexes[uv] = terrainIndex = cachedTerrainIndexes[uv] =
custom != byte.MaxValue ? custom : Rules.TileSet.GetTerrainIndex(MapTiles.Value[uv]); custom != byte.MaxValue ? custom : Rules.TileSet.GetTerrainIndex(Tiles[uv]);
} }
return (byte)terrainIndex; return (byte)terrainIndex;
@@ -1116,7 +1049,7 @@ namespace OpenRA
Func<CPos, bool> valid = Contains; Func<CPos, bool> valid = Contains;
if (allowOutsideBounds) if (allowOutsideBounds)
valid = MapTiles.Value.Contains; valid = Tiles.Contains;
for (var i = minRange; i <= maxRange; i++) for (var i = minRange; i <= maxRange; i++)
{ {

View File

@@ -44,8 +44,8 @@ namespace OpenRA
var maxHeight = map.Grid.MaximumTerrainHeight; var maxHeight = map.Grid.MaximumTerrainHeight;
var heightOffset = map.Grid.Type == MapGridType.RectangularIsometric ? maxHeight : maxHeight / 2; var heightOffset = map.Grid.Type == MapGridType.RectangularIsometric ? maxHeight : maxHeight / 2;
// Use the MapHeight data array to clamp the bottom coordinate so it doesn't overflow the map // Use the map Height data array to clamp the bottom coordinate so it doesn't overflow the map
mapBottomRight = map.MapHeight.Value.Clamp(new MPos(bottomRight.U, bottomRight.V + heightOffset)); mapBottomRight = map.Height.Clamp(new MPos(bottomRight.U, bottomRight.V + heightOffset));
} }
public bool Contains(PPos puv) public bool Contains(PPos puv)

View File

@@ -186,19 +186,15 @@ namespace OpenRA
if (MapCache[uid].Status != MapStatus.Available) if (MapCache[uid].Status != MapStatus.Available)
throw new InvalidDataException("Invalid map uid: {0}".F(uid)); throw new InvalidDataException("Invalid map uid: {0}".F(uid));
// Operate on a copy of the map to avoid gameplay state leaking into the cache Map map;
var map = new Map(this, MapCache[uid].Package); using (new Support.PerfTimer("Map"))
map = new Map(this, MapCache[uid].Package);
LoadTranslations(map); LoadTranslations(map);
// Reinitialize all our assets // Reinitialize all our assets
InitializeLoaders(map); InitializeLoaders(map);
using (new Support.PerfTimer("Map.PreloadRules"))
map.PreloadRules();
using (new Support.PerfTimer("Map.SequenceProvider.Preload"))
map.Rules.Sequences.Preload();
// Load music with map assets mounted // Load music with map assets mounted
using (new Support.PerfTimer("Map.Music")) using (new Support.PerfTimer("Map.Music"))
foreach (var entry in map.Rules.Music) foreach (var entry in map.Rules.Music)

View File

@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
{ {
var type = ms.ReadUInt8(); var type = ms.ReadUInt8();
var index = ms.ReadUInt8(); var index = ms.ReadUInt8();
Map.MapTiles.Value[new CPos(i, j)] = new TerrainTile(type, index); Map.Tiles[new CPos(i, j)] = new TerrainTile(type, index);
} }
} }
} }
@@ -96,7 +96,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
if (overlayResourceMapping.ContainsKey(type)) if (overlayResourceMapping.ContainsKey(type))
res = overlayResourceMapping[type]; res = overlayResourceMapping[type];
Map.MapResources.Value[cell] = new ResourceTile(res.First, res.Second); Map.Resources[cell] = new ResourceTile(res.First, res.Second);
if (overlayActors.Contains(type)) if (overlayActors.Contains(type))
{ {
var ar = new ActorReference(type) var ar = new ActorReference(type)

View File

@@ -95,7 +95,7 @@ namespace OpenRA.Mods.Common.Widgets
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{ {
// Check the actor is inside the map // Check the actor is inside the map
if (!footprint.All(c => world.Map.MapTiles.Value.Contains(cell + locationOffset + c))) if (!footprint.All(c => world.Map.Tiles.Contains(cell + locationOffset + c)))
return true; return true;
var newActorReference = new ActorReference(Actor.Name); var newActorReference = new ActorReference(Actor.Name);

View File

@@ -94,9 +94,9 @@ namespace OpenRA.Mods.Common.Widgets
void Copy(CellRegion source, CVec offset) void Copy(CellRegion source, CVec offset)
{ {
var gridType = worldRenderer.World.Map.Grid.Type; var gridType = worldRenderer.World.Map.Grid.Type;
var mapTiles = worldRenderer.World.Map.MapTiles.Value; var mapTiles = worldRenderer.World.Map.Tiles;
var mapHeight = worldRenderer.World.Map.MapHeight.Value; var mapHeight = worldRenderer.World.Map.Height;
var mapResources = worldRenderer.World.Map.MapResources.Value; var mapResources = worldRenderer.World.Map.Resources;
var dest = new CellRegion(gridType, source.TopLeft + offset, source.BottomRight + offset); var dest = new CellRegion(gridType, source.TopLeft + offset, source.BottomRight + offset);

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Widgets
var underCursor = editorLayer.PreviewsAt(worldPixel).MinByOrDefault(CalculateActorSelectionPriority); var underCursor = editorLayer.PreviewsAt(worldPixel).MinByOrDefault(CalculateActorSelectionPriority);
var mapResources = world.Map.MapResources.Value; var mapResources = world.Map.Resources;
ResourceType type; ResourceType type;
if (underCursor != null) if (underCursor != null)
editorWidget.SetTooltip(underCursor.Tooltip); editorWidget.SetTooltip(underCursor.Tooltip);

View File

@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.Widgets
{ {
var type = (byte)ResourceType.ResourceType; var type = (byte)ResourceType.ResourceType;
var index = (byte)ResourceType.MaxDensity; var index = (byte)ResourceType.MaxDensity;
world.Map.MapResources.Value[cell] = new ResourceTile(type, index); world.Map.Resources[cell] = new ResourceTile(type, index);
} }
return true; return true;
@@ -77,11 +77,11 @@ namespace OpenRA.Mods.Common.Widgets
public bool AllowResourceAt(CPos cell) public bool AllowResourceAt(CPos cell)
{ {
var mapResources = world.Map.MapResources.Value; var mapResources = world.Map.Resources;
if (!mapResources.Contains(cell)) if (!mapResources.Contains(cell))
return false; return false;
var tile = world.Map.MapTiles.Value[cell]; var tile = world.Map.Tiles[cell];
var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile); var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile);
if (tileInfo == null) if (tileInfo == null)
return false; return false;

View File

@@ -97,8 +97,8 @@ namespace OpenRA.Mods.Common.Widgets
void PaintCell(CPos cell, bool isMoving) void PaintCell(CPos cell, bool isMoving)
{ {
var map = world.Map; var map = world.Map;
var mapTiles = map.MapTiles.Value; var mapTiles = map.Tiles;
var mapHeight = map.MapHeight.Value; var mapHeight = map.Height;
var tileset = map.Rules.TileSet; var tileset = map.Rules.TileSet;
var template = tileset.Templates[Template]; var template = tileset.Templates[Template];
@@ -129,7 +129,7 @@ namespace OpenRA.Mods.Common.Widgets
void FloodFillWithBrush(CPos cell, bool isMoving) void FloodFillWithBrush(CPos cell, bool isMoving)
{ {
var map = world.Map; var map = world.Map;
var mapTiles = map.MapTiles.Value; var mapTiles = map.Tiles;
var replace = mapTiles[cell]; var replace = mapTiles[cell];
if (replace.Type == Template) if (replace.Type == Template)
@@ -203,7 +203,7 @@ namespace OpenRA.Mods.Common.Widgets
bool PlacementOverlapsSameTemplate(TerrainTemplateInfo template, CPos cell) bool PlacementOverlapsSameTemplate(TerrainTemplateInfo template, CPos cell)
{ {
var map = world.Map; var map = world.Map;
var mapTiles = map.MapTiles.Value; var mapTiles = map.Tiles;
var i = 0; var i = 0;
for (var y = 0; y < template.Size.Y; y++) for (var y = 0; y < template.Size.Y; y++)
{ {

View File

@@ -447,7 +447,7 @@ namespace OpenRA.Mods.Common.Effects
if (!world.Map.Contains(world.Map.CellContaining(posProbe))) if (!world.Map.Contains(world.Map.CellContaining(posProbe)))
break; break;
var ht = world.Map.MapHeight.Value[world.Map.CellContaining(posProbe)] * 512; var ht = world.Map.Height[world.Map.CellContaining(posProbe)] * 512;
curDist += stepSize; curDist += stepSize;
if (ht > predClfHgt) if (ht > predClfHgt)

View File

@@ -10,6 +10,7 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Traits; using OpenRA.Traits;
@@ -46,14 +47,18 @@ namespace OpenRA.Mods.Common.Lint
if (worldActor.HasTraitInfo<MPStartLocationsInfo>()) if (worldActor.HasTraitInfo<MPStartLocationsInfo>())
{ {
var multiPlayers = players.Count(p => p.Value.Playable); var playerCount = players.Count(p => p.Value.Playable);
var spawns = map.ActorDefinitions.Where(a => a.Value.Value == "mpspawn"); var spawns = new List<CPos>();
var spawnCount = spawns.Count(); foreach (var kv in map.ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
{
var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
}
if (multiPlayers > spawnCount) if (playerCount > spawns.Count)
emitError("The map allows {0} possible players, but defines only {1} spawn points".F(multiPlayers, spawnCount)); emitError("The map allows {0} possible players, but defines only {1} spawn points".F(playerCount, spawns.Count));
if (map.SpawnPoints.Value.Distinct().Count() != spawnCount) if (spawns.Distinct().Count() != spawns.Count)
emitError("Duplicate spawn point locations detected."); emitError("Duplicate spawn point locations detected.");
} }

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
if (!bi.AllowInvalidPlacement && world.ActorMap.GetActorsAt(cell).Any(a => a != toIgnore)) if (!bi.AllowInvalidPlacement && world.ActorMap.GetActorsAt(cell).Any(a => a != toIgnore))
return false; return false;
var tile = world.Map.MapTiles.Value[cell]; var tile = world.Map.Tiles[cell];
var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile); var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile);
// TODO: This is bandaiding over bogus tilesets. // TODO: This is bandaiding over bogus tilesets.

View File

@@ -49,7 +49,6 @@ namespace OpenRA.Mods.Common.Traits
var world = self.World; var world = self.World;
var map = world.Map; var map = world.Map;
var tiles = map.MapTiles.Value;
var pos = map.CellContaining(self.CenterPosition); var pos = map.CellContaining(self.CenterPosition);
var terrainType = map.GetTerrainInfo(pos).Type; var terrainType = map.GetTerrainInfo(pos).Type;

View File

@@ -158,7 +158,6 @@ namespace OpenRA.Mods.Common.Traits
if (!checkTerrainType) if (!checkTerrainType)
return true; return true;
var tiles = self.World.Map.MapTiles.Value;
var terrainType = self.World.Map.GetTerrainInfo(self.Location).Type; var terrainType = self.World.Map.GetTerrainInfo(self.Location).Type;
return info.AllowedTerrainTypes.Contains(terrainType); return info.AllowedTerrainTypes.Contains(terrainType);
@@ -172,7 +171,7 @@ namespace OpenRA.Mods.Common.Traits
var ramp = 0; var ramp = 0;
if (self.World.Map.Contains(self.Location)) if (self.World.Map.Contains(self.Location))
{ {
var tile = self.World.Map.MapTiles.Value[self.Location]; var tile = self.World.Map.Tiles[self.Location];
var ti = self.World.Map.Rules.TileSet.GetTileInfo(tile); var ti = self.World.Map.Rules.TileSet.GetTileInfo(tile);
if (ti != null) if (ti != null)
ramp = ti.RampType; ramp = ti.RampType;

View File

@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
} }
// Take all templates to overlay from the map // Take all templates to overlay from the map
foreach (var cell in w.Map.AllCells.Where(cell => bridgeTypes.ContainsKey(w.Map.MapTiles.Value[cell].Type))) foreach (var cell in w.Map.AllCells.Where(cell => bridgeTypes.ContainsKey(w.Map.Tiles[cell].Type)))
ConvertBridgeToActor(w, cell); ConvertBridgeToActor(w, cell);
// Link adjacent (long)-bridges so that artwork is updated correctly // Link adjacent (long)-bridges so that artwork is updated correctly
@@ -65,8 +65,8 @@ namespace OpenRA.Mods.Common.Traits
return; return;
// Correlate the tile "image" aka subtile with its position to find the template origin // Correlate the tile "image" aka subtile with its position to find the template origin
var tile = w.Map.MapTiles.Value[cell].Type; var tile = w.Map.Tiles[cell].Type;
var index = w.Map.MapTiles.Value[cell].Index; var index = w.Map.Tiles[cell].Index;
var template = w.Map.Rules.TileSet.Templates[tile]; var template = w.Map.Rules.TileSet.Templates[tile];
var ni = cell.X - index % template.Size.X; var ni = cell.X - index % template.Size.X;
var nj = cell.Y - index / template.Size.X; var nj = cell.Y - index / template.Size.X;
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
}).Trait<Bridge>(); }).Trait<Bridge>();
var subTiles = new Dictionary<CPos, byte>(); var subTiles = new Dictionary<CPos, byte>();
var mapTiles = w.Map.MapTiles.Value; var mapTiles = w.Map.Tiles;
// For each subtile in the template // For each subtile in the template
for (byte ind = 0; ind < template.Size.X * template.Size.Y; ind++) for (byte ind = 0; ind < template.Size.X * template.Size.Y; ind++)

View File

@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
Resources = self.TraitsImplementing<ResourceType>() Resources = self.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.ResourceType, r => r); .ToDictionary(r => r.Info.ResourceType, r => r);
Map.MapResources.Value.CellEntryChanged += UpdateCell; Map.Resources.CellEntryChanged += UpdateCell;
} }
public void WorldLoaded(World w, WorldRenderer wr) public void WorldLoaded(World w, WorldRenderer wr)
@@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Traits
public void UpdateCell(CPos cell) public void UpdateCell(CPos cell)
{ {
var uv = cell.ToMPos(Map); var uv = cell.ToMPos(Map);
var tile = Map.MapResources.Value[uv]; var tile = Map.Resources[uv];
var t = Tiles[cell]; var t = Tiles[cell];
if (t.Density > 0) if (t.Density > 0)
@@ -127,7 +127,7 @@ namespace OpenRA.Mods.Common.Traits
// Set density based on the number of neighboring resources // Set density based on the number of neighboring resources
var adjacent = 0; var adjacent = 0;
var type = Tiles[c].Type; var type = Tiles[c].Type;
var resources = Map.MapResources.Value; var resources = Map.Resources;
for (var u = -1; u < 2; u++) for (var u = -1; u < 2; u++)
{ {
for (var v = -1; v < 2; v++) for (var v = -1; v < 2; v++)
@@ -205,7 +205,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var kv in spriteLayers.Values) foreach (var kv in spriteLayers.Values)
kv.Dispose(); kv.Dispose();
Map.MapResources.Value.CellEntryChanged -= UpdateCell; Map.Resources.CellEntryChanged -= UpdateCell;
disposed = true; disposed = true;
} }

View File

@@ -38,7 +38,10 @@ namespace OpenRA.Mods.Common.Traits
public void WorldLoaded(World world, WorldRenderer wr) public void WorldLoaded(World world, WorldRenderer wr)
{ {
var spawns = world.Map.SpawnPoints.Value; var spawns = world.Actors.Where(a => a.Info.Name == "mpspawn")
.Select(a => a.Location)
.ToArray();
var taken = world.LobbyInfo.Clients.Where(c => c.SpawnPoint != 0 && c.Slot != null) var taken = world.LobbyInfo.Clients.Where(c => c.SpawnPoint != 0 && c.Slot != null)
.Select(c => spawns[c.SpawnPoint - 1]).ToList(); .Select(c => spawns[c.SpawnPoint - 1]).ToList();
var available = spawns.Except(taken).ToList(); var available = spawns.Except(taken).ToList();

View File

@@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var cell in w.Map.AllCells) foreach (var cell in w.Map.AllCells)
{ {
ResourceType t; ResourceType t;
if (!resources.TryGetValue(w.Map.MapResources.Value[cell].Type, out t)) if (!resources.TryGetValue(w.Map.Resources[cell].Type, out t))
continue; continue;
if (!AllowResourceAt(t, cell)) if (!AllowResourceAt(t, cell))
@@ -193,7 +193,7 @@ namespace OpenRA.Mods.Common.Traits
if (!rt.Info.AllowOnRamps) if (!rt.Info.AllowOnRamps)
{ {
var tile = world.Map.MapTiles.Value[cell]; var tile = world.Map.Tiles[cell];
var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile); var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile);
if (tileInfo != null && tileInfo.RampType > 0) if (tileInfo != null && tileInfo.RampType > 0)
return false; return false;

View File

@@ -57,11 +57,11 @@ namespace OpenRA.Mods.Common.Traits
foreach (var uv in wr.Viewport.AllVisibleCells.CandidateMapCoords) foreach (var uv in wr.Viewport.AllVisibleCells.CandidateMapCoords)
{ {
if (!map.MapHeight.Value.Contains(uv)) if (!map.Height.Contains(uv))
continue; continue;
var height = (int)map.MapHeight.Value[uv]; var height = (int)map.Height[uv];
var tile = map.MapTiles.Value[uv]; var tile = map.Tiles[uv];
var ti = tileSet.GetTileInfo(tile); var ti = tileSet.GetTileInfo(tile);
var ramp = ti != null ? ti.RampType : 0; var ramp = ti != null ? ti.RampType : 0;

View File

@@ -87,7 +87,6 @@ namespace OpenRA.Mods.Common.UtilityCommands
foreach (var testMap in maps) foreach (var testMap in maps)
{ {
Console.WriteLine("Testing map: {0}".F(testMap.Title)); Console.WriteLine("Testing map: {0}".F(testMap.Title));
testMap.PreloadRules();
// Run all rule checks on the map if it defines custom rules. // Run all rule checks on the map if it defines custom rules.
if (testMap.RuleDefinitions != null || testMap.VoiceDefinitions != null || testMap.WeaponDefinitions != null) if (testMap.RuleDefinitions != null || testMap.VoiceDefinitions != null || testMap.WeaponDefinitions != null)

View File

@@ -35,6 +35,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
public Map Map; public Map Map;
public List<string> Players = new List<string>(); public List<string> Players = new List<string>();
public MapPlayers MapPlayers; public MapPlayers MapPlayers;
int spawnCount;
public bool ValidateArguments(string[] args) public bool ValidateArguments(string[] args)
{ {
@@ -81,12 +82,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
LoadSmudges(file, "SMUDGE"); LoadSmudges(file, "SMUDGE");
var waypoints = file.GetSection("Waypoints"); var waypoints = file.GetSection("Waypoints");
LoadWaypoints(Map, waypoints, MapSize); LoadWaypoints(waypoints);
// Create default player definitions only if there are no players to import // Create default player definitions only if there are no players to import
MapPlayers = new MapPlayers(Map.Rules, (Players.Count == 0) ? Map.SpawnPoints.Value.Length : 0); MapPlayers = new MapPlayers(Map.Rules, Players.Count == 0 ? spawnCount : 0);
foreach (var p in Players) foreach (var p in Players)
LoadPlayer(file, p); LoadPlayer(file, p);
Map.PlayerDefinitions = MapPlayers.ToMiniYaml(); Map.PlayerDefinitions = MapPlayers.ToMiniYaml();
} }
@@ -235,13 +237,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
return new int2(offset % mapSize, offset / mapSize); return new int2(offset % mapSize, offset / mapSize);
} }
static void LoadWaypoints(Map map, IniSection waypointSection, int mapSize) void LoadWaypoints(IniSection waypointSection)
{ {
var actorCount = map.ActorDefinitions.Count; var actorCount = Map.ActorDefinitions.Count;
var wps = waypointSection var wps = waypointSection
.Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0) .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
.Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key), .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize))); LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), MapSize)));
// Add waypoint actors // Add waypoint actors
foreach (var kv in wps) foreach (var kv in wps)
@@ -254,7 +256,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
new OwnerInit("Neutral") new OwnerInit("Neutral")
}; };
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save())); Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
spawnCount++;
} }
else else
{ {
@@ -264,7 +267,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
new OwnerInit("Neutral") new OwnerInit("Neutral")
}; };
map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save())); Map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save()));
} }
} }
} }

View File

@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var br = new PPos(width, height + maxTerrainHeight); var br = new PPos(width, height + maxTerrainHeight);
map.SetBounds(tl, br); map.SetBounds(tl, br);
map.PlayerDefinitions = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length).ToMiniYaml(); map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml();
map.FixOpenAreas(); map.FixOpenAreas();
Action<string> afterSave = uid => Action<string> afterSave = uid =>

View File

@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Widgets
foreach (var cell in world.Map.AllCells) foreach (var cell in world.Map.AllCells)
UpdateTerrainCell(cell); UpdateTerrainCell(cell);
world.Map.MapTiles.Value.CellEntryChanged += UpdateTerrainCell; world.Map.Tiles.CellEntryChanged += UpdateTerrainCell;
world.Map.CustomTerrain.CellEntryChanged += UpdateTerrainCell; world.Map.CustomTerrain.CellEntryChanged += UpdateTerrainCell;
} }
@@ -140,7 +140,7 @@ namespace OpenRA.Mods.Common.Widgets
int leftColor, rightColor; int leftColor, rightColor;
if (custom == byte.MaxValue) if (custom == byte.MaxValue)
{ {
var type = world.Map.Rules.TileSet.GetTileInfo(world.Map.MapTiles.Value[uv]); var type = world.Map.Rules.TileSet.GetTileInfo(world.Map.Tiles[uv]);
leftColor = type != null ? type.LeftColor.ToArgb() : Color.Black.ToArgb(); leftColor = type != null ? type.LeftColor.ToArgb() : Color.Black.ToArgb();
rightColor = type != null ? type.RightColor.ToArgb() : Color.Black.ToArgb(); rightColor = type != null ? type.RightColor.ToArgb() : Color.Black.ToArgb();
} }
@@ -444,7 +444,7 @@ namespace OpenRA.Mods.Common.Widgets
public override void Removed() public override void Removed()
{ {
base.Removed(); base.Removed();
world.Map.MapTiles.Value.CellEntryChanged -= UpdateTerrainCell; world.Map.Tiles.CellEntryChanged -= UpdateTerrainCell;
world.Map.CustomTerrain.CellEntryChanged -= UpdateTerrainCell; world.Map.CustomTerrain.CellEntryChanged -= UpdateTerrainCell;
Dispose(); Dispose();
} }

View File

@@ -263,6 +263,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands
Size mapSize; Size mapSize;
TileSet tileSet; TileSet tileSet;
List<TerrainTemplateInfo> tileSetsFromYaml; List<TerrainTemplateInfo> tileSetsFromYaml;
int playerCount;
D2kMapImporter(string filename, string tileset, Ruleset rules) D2kMapImporter(string filename, string tileset, Ruleset rules)
{ {
@@ -293,13 +294,12 @@ namespace OpenRA.Mods.D2k.UtilityCommands
public static Map Import(string filename, string mod, string tileset, Ruleset rules) public static Map Import(string filename, string mod, string tileset, Ruleset rules)
{ {
var map = new D2kMapImporter(filename, tileset, rules).map; var importer = new D2kMapImporter(filename, tileset, rules);
var map = importer.map;
if (map == null) if (map == null)
return null; return null;
map.RequiresMod = mod; map.RequiresMod = mod;
var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
map.PlayerDefinitions = players.ToMiniYaml();
return map; return map;
} }
@@ -324,6 +324,9 @@ namespace OpenRA.Mods.D2k.UtilityCommands
// Each frame is a tile from the Dune 2000 tileset files, with the Frame ID being the index of the tile in the original file // Each frame is a tile from the Dune 2000 tileset files, with the Frame ID being the index of the tile in the original file
tileSetsFromYaml = tileSet.Templates.Where(t => t.Value.Frames != null tileSetsFromYaml = tileSet.Templates.Where(t => t.Value.Frames != null
&& t.Value.Images[0].ToLower() == tilesetName.ToLower()).Select(ts => ts.Value).ToList(); && t.Value.Images[0].ToLower() == tilesetName.ToLower()).Select(ts => ts.Value).ToList();
var players = new MapPlayers(map.Rules, playerCount);
map.PlayerDefinitions = players.ToMiniYaml();
} }
void FillMap() void FillMap()
@@ -336,13 +339,13 @@ namespace OpenRA.Mods.D2k.UtilityCommands
var locationOnMap = GetCurrentTilePositionOnMap(); var locationOnMap = GetCurrentTilePositionOnMap();
map.MapTiles.Value[locationOnMap] = tile; map.Tiles[locationOnMap] = tile;
// Spice // Spice
if (tileSpecialInfo == 1) if (tileSpecialInfo == 1)
map.MapResources.Value[locationOnMap] = new ResourceTile(1, 1); map.Resources[locationOnMap] = new ResourceTile(1, 1);
if (tileSpecialInfo == 2) if (tileSpecialInfo == 2)
map.MapResources.Value[locationOnMap] = new ResourceTile(1, 2); map.Resources[locationOnMap] = new ResourceTile(1, 2);
// Actors // Actors
if (ActorDataByActorCode.ContainsKey(tileSpecialInfo)) if (ActorDataByActorCode.ContainsKey(tileSpecialInfo))
@@ -356,7 +359,11 @@ namespace OpenRA.Mods.D2k.UtilityCommands
new LocationInit(locationOnMap), new LocationInit(locationOnMap),
new OwnerInit(kvp.Second) new OwnerInit(kvp.Second)
}; };
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, a.Save())); map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, a.Save()));
if (kvp.First == "mpspawn")
playerCount++;
} }
} }
} }

View File

@@ -79,7 +79,7 @@ namespace OpenRA.Mods.RA.UtilityCommands
for (var j = 0; j < MapSize; j++) for (var j = 0; j < MapSize; j++)
for (var i = 0; i < MapSize; i++) for (var i = 0; i < MapSize; i++)
Map.MapTiles.Value[new CPos(i, j)] = new TerrainTile(types[i, j], ms.ReadUInt8()); Map.Tiles[new CPos(i, j)] = new TerrainTile(types[i, j], ms.ReadUInt8());
} }
static string[] overlayActors = new string[] static string[] overlayActors = new string[]
@@ -104,7 +104,7 @@ namespace OpenRA.Mods.RA.UtilityCommands
res = overlayResourceMapping[redAlertOverlayNames[o]]; res = overlayResourceMapping[redAlertOverlayNames[o]];
var cell = new CPos(i, j); var cell = new CPos(i, j);
Map.MapResources.Value[cell] = new ResourceTile(res.First, res.Second); Map.Resources[cell] = new ResourceTile(res.First, res.Second);
if (o != 255 && overlayActors.Contains(redAlertOverlayNames[o])) if (o != 255 && overlayActors.Contains(redAlertOverlayNames[o]))
{ {

View File

@@ -232,9 +232,9 @@ namespace OpenRA.Mods.TS.UtilityCommands
map.Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)); map.Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename));
map.Author = "Westwood Studios"; map.Author = "Westwood Studios";
map.Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]); map.Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]);
map.MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(map.Grid.Type, size)); map.Resources = new CellLayer<ResourceTile>(map.Grid.Type, size);
map.MapTiles = Exts.Lazy(() => new CellLayer<TerrainTile>(map.Grid.Type, size)); map.Tiles = new CellLayer<TerrainTile>(map.Grid.Type, size);
map.MapHeight = Exts.Lazy(() => new CellLayer<byte>(map.Grid.Type, size)); map.Height = new CellLayer<byte>(map.Grid.Type, size);
map.RequiresMod = modData.Manifest.Mod.Id; map.RequiresMod = modData.Manifest.Mod.Id;
@@ -268,13 +268,13 @@ namespace OpenRA.Mods.TS.UtilityCommands
var mapCell = new MPos(dx / 2, dy); var mapCell = new MPos(dx / 2, dy);
var cell = mapCell.ToCPos(map); var cell = mapCell.ToCPos(map);
if (map.MapTiles.Value.Contains(cell)) if (map.Tiles.Contains(cell))
{ {
if (!tileset.Templates.ContainsKey(tilenum)) if (!tileset.Templates.ContainsKey(tilenum))
tilenum = subtile = 0; tilenum = subtile = 0;
map.MapTiles.Value[cell] = new TerrainTile(tilenum, subtile); map.Tiles[cell] = new TerrainTile(tilenum, subtile);
map.MapHeight.Value[cell] = z; map.Height[cell] = z;
} }
} }
} }
@@ -303,7 +303,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
var rx = (ushort)((dx + dy) / 2 + 1); var rx = (ushort)((dx + dy) / 2 + 1);
var ry = (ushort)(dy - rx + fullSize.X + 1); var ry = (ushort)(dy - rx + fullSize.X + 1);
if (!map.MapResources.Value.Contains(uv)) if (!map.Resources.Contains(uv))
continue; continue;
var idx = rx + 512 * ry; var idx = rx + 512 * ry;
@@ -331,7 +331,7 @@ namespace OpenRA.Mods.TS.UtilityCommands
if (resourceType != 0) if (resourceType != 0)
{ {
map.MapResources.Value[uv] = new ResourceTile(resourceType, overlayDataPack[idx]); map.Resources[uv] = new ResourceTile(resourceType, overlayDataPack[idx]);
continue; continue;
} }