diff --git a/OpenRA.Game/Map/CellLayer.cs b/OpenRA.Game/Map/CellLayer.cs new file mode 100644 index 0000000000..7f973b8902 --- /dev/null +++ b/OpenRA.Game/Map/CellLayer.cs @@ -0,0 +1,105 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using OpenRA.Graphics; + +namespace OpenRA +{ + // Represents a layer of "something" that covers the map + public class CellLayer : IEnumerable + { + public readonly Size Size; + T[] entries; + + public CellLayer(Map map) + : this(new Size(map.MapSize.X, map.MapSize.Y)) { } + + public CellLayer(Size size) + { + Size = size; + entries = new T[size.Width * size.Height]; + } + + // Resolve an array index from cell coordinates + int Index(CPos cell) + { + // This will eventually define a distinct case for diagonal cell grids + return cell.Y * Size.Width + cell.X; + } + + /// Gets or sets the using cell coordinates + public T this[CPos cell] + { + get + { + return entries[Index(cell)]; + } + + set + { + entries[Index(cell)] = value; + } + } + + /// Gets or sets the layer contents using raw map coordinates (not CPos!) + public T this[int u, int v] + { + get + { + return entries[v * Size.Width + u]; + } + + set + { + entries[v * Size.Width + u] = value; + } + } + + /// Clears the layer contents with a known value + public void Clear(T clearValue) + { + for (var i = 0; i < entries.Length; i++) + entries[i] = clearValue; + } + + public IEnumerator GetEnumerator() + { + return (IEnumerator)entries.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + // Helper functions + public static class CellLayer + { + /// Create a new layer by resizing another layer. New cells are filled with defaultValue. + public static CellLayer Resize(CellLayer layer, Size newSize, T defaultValue) + { + var result = new CellLayer(newSize); + var width = Math.Min(layer.Size.Width, newSize.Width); + var height = Math.Min(layer.Size.Height, newSize.Height); + + result.Clear(defaultValue); + for (var j = 0; j < height; j++) + for (var i = 0; i < width; i++) + result[i, j] = layer[i, j]; + + return result; + } + } +} diff --git a/OpenRA.Game/Map/CellRegion.cs b/OpenRA.Game/Map/CellRegion.cs new file mode 100644 index 0000000000..3cdccc7fbe --- /dev/null +++ b/OpenRA.Game/Map/CellRegion.cs @@ -0,0 +1,101 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using OpenRA.Graphics; + +namespace OpenRA +{ + // Represents a (on-screen) rectangular collection of tiles. + // TopLeft and BottomRight are inclusive + public class CellRegion : IEnumerable + { + // Corners of the region + public readonly CPos TopLeft; + public readonly CPos BottomRight; + + // Corners in map coordinates + // Defined for forward compatibility with diagonal cell grids + readonly CPos mapTopLeft; + readonly CPos mapBottomRight; + + public CellRegion(CPos topLeft, CPos bottomRight) + { + TopLeft = topLeft; + BottomRight = bottomRight; + + mapTopLeft = TopLeft; + mapBottomRight = BottomRight; + } + + public bool Contains(CPos cell) + { + // Defined for forward compatibility with diagonal cell grids + var uv = cell; + return uv.X >= mapTopLeft.X && uv.X <= mapBottomRight.X && uv.Y >= mapTopLeft.Y && uv.Y <= mapBottomRight.Y; + } + + public IEnumerator GetEnumerator() + { + return new CellRegionEnumerator(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + class CellRegionEnumerator : IEnumerator + { + readonly CellRegion r; + + // Current position, in map coordinates + int u, v; + + public CellRegionEnumerator(CellRegion region) + { + r = region; + Reset(); + } + + public bool MoveNext() + { + u += 1; + + // Check for column overflow + if (u > r.mapBottomRight.X) + { + v += 1; + u = r.mapTopLeft.X; + + // Check for row overflow + if (v > r.mapBottomRight.Y) + return false; + } + + return true; + } + + public void Reset() + { + // Enumerator starts *before* the first element in the sequence. + u = r.mapTopLeft.X - 1; + v = r.mapTopLeft.Y; + } + + public CPos Current { get { return new CPos(u, v); } } + object IEnumerator.Current { get { return Current; } } + public void Dispose() { } + } + } +} diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 0657df79df..d41cd7a7c4 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -235,6 +235,8 @@ + + @@ -358,4 +360,4 @@ --> - \ No newline at end of file +