diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index c766273883..f81c6860b4 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -20,11 +20,12 @@ namespace OpenRA.Graphics { public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false) { - var width = map.Bounds.Width; - var height = map.Bounds.Height; + var b = map.Bounds; + var width = b.Width; + var height = b.Height; if (!actualSize) - width = height = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); + width = height = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var terrain = new Bitmap(width, height); @@ -37,15 +38,17 @@ namespace OpenRA.Graphics { var c = (int*)bitmapData.Scan0; - for (var x = 0; x < map.Bounds.Width; x++) - for (var y = 0; y < map.Bounds.Height; y++) + for (var x = 0; x < b.Width; x++) + { + for (var y = 0; y < b.Height; y++) { - var mapX = x + map.Bounds.Left; - var mapY = y + map.Bounds.Top; + var mapX = x + b.Left; + var mapY = y + b.Top; var type = tileset.GetTerrainInfo(mapTiles[mapX, mapY]); *(c + (y * bitmapData.Stride >> 2) + x) = type.Color.ToArgb(); } + } } terrain.UnlockBits(bitmapData); @@ -57,6 +60,7 @@ namespace OpenRA.Graphics static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap) { var terrain = new Bitmap(terrainBitmap); + var b = map.Bounds; var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); @@ -65,11 +69,12 @@ namespace OpenRA.Graphics { var c = (int*)bitmapData.Scan0; - for (var x = 0; x < map.Bounds.Width; x++) - for (var y = 0; y < map.Bounds.Height; y++) + for (var x = 0; x < b.Width; x++) + { + for (var y = 0; y < b.Height; y++) { - var mapX = x + map.Bounds.Left; - var mapY = y + map.Bounds.Top; + var mapX = x + b.Left; + var mapY = y + b.Top; if (map.MapResources.Value[mapX, mapY].Type == 0) continue; @@ -82,6 +87,7 @@ namespace OpenRA.Graphics *(c + (y * bitmapData.Stride >> 2) + x) = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb(); } + } } terrain.UnlockBits(bitmapData); @@ -92,7 +98,9 @@ namespace OpenRA.Graphics public static Bitmap CustomTerrainBitmap(World world) { var map = world.Map; - var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); + var b = map.Bounds; + + var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var bitmap = new Bitmap(size, size); var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); @@ -101,16 +109,19 @@ namespace OpenRA.Graphics { var c = (int*)bitmapData.Scan0; - for (var x = 0; x < map.Bounds.Width; x++) - for (var y = 0; y < map.Bounds.Height; y++) + for (var x = 0; x < b.Width; x++) + { + for (var y = 0; y < b.Height; y++) { - var mapX = x + map.Bounds.Left; - var mapY = y + map.Bounds.Top; + var mapX = x + b.Left; + var mapY = y + b.Top; var custom = map.CustomTerrain[mapX, mapY]; if (custom == -1) continue; + *(c + (y * bitmapData.Stride >> 2) + x) = world.TileSet[custom].Color.ToArgb(); } + } } bitmap.UnlockBits(bitmapData); @@ -120,7 +131,9 @@ namespace OpenRA.Graphics public static Bitmap ActorsBitmap(World world) { var map = world.Map; - var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); + var b = map.Bounds; + + var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var bitmap = new Bitmap(size, size); var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); @@ -136,8 +149,11 @@ namespace OpenRA.Graphics var color = t.Trait.RadarSignatureColor(t.Actor); foreach (var cell in t.Trait.RadarSignatureCells(t.Actor)) - if (world.Map.Contains(cell)) - *(c + ((cell.Y - world.Map.Bounds.Top) * bitmapData.Stride >> 2) + cell.X - world.Map.Bounds.Left) = color.ToArgb(); + { + var uv = Map.CellToMap(map.TileShape, cell); + if (b.Contains(uv.X, uv.Y)) + *(c + ((uv.Y - b.Top) * bitmapData.Stride >> 2) + uv.X - b.Left) = color.ToArgb(); + } } } @@ -148,7 +164,9 @@ namespace OpenRA.Graphics public static Bitmap ShroudBitmap(World world) { var map = world.Map; - var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); + var b = map.Bounds; + + var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var bitmap = new Bitmap(size, size); if (world.RenderPlayer == null) return bitmap; @@ -158,20 +176,20 @@ namespace OpenRA.Graphics var shroud = Color.Black.ToArgb(); var fog = Color.FromArgb(128, Color.Black).ToArgb(); + var offset = new CVec(b.Left, b.Top); unsafe { var c = (int*)bitmapData.Scan0; - for (var x = 0; x < map.Bounds.Width; x++) - for (var y = 0; y < map.Bounds.Height; y++) - { - var p = new CPos(x + map.Bounds.Left, y + map.Bounds.Top); - if (world.ShroudObscures(p)) - *(c + (y * bitmapData.Stride >> 2) + x) = shroud; - else if (world.FogObscures(p)) - *(c + (y * bitmapData.Stride >> 2) + x) = fog; - } + foreach (var cell in map.Cells) + { + var uv = Map.CellToMap(map.TileShape, cell) - offset; + if (world.ShroudObscures(cell)) + *(c + (uv.Y * bitmapData.Stride >> 2) + uv.X) = shroud; + else if (world.FogObscures(cell)) + *(c + (uv.Y * bitmapData.Stride >> 2) + uv.X) = fog; + } } bitmap.UnlockBits(bitmapData); diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 11dc2f142d..c194be88e3 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -44,11 +44,12 @@ namespace OpenRA.Graphics { var verticesPerRow = 4*map.Bounds.Width; var cells = viewport.VisibleCells; - var firstRow = cells.TopLeft.Y - map.Bounds.Top; - var lastRow = cells.BottomRight.Y - map.Bounds.Top + 1; + var shape = wr.world.Map.TileShape; - if (lastRow < 0 || firstRow > map.Bounds.Height) - return; + // Only draw the rows that are visible. + // VisibleCells is clamped to the map, so additional checks are unnecessary + var firstRow = Map.CellToMap(shape, cells.TopLeft).Y - map.Bounds.Top; + var lastRow = Map.CellToMap(shape, cells.BottomRight).Y - map.Bounds.Top + 1; Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer( vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow), diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 3c181f6480..383f6df1d7 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -92,8 +92,8 @@ namespace OpenRA.Graphics var b = map.Bounds; // Expand to corners of cells - var tl = wr.ScreenPxPosition(map.CenterOfCell(new CPos(b.Left, b.Top)) - new WVec(512, 512, 0)); - var br = wr.ScreenPxPosition(map.CenterOfCell(new CPos(b.Right, b.Bottom)) + new WVec(511, 511, 0)); + var tl = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Left, b.Top))) - new WVec(512, 512, 0)); + var br = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Right, b.Bottom))) + new WVec(511, 511, 0)); mapBounds = Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y); CenterLocation = (tl + br) / 2; @@ -138,8 +138,13 @@ namespace OpenRA.Graphics { get { - var ctl = worldRenderer.world.Map.CenterOfCell(VisibleCells.TopLeft) - new WVec(512, 512, 0); - var cbr = worldRenderer.world.Map.CenterOfCell(VisibleCells.BottomRight) + new WVec(511, 511, 0); + // Visible rectangle in world coordinates (expanded to the corners of the cells) + // Expand the cordon by an additional cell to account for staggered rows on diamond cell grids. + var map = worldRenderer.world.Map; + var ctl = map.CenterOfCell(VisibleCells.TopLeft) - new WVec(1536, 1536, 0); + var cbr = map.CenterOfCell(VisibleCells.BottomRight) + new WVec(1535, 1535, 0); + + // Convert to screen coordinates var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl)).Clamp(ScreenClip); var br = WorldToViewPx(worldRenderer.ScreenPxPosition(cbr)).Clamp(ScreenClip); return Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y); @@ -152,12 +157,16 @@ namespace OpenRA.Graphics { if (cellsDirty) { - // Calculate the intersection of the visible rectangle and the map. + // Visible rectangle in map coordinates var map = worldRenderer.world.Map; - var tl = map.Clamp(map.CellContaining(worldRenderer.Position(TopLeft)) - new CVec(1, 1)); - var br = map.Clamp(map.CellContaining(worldRenderer.Position(BottomRight))); + var ctl = Map.CellToMap(map.TileShape, map.CellContaining(worldRenderer.Position(TopLeft))); + var cbr = Map.CellToMap(map.TileShape, map.CellContaining(worldRenderer.Position(BottomRight))); - cells = new CellRegion(tl, br); + // Add a 2 cell cordon to prevent holes, then convert back to cell coordinates + var tl = map.Clamp(Map.MapToCell(map.TileShape, ctl - new CVec(2, 2))); + var br = map.Clamp(Map.MapToCell(map.TileShape, cbr + new CVec(2, 2))); + + cells = new CellRegion(map.TileShape, tl, br); cellsDirty = false; } diff --git a/OpenRA.Game/Manifest.cs b/OpenRA.Game/Manifest.cs index 194dadca8c..ece91098dc 100644 --- a/OpenRA.Game/Manifest.cs +++ b/OpenRA.Game/Manifest.cs @@ -16,6 +16,8 @@ using OpenRA.Primitives; namespace OpenRA { + public enum TileShape { Rectangle, Diamond } + // Describes what is to be loaded in order to run a mod public class Manifest { @@ -33,6 +35,7 @@ namespace OpenRA public readonly Dictionary> Fonts; public readonly Size TileSize = new Size(24, 24); public readonly string NewsUrl; + public readonly TileShape TileShape = TileShape.Rectangle; public Manifest(string mod) { @@ -77,6 +80,9 @@ namespace OpenRA if (yaml.ContainsKey("TileSize")) TileSize = FieldLoader.GetValue("TileSize", yaml["TileSize"].Value); + if (yaml.ContainsKey("TileShape")) + TileShape = FieldLoader.GetValue("TileShape", yaml["TileShape"].Value); + // Allow inherited mods to import parent maps. var compat = new List(); compat.Add(mod); diff --git a/OpenRA.Game/Map/CellLayer.cs b/OpenRA.Game/Map/CellLayer.cs index 7f973b8902..3c0f444840 100644 --- a/OpenRA.Game/Map/CellLayer.cs +++ b/OpenRA.Game/Map/CellLayer.cs @@ -20,22 +20,24 @@ namespace OpenRA public class CellLayer : IEnumerable { public readonly Size Size; + public readonly TileShape Shape; T[] entries; public CellLayer(Map map) - : this(new Size(map.MapSize.X, map.MapSize.Y)) { } + : this(map.TileShape, new Size(map.MapSize.X, map.MapSize.Y)) { } - public CellLayer(Size size) + public CellLayer(TileShape shape, Size size) { Size = size; + Shape = shape; 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; + var uv = Map.CellToMap(Shape, cell); + return uv.Y * Size.Width + uv.X; } /// Gets or sets the using cell coordinates @@ -90,7 +92,7 @@ namespace OpenRA /// 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 result = new CellLayer(layer.Shape, newSize); var width = Math.Min(layer.Size.Width, newSize.Width); var height = Math.Min(layer.Size.Height, newSize.Height); diff --git a/OpenRA.Game/Map/CellRegion.cs b/OpenRA.Game/Map/CellRegion.cs index 3cdccc7fbe..282030b07f 100644 --- a/OpenRA.Game/Map/CellRegion.cs +++ b/OpenRA.Game/Map/CellRegion.cs @@ -23,25 +23,26 @@ namespace OpenRA // Corners of the region public readonly CPos TopLeft; public readonly CPos BottomRight; + readonly TileShape shape; // Corners in map coordinates - // Defined for forward compatibility with diagonal cell grids + // These will only equal TopLeft and BottomRight for TileShape.Rectangular readonly CPos mapTopLeft; readonly CPos mapBottomRight; - public CellRegion(CPos topLeft, CPos bottomRight) + public CellRegion(TileShape shape, CPos topLeft, CPos bottomRight) { + this.shape = shape; TopLeft = topLeft; BottomRight = bottomRight; - mapTopLeft = TopLeft; - mapBottomRight = BottomRight; + mapTopLeft = Map.CellToMap(shape, TopLeft); + mapBottomRight = Map.CellToMap(shape, BottomRight); } public bool Contains(CPos cell) { - // Defined for forward compatibility with diagonal cell grids - var uv = cell; + var uv = Map.CellToMap(shape, cell); return uv.X >= mapTopLeft.X && uv.X <= mapBottomRight.X && uv.Y >= mapTopLeft.Y && uv.Y <= mapBottomRight.Y; } @@ -93,7 +94,7 @@ namespace OpenRA v = r.mapTopLeft.Y; } - public CPos Current { get { return new CPos(u, v); } } + public CPos Current { get { return Map.MapToCell(r.shape, new CPos(u, v)); } } object IEnumerator.Current { get { return Current; } } public void Dispose() { } } diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 8cbe791316..484362f138 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -76,6 +76,8 @@ namespace OpenRA public bool AllowStartUnitConfig = true; public Bitmap CustomPreview; + public readonly TileShape TileShape; + [FieldLoader.LoadUsing("LoadOptions")] public MapOptions Options; @@ -125,11 +127,12 @@ namespace OpenRA public static Map FromTileset(TileSet tileset) { var size = new Size(1, 1); + var tileShape = Game.modData.Manifest.TileShape; var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); var makeMapTiles = Exts.Lazy(() => { - var ret = new CellLayer(size); + var ret = new CellLayer(tileShape, size); ret.Clear(tileRef); return ret; }); @@ -142,7 +145,7 @@ namespace OpenRA MapSize = new int2(size), Tileset = tileset.Id, Options = new MapOptions(), - MapResources = Exts.Lazy(() => new CellLayer(size)), + MapResources = Exts.Lazy(() => new CellLayer(tileShape, size)), MapTiles = makeMapTiles, Actors = Exts.Lazy(() => new Dictionary()), Smudges = Exts.Lazy(() => new List()) @@ -242,6 +245,7 @@ namespace OpenRA MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); + TileShape = Game.modData.Manifest.TileShape; // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. @@ -262,9 +266,9 @@ namespace OpenRA rules = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this)); cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]); - var tl = new CPos(Bounds.Left, Bounds.Top); - var br = new CPos(Bounds.Right - 1, Bounds.Bottom - 1); - Cells = new CellRegion(tl, br); + var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top)); + var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1)); + Cells = new CellRegion(TileShape, tl, br); CustomTerrain = new CellLayer(this); foreach (var cell in Cells) @@ -465,17 +469,79 @@ namespace OpenRA public bool Contains(CPos cell) { - return Bounds.Contains(cell.X, cell.Y); + var uv = CellToMap(TileShape, cell); + return Bounds.Contains(uv.X, uv.Y); } - public WPos CenterOfCell(CPos c) + public WPos CenterOfCell(CPos cell) { - return new WPos(1024 * c.X + 512, 1024 * c.Y + 512, 0); + if (TileShape == TileShape.Rectangle) + return new WPos(1024 * cell.X + 512, 1024 * cell.Y + 512, 0); + + // Convert from diamond cell position (x, y) to world position (u, v): + // (a) Consider the relationships: + // - Center of origin cell is (512, 512) + // - +x adds (512, 512) to world pos + // - +y adds (-512, 512) to world pos + // (b) Therefore: + // - ax + by adds (a - b) * 512 + 512 to u + // - ax + by adds (a + b) * 512 + 512 to v + return new WPos(512 * (cell.X - cell.Y + 1), 512 * (cell.X + cell.Y + 1), 0); } public CPos CellContaining(WPos pos) { - return new CPos(pos.X / 1024, pos.Y / 1024); + if (TileShape == TileShape.Rectangle) + return new CPos(pos.X / 1024, pos.Y / 1024); + + // Convert from world position to diamond cell position: + // (a) Subtract (512, 512) to move the rotation center to the middle of the corner cell + // (b) Rotate axes by -pi/4 + // (c) Add 512 to x (but not y) to realign the cell + // (d) Divide by 1024 to find final cell coords + var u = (pos.Y + pos.X - 512) / 1024; + var v = (pos.Y - pos.X) / 1024; + return new CPos(u, v); + } + + public static CPos MapToCell(TileShape shape, CPos map) + { + if (shape == TileShape.Rectangle) + return map; + + // Convert from rectangular map position to diamond cell position + // - The staggered rows make this fiddly (hint: draw a diagram!) + // (a) Consider the relationships: + // - +1u (even -> odd) adds (1, -1) to (x, y) + // - +1v (even -> odd) adds (1, 0) to (x, y) + // - +1v (odd -> even) adds (0, 1) to (x, y) + // (b) Therefore: + // - au + 2bv adds (a + b) to (x, y) + // - a correction factor is added if v is odd + var offset = (map.Y & 1) == 1 ? 1 : 0; + var y = (map.Y - offset) / 2 - map.X; + var x = map.Y - y; + return new CPos(x, y); + } + + public static CPos CellToMap(TileShape shape, CPos cell) + { + if (shape == TileShape.Rectangle) + return cell; + + // Convert from diamond cell (x, y) position to rectangular map position (u, v) + // - The staggered rows make this fiddly (hint: draw a diagram!) + // (a) Consider the relationships: + // - +1x (even -> odd) adds (0, 1) to (u, v) + // - +1x (odd -> even) adds (1, 1) to (u, v) + // - +1y (even -> odd) adds (-1, 1) to (u, v) + // - +1y (odd -> even) adds (0, 1) to (u, v) + // (b) Therefore: + // - ax + by adds (a - b)/2 to u (only even increments count) + // - ax + by adds a + b to v + var u = (cell.X - cell.Y) / 2; + var v = cell.X + cell.Y; + return new CPos(u, v); } public int FacingBetween(CPos cell, CPos towards, int fallbackfacing) @@ -497,7 +563,10 @@ namespace OpenRA public void ResizeCordon(int left, int top, int right, int bottom) { Bounds = Rectangle.FromLTRB(left, top, right, bottom); - Cells = new CellRegion(new CPos(Bounds.Left, Bounds.Top), new CPos(Bounds.Right - 1, Bounds.Bottom - 1)); + + var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top)); + var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1)); + Cells = new CellRegion(TileShape, tl, br); } string ComputeHash() @@ -597,17 +666,18 @@ namespace OpenRA return cachedTileSet.Value[GetTerrainIndex(cell)]; } - public CPos Clamp(CPos xy) + public CPos Clamp(CPos cell) { - var r = Bounds; - return xy.Clamp(new Rectangle(r.X, r.Y, r.Width - 1, r.Height - 1)); + var bounds = new Rectangle(Bounds.X, Bounds.Y, Bounds.Width - 1, Bounds.Height - 1); + return MapToCell(TileShape, CellToMap(TileShape, cell).Clamp(bounds)); } public CPos ChooseRandomCell(MersenneTwister rand) { - return new CPos( - rand.Next(Bounds.Left, Bounds.Right), - rand.Next(Bounds.Top, Bounds.Bottom)); + var x = rand.Next(Bounds.Left, Bounds.Right); + var y = rand.Next(Bounds.Top, Bounds.Bottom); + + return MapToCell(TileShape, new CPos(x, y)); } public CPos ChooseRandomEdgeCell(MersenneTwister rand) @@ -615,15 +685,16 @@ namespace OpenRA var isX = rand.Next(2) == 0; var edge = rand.Next(2) == 0; - return new CPos( - isX ? rand.Next(Bounds.Left, Bounds.Right) : (edge ? Bounds.Left : Bounds.Right), - !isX ? rand.Next(Bounds.Top, Bounds.Bottom) : (edge ? Bounds.Top : Bounds.Bottom)); + var x = isX ? rand.Next(Bounds.Left, Bounds.Right) : (edge ? Bounds.Left : Bounds.Right); + var y = !isX ? rand.Next(Bounds.Top, Bounds.Bottom) : (edge ? Bounds.Top : Bounds.Bottom); + + return MapToCell(TileShape, new CPos(x, y)); } public WRange DistanceToEdge(WPos pos, WVec dir) { - var tl = CenterOfCell(new CPos(Bounds.Left, Bounds.Top)) - new WVec(512, 512, 0); - var br = CenterOfCell(new CPos(Bounds.Right, Bounds.Bottom)) + new WVec(511, 511, 0); + var tl = CenterOfCell(Cells.TopLeft) - new WVec(512, 512, 0); + var br = CenterOfCell(Cells.BottomRight) + new WVec(511, 511, 0); var x = dir.X == 0 ? int.MaxValue : ((dir.X < 0 ? tl.X : br.X) - pos.X) / dir.X; var y = dir.Y == 0 ? int.MaxValue : ((dir.Y < 0 ? tl.Y : br.Y) - pos.Y) / dir.Y; return new WRange(Math.Min(x, y) * dir.Length); diff --git a/OpenRA.Game/Widgets/MapPreviewWidget.cs b/OpenRA.Game/Widgets/MapPreviewWidget.cs index 384bd8b316..c70aab3c0f 100644 --- a/OpenRA.Game/Widgets/MapPreviewWidget.cs +++ b/OpenRA.Game/Widgets/MapPreviewWidget.cs @@ -129,9 +129,10 @@ namespace OpenRA.Widgets tooltipContainer.Value.RemoveTooltip(); } - public int2 ConvertToPreview(CPos point) + public int2 ConvertToPreview(CPos cell) { var preview = Preview(); + var point = Map.CellToMap(preview.Map.TileShape, cell); var dx = (int)(previewScale * (point.X - preview.Bounds.Left)); var dy = (int)(previewScale * (point.Y - preview.Bounds.Top)); return new int2(mapRect.X + dx, mapRect.Y + dy); diff --git a/OpenRA.Mods.RA/Move/PathSearch.cs b/OpenRA.Mods.RA/Move/PathSearch.cs index 1b61a86814..93a3ccb2fb 100755 --- a/OpenRA.Mods.RA/Move/PathSearch.cs +++ b/OpenRA.Mods.RA/Move/PathSearch.cs @@ -287,7 +287,7 @@ namespace OpenRA.Mods.RA.Move while (CellInfoPool.Count > 0) { var cellInfo = GetFromPool(); - if (cellInfo.Size != mapSize) + if (cellInfo.Size != mapSize || cellInfo.Shape != self.World.Map.TileShape) { Log.Write("debug", "Discarding old pooled CellInfo of wrong size."); continue; diff --git a/OpenRA.Mods.RA/Widgets/RadarWidget.cs b/OpenRA.Mods.RA/Widgets/RadarWidget.cs index 960e484b5e..e7b4fdaa96 100755 --- a/OpenRA.Mods.RA/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.RA/Widgets/RadarWidget.cs @@ -115,7 +115,7 @@ namespace OpenRA.Mods.RA.Widgets var cell = MinimapPixelToCell(mi.Location); var pos = world.Map.CenterOfCell(cell); if ((mi.Event == MouseInputEvent.Down || mi.Event == MouseInputEvent.Move) && mi.Button == MouseButton.Left) - worldRenderer.Viewport.Center(world.Map.CenterOfCell(cell)); + worldRenderer.Viewport.Center(pos); if (mi.Event == MouseInputEvent.Down && mi.Button == MouseButton.Right) { @@ -242,8 +242,8 @@ namespace OpenRA.Mods.RA.Widgets int2 CellToMinimapPixel(CPos p) { - var mapOrigin = new CPos(world.Map.Bounds.Left, world.Map.Bounds.Top); - var mapOffset = p - mapOrigin; + var mapOrigin = new CVec(world.Map.Bounds.Left, world.Map.Bounds.Top); + var mapOffset = Map.CellToMap(world.Map.TileShape, p) - mapOrigin; return new int2(mapRect.X, mapRect.Y) + (previewScale * new float2(mapOffset.X, mapOffset.Y)).ToInt2(); } @@ -253,7 +253,7 @@ namespace OpenRA.Mods.RA.Widgets var viewOrigin = new float2(mapRect.X, mapRect.Y); var mapOrigin = new float2(world.Map.Bounds.Left, world.Map.Bounds.Top); var fcell = mapOrigin + (1f / previewScale) * (p - viewOrigin); - return new CPos((int)fcell.X, (int)fcell.Y); + return Map.MapToCell(world.Map.TileShape, new CPos((int)fcell.X, (int)fcell.Y)); } } } diff --git a/OpenRA.Utility/LegacyMapImporter.cs b/OpenRA.Utility/LegacyMapImporter.cs index ded0b9d2ab..ce83937535 100644 --- a/OpenRA.Utility/LegacyMapImporter.cs +++ b/OpenRA.Utility/LegacyMapImporter.cs @@ -149,8 +149,8 @@ namespace OpenRA.Utility map.Smudges = Exts.Lazy(() => new List()); map.Actors = Exts.Lazy(() => new Dictionary()); - map.MapResources = Exts.Lazy(() => new CellLayer(size)); - map.MapTiles = Exts.Lazy(() => new CellLayer(size)); + map.MapResources = Exts.Lazy(() => new CellLayer(TileShape.Rectangle, size)); + map.MapTiles = Exts.Lazy(() => new CellLayer(TileShape.Rectangle, size)); map.Options = new MapOptions();