diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index d54def71b5..54a49749c0 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -20,14 +20,23 @@ namespace OpenRA.Graphics { public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false) { + var isDiamond = map.TileShape == TileShape.Diamond; var b = map.Bounds; + + // Fudge the heightmap offset by adding as much extra as we need / can. + // This tries to correct for our incorrect assumption that MPos == PPos + var heightOffset = Math.Min(map.MaximumTerrainHeight, map.MapSize.Y - b.Bottom); var width = b.Width; - var height = b.Height; + var height = b.Height + heightOffset; + + var bitmapWidth = width; + if (isDiamond) + bitmapWidth = 2 * bitmapWidth - 1; if (!actualSize) - width = height = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); + bitmapWidth = height = Exts.NextPowerOf2(Math.Max(bitmapWidth, height)); - var terrain = new Bitmap(width, height); + var terrain = new Bitmap(bitmapWidth, height); var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); @@ -38,16 +47,27 @@ namespace OpenRA.Graphics { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; - for (var y = 0; y < b.Height; y++) + for (var y = 0; y < height; y++) { - for (var x = 0; x < b.Width; x++) + for (var x = 0; x < width; x++) { - var mapX = x + b.Left; - var mapY = y + b.Top; - var type = tileset.GetTileInfo(mapTiles[new MPos(mapX, mapY)]); - var color = type != null ? type.LeftColor : Color.Black; + var uv = new MPos(x + b.Left, y + b.Top); + var type = tileset.GetTileInfo(mapTiles[uv]); + var leftColor = type != null ? type.LeftColor : Color.Black; - colors[y * stride + x] = color.ToArgb(); + if (isDiamond) + { + // Odd rows are shifted right by 1px + var dx = uv.V & 1; + var rightColor = type != null ? type.RightColor : Color.Black; + if (x + dx > 0) + colors[y * stride + 2 * x + dx - 1] = leftColor.ToArgb(); + + if (2 * x + dx < stride) + colors[y * stride + 2 * x + dx] = rightColor.ToArgb(); + } + else + colors[y * stride + x] = leftColor.ToArgb(); } } } @@ -61,8 +81,18 @@ namespace OpenRA.Graphics static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap) { var terrain = new Bitmap(terrainBitmap); + var isDiamond = map.TileShape == TileShape.Diamond; var b = map.Bounds; + // Fudge the heightmap offset by adding as much extra as we need / can + // This tries to correct for our incorrect assumption that MPos == PPos + var heightOffset = Math.Min(map.MaximumTerrainHeight, map.MapSize.Y - b.Bottom); + var width = b.Width; + var height = b.Height + heightOffset; + + var resources = resourceRules.Actors["world"].Traits.WithInterface() + .ToDictionary(r => r.ResourceType, r => r.TerrainType); + var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); @@ -70,23 +100,31 @@ namespace OpenRA.Graphics { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; - for (var y = 0; y < b.Height; y++) + for (var y = 0; y < height; y++) { - for (var x = 0; x < b.Width; x++) + for (var x = 0; x < width; x++) { - var mapX = x + b.Left; - var mapY = y + b.Top; - if (map.MapResources.Value[new MPos(mapX, mapY)].Type == 0) + var uv = new MPos(x + b.Left, y + b.Top); + if (map.MapResources.Value[uv].Type == 0) continue; - var res = resourceRules.Actors["world"].Traits.WithInterface() - .Where(t => t.ResourceType == map.MapResources.Value[new MPos(mapX, mapY)].Type) - .Select(t => t.TerrainType).FirstOrDefault(); - - if (res == null) + string res; + if (!resources.TryGetValue(map.MapResources.Value[uv].Type, out res)) continue; - colors[y * stride + x] = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb(); + var color = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb(); + if (isDiamond) + { + // Odd rows are shifted right by 1px + var dx = uv.V & 1; + if (x + dx > 0) + colors[y * stride + 2 * x + dx - 1] = color; + + if (2 * x + dx < stride) + colors[y * stride + 2 * x + dx] = color; + } + else + colors[y * stride + x] = color; } } } diff --git a/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs b/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs index b017d481c6..f7469b904e 100644 --- a/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs +++ b/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs @@ -61,6 +61,7 @@ namespace OpenRA.Mods.Common.Widgets readonly SpriteFont spawnFont; readonly Color spawnColor, spawnContrastColor; readonly int2 spawnLabelOffset; + readonly int cellWidth; public Func Preview = () => null; public Func> SpawnOccupants = () => new Dictionary(); @@ -81,6 +82,8 @@ namespace OpenRA.Mods.Common.Widgets spawnColor = ChromeMetrics.Get("SpawnColor"); spawnContrastColor = ChromeMetrics.Get("SpawnContrastColor"); spawnLabelOffset = ChromeMetrics.Get("SpawnLabelOffset"); + + cellWidth = Game.ModData.Manifest.TileShape == TileShape.Diamond ? 2 : 1; } protected MapPreviewWidget(MapPreviewWidget other) @@ -102,6 +105,8 @@ namespace OpenRA.Mods.Common.Widgets spawnColor = ChromeMetrics.Get("SpawnColor"); spawnContrastColor = ChromeMetrics.Get("SpawnContrastColor"); spawnLabelOffset = ChromeMetrics.Get("SpawnLabelOffset"); + + cellWidth = other.cellWidth; } public override Widget Clone() { return new MapPreviewWidget(this); } @@ -135,8 +140,13 @@ namespace OpenRA.Mods.Common.Widgets var preview = Preview(); var tileShape = Game.ModData.Manifest.TileShape; var point = cell.ToMPos(tileShape); - var dx = (int)(previewScale * (point.U - preview.Bounds.Left)); + var dx = (int)(previewScale * cellWidth * (point.U - preview.Bounds.Left)); var dy = (int)(previewScale * (point.V - preview.Bounds.Top)); + + // Odd rows are shifted right by 1px + if ((point.V & 1) == 1) + dx += 1; + return new int2(mapRect.X + dx, mapRect.Y + dy); }