Merge pull request #10942 from pchote/remove-map-lazyness
Remove map lazyness.
This commit is contained in:
@@ -125,8 +125,6 @@ namespace OpenRA
|
||||
/// </summary>
|
||||
public WPos ProjectedBottomRight;
|
||||
|
||||
public Lazy<CPos[]> SpawnPoints;
|
||||
|
||||
// Yaml map data
|
||||
[FieldLoader.Ignore] public readonly MiniYaml RuleDefinitions;
|
||||
[FieldLoader.Ignore] public readonly MiniYaml SequenceDefinitions;
|
||||
@@ -145,9 +143,9 @@ namespace OpenRA
|
||||
|
||||
public int2 MapSize;
|
||||
|
||||
[FieldLoader.Ignore] public Lazy<CellLayer<TerrainTile>> MapTiles;
|
||||
[FieldLoader.Ignore] public Lazy<CellLayer<ResourceTile>> MapResources;
|
||||
[FieldLoader.Ignore] public Lazy<CellLayer<byte>> MapHeight;
|
||||
[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;
|
||||
@@ -156,20 +154,12 @@ namespace OpenRA
|
||||
[FieldLoader.Ignore] CellLayer<PPos[]> cellProjection;
|
||||
[FieldLoader.Ignore] CellLayer<List<MPos>> inverseCellProjection;
|
||||
|
||||
[FieldLoader.Ignore] Lazy<Ruleset> rules;
|
||||
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
|
||||
public Ruleset Rules { get; private set; }
|
||||
|
||||
[FieldLoader.Ignore] public ProjectedCellRegion ProjectedCellBounds;
|
||||
[FieldLoader.Ignore] public CellRegion AllCells;
|
||||
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>
|
||||
/// 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.
|
||||
@@ -191,27 +181,16 @@ namespace OpenRA
|
||||
// Will be dropped on save if nothing is added to it
|
||||
RuleDefinitions = new MiniYaml("");
|
||||
|
||||
MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(Grid.Type, size));
|
||||
|
||||
MapTiles = Exts.Lazy(() =>
|
||||
Tiles = new CellLayer<TerrainTile>(Grid.Type, size);
|
||||
Resources = new CellLayer<ResourceTile>(Grid.Type, size);
|
||||
Height = new CellLayer<byte>(Grid.Type, size);
|
||||
if (Grid.MaximumTerrainHeight > 0)
|
||||
{
|
||||
var ret = new CellLayer<TerrainTile>(Grid.Type, size);
|
||||
ret.Clear(tileRef);
|
||||
if (Grid.MaximumTerrainHeight > 0)
|
||||
ret.CellEntryChanged += UpdateProjection;
|
||||
return ret;
|
||||
});
|
||||
Height.CellEntryChanged += UpdateProjection;
|
||||
Tiles.CellEntryChanged += UpdateProjection;
|
||||
}
|
||||
|
||||
MapHeight = Exts.Lazy(() =>
|
||||
{
|
||||
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]);
|
||||
Tiles.Clear(tileRef);
|
||||
|
||||
PostInit();
|
||||
}
|
||||
@@ -221,8 +200,8 @@ namespace OpenRA
|
||||
this.modData = modData;
|
||||
Package = package;
|
||||
|
||||
AssertExists("map.yaml");
|
||||
AssertExists("map.bin");
|
||||
if (!Package.Contains("map.yaml") || !Package.Contains("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));
|
||||
FieldLoader.Load(this, yaml);
|
||||
@@ -230,19 +209,6 @@ namespace OpenRA
|
||||
if (MapFormat != SupportedMapFormat)
|
||||
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");
|
||||
SequenceDefinitions = LoadRuleSection(yaml, "Sequences");
|
||||
VoxelSequenceDefinitions = LoadRuleSection(yaml, "VoxelSequences");
|
||||
@@ -255,12 +221,64 @@ namespace OpenRA
|
||||
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
|
||||
ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");
|
||||
|
||||
MapTiles = Exts.Lazy(LoadMapTiles);
|
||||
MapResources = Exts.Lazy(LoadResourceTiles);
|
||||
MapHeight = Exts.Lazy(LoadMapHeight);
|
||||
|
||||
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();
|
||||
|
||||
Uid = ComputeUID(Package);
|
||||
@@ -274,21 +292,19 @@ namespace OpenRA
|
||||
|
||||
void PostInit()
|
||||
{
|
||||
rules = Exts.Lazy(() =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ruleset.Load(modData, this, Tileset, RuleDefinitions, WeaponDefinitions,
|
||||
VoiceDefinitions, NotificationDefinitions, MusicDefinitions, SequenceDefinitions);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
InvalidCustomRules = true;
|
||||
Log.Write("debug", "Failed to load rules for {0} with error {1}", Title, e.Message);
|
||||
}
|
||||
Rules = Ruleset.Load(modData, this, Tileset, RuleDefinitions, WeaponDefinitions,
|
||||
VoiceDefinitions, NotificationDefinitions, MusicDefinitions, SequenceDefinitions);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
InvalidCustomRules = true;
|
||||
Rules = Ruleset.LoadDefaultsForTileSet(modData, Tileset);
|
||||
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 br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);
|
||||
@@ -360,7 +376,7 @@ namespace OpenRA
|
||||
|
||||
PPos[] ProjectCellInner(MPos uv)
|
||||
{
|
||||
var mapHeight = MapHeight.Value;
|
||||
var mapHeight = Height;
|
||||
if (!mapHeight.Contains(uv))
|
||||
return NoProjectedCells;
|
||||
|
||||
@@ -371,7 +387,7 @@ namespace OpenRA
|
||||
// Odd-height ramps get bumped up a level to the next even height layer
|
||||
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)
|
||||
height += 1;
|
||||
}
|
||||
@@ -396,11 +412,6 @@ namespace OpenRA
|
||||
return candidates.Where(c => mapHeight.Contains((MPos)c)).ToArray();
|
||||
}
|
||||
|
||||
public Ruleset PreloadRules()
|
||||
{
|
||||
return rules.Value;
|
||||
}
|
||||
|
||||
public void Save(IReadWritePackage toPackage)
|
||||
{
|
||||
MapFormat = SupportedMapFormat;
|
||||
@@ -468,84 +479,6 @@ namespace OpenRA
|
||||
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()
|
||||
{
|
||||
var dataStream = new MemoryStream();
|
||||
@@ -574,7 +507,7 @@ namespace OpenRA
|
||||
{
|
||||
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.Index);
|
||||
}
|
||||
@@ -585,7 +518,7 @@ namespace OpenRA
|
||||
if (heightsOffset != 0)
|
||||
for (var i = 0; i < MapSize.X; i++)
|
||||
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
|
||||
if (resourcesOffset != 0)
|
||||
@@ -594,7 +527,7 @@ namespace OpenRA
|
||||
{
|
||||
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.Index);
|
||||
}
|
||||
@@ -641,7 +574,7 @@ namespace OpenRA
|
||||
for (var x = 0; x < width; x++)
|
||||
{
|
||||
var uv = new MPos(x + Bounds.Left, y + Bounds.Top);
|
||||
var resourceType = MapResources.Value[uv].Type;
|
||||
var resourceType = Resources[uv].Type;
|
||||
if (resourceType != 0)
|
||||
{
|
||||
// Cell contains resources
|
||||
@@ -654,7 +587,7 @@ namespace OpenRA
|
||||
else
|
||||
{
|
||||
// Cell contains terrain
|
||||
var type = tileset.GetTileInfo(MapTiles.Value[uv]);
|
||||
var type = tileset.GetTileInfo(Tiles[uv]);
|
||||
leftColor = type != null ? type.LeftColor : 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
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -736,7 +669,7 @@ namespace OpenRA
|
||||
// (b) Therefore:
|
||||
// - ax + by adds (a - b) * 512 + 512 to u
|
||||
// - 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);
|
||||
}
|
||||
|
||||
@@ -815,14 +748,14 @@ namespace OpenRA
|
||||
|
||||
public void Resize(int width, int height)
|
||||
{
|
||||
var oldMapTiles = MapTiles.Value;
|
||||
var oldMapResources = MapResources.Value;
|
||||
var oldMapHeight = MapHeight.Value;
|
||||
var oldMapTiles = Tiles;
|
||||
var oldMapResources = Resources;
|
||||
var oldMapHeight = Height;
|
||||
var newSize = new Size(width, height);
|
||||
|
||||
MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]));
|
||||
MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]));
|
||||
MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]));
|
||||
Tiles = CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]);
|
||||
Resources = CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]);
|
||||
Height = CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]);
|
||||
MapSize = new int2(newSize);
|
||||
|
||||
var tl = new MPos(0, 0);
|
||||
@@ -864,8 +797,8 @@ namespace OpenRA
|
||||
{
|
||||
for (var i = Bounds.Left; i < Bounds.Right; i++)
|
||||
{
|
||||
var type = MapTiles.Value[new MPos(i, j)].Type;
|
||||
var index = MapTiles.Value[new MPos(i, j)].Index;
|
||||
var type = Tiles[new MPos(i, j)].Type;
|
||||
var index = Tiles[new MPos(i, j)].Index;
|
||||
if (!tileset.Templates.ContainsKey(type))
|
||||
{
|
||||
Console.WriteLine("Unknown Tile ID {0}".F(type));
|
||||
@@ -877,7 +810,7 @@ namespace OpenRA
|
||||
continue;
|
||||
|
||||
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.
|
||||
Action<CPos> invalidateTerrainIndex = c => cachedTerrainIndexes[c] = InvalidCachedTerrainIndex;
|
||||
CustomTerrain.CellEntryChanged += invalidateTerrainIndex;
|
||||
MapTiles.Value.CellEntryChanged += invalidateTerrainIndex;
|
||||
Tiles.CellEntryChanged += invalidateTerrainIndex;
|
||||
}
|
||||
|
||||
var uv = cell.ToMPos(this);
|
||||
@@ -906,7 +839,7 @@ namespace OpenRA
|
||||
{
|
||||
var custom = CustomTerrain[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;
|
||||
@@ -1116,7 +1049,7 @@ namespace OpenRA
|
||||
|
||||
Func<CPos, bool> valid = Contains;
|
||||
if (allowOutsideBounds)
|
||||
valid = MapTiles.Value.Contains;
|
||||
valid = Tiles.Contains;
|
||||
|
||||
for (var i = minRange; i <= maxRange; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user