diff --git a/OpenRA.Editor/Form1.cs b/OpenRA.Editor/Form1.cs index 51d7c68441..959d2fc220 100644 --- a/OpenRA.Editor/Form1.cs +++ b/OpenRA.Editor/Form1.cs @@ -641,7 +641,8 @@ namespace OpenRA.Editor for (var i = 0; i < surface1.Map.MapSize.X; i++) for (var j = 0; j < surface1.Map.MapSize.Y; j++) { - if (surface1.Map.MapResources.Value[i, j].Type != 0) + var cell = new CPos(i, j); + if (surface1.Map.MapResources.Value[cell].Type != 0) totalResource += GetResourceValue(i, j); } @@ -654,9 +655,12 @@ namespace OpenRA.Editor for (var u = -1; u < 2; u++) for (var v = -1; v < 2; v++) { - if (!surface1.Map.IsInMap(new CPos(x + u, y + v))) + var cell = new CPos(x + u, y + v); + + if (!surface1.Map.IsInMap(cell)) continue; - if (surface1.Map.MapResources.Value[x + u, y + v].Type == resourceType) + + if (surface1.Map.MapResources.Value[cell].Type == resourceType) ++sum; } @@ -666,7 +670,7 @@ namespace OpenRA.Editor int GetResourceValue(int x, int y) { var imageLength = 0; - int type = surface1.Map.MapResources.Value[x, y].Type; + var type = surface1.Map.MapResources.Value[new CPos(x, y)].Type; var template = surface1.ResourceTemplates.FirstOrDefault(a => a.Value.Info.ResourceType == type).Value; if (type == 1) imageLength = 12; diff --git a/OpenRA.Editor/ResourceTool.cs b/OpenRA.Editor/ResourceTool.cs index f8f6351e05..b135daaf0d 100644 --- a/OpenRA.Editor/ResourceTool.cs +++ b/OpenRA.Editor/ResourceTool.cs @@ -21,12 +21,9 @@ namespace OpenRA.Editor public void Apply(Surface surface) { - surface.Map.MapResources.Value[surface.GetBrushLocation().X, surface.GetBrushLocation().Y] - = new TileReference - { - Type = (byte)resourceTemplate.Info.ResourceType, - Index = (byte)random.Next(resourceTemplate.Info.MaxDensity) - }; + var type = (byte)resourceTemplate.Info.ResourceType; + var index = (byte)random.Next(resourceTemplate.Info.MaxDensity); + surface.Map.MapResources.Value[surface.GetBrushLocation()] = new ResourceTile(type, index); var ch = new int2(surface.GetBrushLocation().X / Surface.ChunkSize, surface.GetBrushLocation().Y / Surface.ChunkSize); diff --git a/OpenRA.Editor/Surface.cs b/OpenRA.Editor/Surface.cs index 4d4fb25892..6bcb4c6844 100644 --- a/OpenRA.Editor/Surface.cs +++ b/OpenRA.Editor/Surface.cs @@ -63,7 +63,7 @@ namespace OpenRA.Editor public bool IsPaste { get { return TileSelection != null && ResourceSelection != null; } } public TileReference[,] TileSelection; - public TileReference[,] ResourceSelection; + public ResourceTile[,] ResourceSelection; public CPos SelectionStart; public CPos SelectionEnd; @@ -206,9 +206,9 @@ namespace OpenRA.Editor var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == brushLocation); if (key.Key != null) Map.Actors.Value.Remove(key.Key); - if (Map.MapResources.Value[brushLocation.X, brushLocation.Y].Type != 0) + if (Map.MapResources.Value[brushLocation].Type != 0) { - Map.MapResources.Value[brushLocation.X, brushLocation.Y] = new TileReference(); + Map.MapResources.Value[brushLocation] = new ResourceTile(0, 0); var ch = new int2(brushLocation.X / ChunkSize, brushLocation.Y / ChunkSize); if (Chunks.ContainsKey(ch)) { @@ -271,6 +271,7 @@ namespace OpenRA.Editor for (var i = 0; i < ChunkSize; i++) for (var j = 0; j < ChunkSize; j++) { + var cell = new CPos(u * ChunkSize + i, v * ChunkSize + j); var tr = Map.MapTiles.Value[u * ChunkSize + i, v * ChunkSize + j]; var tile = TileSetRenderer.Data(tr.Type); var index = (tr.Index < tile.Count) ? tr.Index : (byte)0; @@ -279,9 +280,9 @@ namespace OpenRA.Editor for (var y = 0; y < TileSetRenderer.TileSize; y++) p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize * y]).ToArgb(); - if (Map.MapResources.Value[u * ChunkSize + i, v * ChunkSize + j].Type != 0) + if (Map.MapResources.Value[cell].Type != 0) { - var resourceImage = ResourceTemplates[Map.MapResources.Value[u * ChunkSize + i, v * ChunkSize + j].Type].Bitmap; + var resourceImage = ResourceTemplates[Map.MapResources.Value[cell].Type].Bitmap; var srcdata = resourceImage.LockBits(resourceImage.Bounds(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); @@ -509,15 +510,16 @@ namespace OpenRA.Editor var height = Math.Abs((start - end).Y); TileSelection = new TileReference[width, height]; - ResourceSelection = new TileReference[width, height]; + ResourceSelection = new ResourceTile[width, height]; for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { // TODO: crash prevention + var cell = new CPos(start.X + x, start.Y + y); TileSelection[x, y] = Map.MapTiles.Value[start.X + x, start.Y + y]; - ResourceSelection[x, y] = Map.MapResources.Value[start.X + x, start.Y + y]; + ResourceSelection[x, y] = Map.MapResources.Value[cell]; } } } @@ -534,10 +536,11 @@ namespace OpenRA.Editor { var mapX = loc.X + x; var mapY = loc.Y + y; + var cell = new CPos(mapX, mapY); // TODO: crash prevention for outside of bounds Map.MapTiles.Value[mapX, mapY] = TileSelection[x, y]; - Map.MapResources.Value[mapX, mapY] = ResourceSelection[x, y]; + Map.MapResources.Value[cell] = ResourceSelection[x, y]; var ch = new int2(mapX / ChunkSize, mapY / ChunkSize); if (Chunks.ContainsKey(ch)) diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index d99d02cdbc..b121ed9e07 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -74,8 +74,9 @@ namespace OpenRA.Graphics continue; var res = resourceRules.Actors["world"].Traits.WithInterface() - .Where(t => t.ResourceType == map.MapResources.Value[mapX, mapY].Type) + .Where(t => t.ResourceType == map.MapResources.Value[mapX, mapY].Type) .Select(t => t.TerrainType).FirstOrDefault(); + if (res == null) continue; diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index d1afb17bd9..489f42ecbf 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -112,7 +112,7 @@ namespace OpenRA public int2 MapSize; [FieldLoader.Ignore] public Lazy[,]> MapTiles; - [FieldLoader.Ignore] public Lazy[,]> MapResources; + [FieldLoader.Ignore] public Lazy> MapResources; [FieldLoader.Ignore] public CellLayer CustomTerrain; [FieldLoader.Ignore] Lazy rules; @@ -126,15 +126,16 @@ namespace OpenRA var tile = tileset.Templates.First(); var tileRef = new TileReference { Type = tile.Key, Index = (byte)0 }; + var size = new Size(1, 1); var map = new Map() { Title = "Name your map here", Description = "Describe your map here", Author = "Your name here", - MapSize = new int2(1, 1), + MapSize = new int2(size), Tileset = tileset.Id, Options = new MapOptions(), - MapResources = Exts.Lazy(() => new TileReference[1, 1]), + MapResources = Exts.Lazy(() => new CellLayer(size)), MapTiles = Exts.Lazy(() => new TileReference[1, 1] { { tileRef } }), Actors = Exts.Lazy(() => new Dictionary()), Smudges = Exts.Lazy(() => new List()) @@ -385,9 +386,9 @@ namespace OpenRA return tiles; } - public TileReference[,] LoadResourceTiles() + public CellLayer LoadResourceTiles() { - var resources = new TileReference[MapSize.X, MapSize.Y]; + var resources = new CellLayer(this); using (var dataStream = Container.GetContent("map.bin")) { @@ -406,10 +407,11 @@ namespace OpenRA var data = dataStream.ReadBytes(MapSize.X * MapSize.Y * 2); var d = 0; + // Load resource data for (var i = 0; i < MapSize.X; i++) for (var j = 0; j < MapSize.Y; j++) - resources[i, j] = new TileReference(data[d++], data[d++]); + resources[i, j] = new ResourceTile(data[d++], data[d++]); } return resources; @@ -435,11 +437,14 @@ namespace OpenRA // Resource data for (var i = 0; i < MapSize.X; i++) + { for (var j = 0; j < MapSize.Y; j++) { - writer.Write(MapResources.Value[i, j].Type); - writer.Write(MapResources.Value[i, j].Index); + var tile = MapResources.Value[new CPos(i, j)]; + writer.Write(tile.Type); + writer.Write(tile.Index); } + } } return dataStream.ToArray(); @@ -452,10 +457,11 @@ namespace OpenRA { var oldMapTiles = MapTiles.Value; var oldMapResources = MapResources.Value; + var newSize = new Size(width, height); MapTiles = Exts.Lazy(() => Exts.ResizeArray(oldMapTiles, oldMapTiles[0, 0], width, height)); - MapResources = Exts.Lazy(() => Exts.ResizeArray(oldMapResources, oldMapResources[0, 0], width, height)); - MapSize = new int2(width, height); + MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[0, 0])); + MapSize = new int2(newSize); } public void ResizeCordon(int left, int top, int right, int bottom) diff --git a/OpenRA.Game/Map/TileReference.cs b/OpenRA.Game/Map/TileReference.cs index 5dc7d719b8..187a80c3b9 100644 --- a/OpenRA.Game/Map/TileReference.cs +++ b/OpenRA.Game/Map/TileReference.cs @@ -23,4 +23,18 @@ namespace OpenRA public override int GetHashCode() { return Type.GetHashCode() ^ Index.GetHashCode(); } } + + public struct ResourceTile + { + public readonly byte Type; + public readonly byte Index; + + public ResourceTile(byte type, byte index) + { + Type = type; + Index = index; + } + + public override int GetHashCode() { return Type.GetHashCode() ^ Index.GetHashCode(); } + } } diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index 223491949f..61fd9790c0 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -64,7 +64,7 @@ namespace OpenRA.Traits foreach (var cell in w.Map.Cells) { ResourceType t; - if (!resources.TryGetValue(w.Map.MapResources.Value[cell.X, cell.Y].Type, out t)) + if (!resources.TryGetValue(w.Map.MapResources.Value[cell].Type, out t)) continue; if (!AllowResourceAt(t, cell)) diff --git a/OpenRA.Utility/LegacyMapImporter.cs b/OpenRA.Utility/LegacyMapImporter.cs index e1a5aa359e..6e40e4ec63 100644 --- a/OpenRA.Utility/LegacyMapImporter.cs +++ b/OpenRA.Utility/LegacyMapImporter.cs @@ -148,7 +148,7 @@ namespace OpenRA.Utility map.Smudges = Exts.Lazy(() => new List()); map.Actors = Exts.Lazy(() => new Dictionary()); - map.MapResources = Exts.Lazy(() => new TileReference[mapSize, mapSize]); + map.MapResources = Exts.Lazy(() => new CellLayer(new Size(mapSize, mapSize))); map.MapTiles = Exts.Lazy(() => new TileReference[mapSize, mapSize]); map.Options = new MapOptions(); @@ -277,15 +277,16 @@ namespace OpenRA.Utility if (o != 255 && overlayResourceMapping.ContainsKey(redAlertOverlayNames[o])) res = overlayResourceMapping[redAlertOverlayNames[o]]; - - map.MapResources.Value[i, j] = new TileReference(res.First, res.Second); + + var cell = new CPos(i, j); + map.MapResources.Value[cell] = new ResourceTile(res.First, res.Second); if (o != 255 && overlayActorMapping.ContainsKey(redAlertOverlayNames[o])) { map.Actors.Value.Add("Actor" + actorCount++, new ActorReference(overlayActorMapping[redAlertOverlayNames[o]]) { - new LocationInit(new CPos(i, j)), + new LocationInit(cell), new OwnerInit("Neutral") }); } @@ -342,7 +343,7 @@ namespace OpenRA.Utility if (overlayResourceMapping.ContainsKey(kv.Value.ToLower())) res = overlayResourceMapping[kv.Value.ToLower()]; - map.MapResources.Value[cell.X, cell.Y] = new TileReference(res.First, res.Second); + map.MapResources.Value[cell] = new ResourceTile(res.First, res.Second); if (overlayActorMapping.ContainsKey(kv.Value.ToLower())) map.Actors.Value.Add("Actor" + actorCount++,