Merge pull request #8825 from pchote/lobby-map-previews
Fix TS lobby map previews
This commit is contained in:
@@ -20,14 +20,23 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false)
|
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false)
|
||||||
{
|
{
|
||||||
|
var isDiamond = map.TileShape == TileShape.Diamond;
|
||||||
var b = map.Bounds;
|
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 width = b.Width;
|
||||||
var height = b.Height;
|
var height = b.Height + heightOffset;
|
||||||
|
|
||||||
|
var bitmapWidth = width;
|
||||||
|
if (isDiamond)
|
||||||
|
bitmapWidth = 2 * bitmapWidth - 1;
|
||||||
|
|
||||||
if (!actualSize)
|
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(),
|
var bitmapData = terrain.LockBits(terrain.Bounds(),
|
||||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||||
@@ -38,16 +47,27 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var colors = (int*)bitmapData.Scan0;
|
var colors = (int*)bitmapData.Scan0;
|
||||||
var stride = bitmapData.Stride / 4;
|
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 uv = new MPos(x + b.Left, y + b.Top);
|
||||||
var mapY = y + b.Top;
|
var type = tileset.GetTileInfo(mapTiles[uv]);
|
||||||
var type = tileset.GetTileInfo(mapTiles[new MPos(mapX, mapY)]);
|
var leftColor = type != null ? type.LeftColor : Color.Black;
|
||||||
var color = 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)
|
static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap)
|
||||||
{
|
{
|
||||||
var terrain = new Bitmap(terrainBitmap);
|
var terrain = new Bitmap(terrainBitmap);
|
||||||
|
var isDiamond = map.TileShape == TileShape.Diamond;
|
||||||
var b = map.Bounds;
|
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<ResourceTypeInfo>()
|
||||||
|
.ToDictionary(r => r.ResourceType, r => r.TerrainType);
|
||||||
|
|
||||||
var bitmapData = terrain.LockBits(terrain.Bounds(),
|
var bitmapData = terrain.LockBits(terrain.Bounds(),
|
||||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
@@ -70,23 +100,31 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var colors = (int*)bitmapData.Scan0;
|
var colors = (int*)bitmapData.Scan0;
|
||||||
var stride = bitmapData.Stride / 4;
|
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 uv = new MPos(x + b.Left, y + b.Top);
|
||||||
var mapY = y + b.Top;
|
if (map.MapResources.Value[uv].Type == 0)
|
||||||
if (map.MapResources.Value[new MPos(mapX, mapY)].Type == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var res = resourceRules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()
|
string res;
|
||||||
.Where(t => t.ResourceType == map.MapResources.Value[new MPos(mapX, mapY)].Type)
|
if (!resources.TryGetValue(map.MapResources.Value[uv].Type, out res))
|
||||||
.Select(t => t.TerrainType).FirstOrDefault();
|
|
||||||
|
|
||||||
if (res == null)
|
|
||||||
continue;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
readonly SpriteFont spawnFont;
|
readonly SpriteFont spawnFont;
|
||||||
readonly Color spawnColor, spawnContrastColor;
|
readonly Color spawnColor, spawnContrastColor;
|
||||||
readonly int2 spawnLabelOffset;
|
readonly int2 spawnLabelOffset;
|
||||||
|
readonly int cellWidth;
|
||||||
|
|
||||||
public Func<MapPreview> Preview = () => null;
|
public Func<MapPreview> Preview = () => null;
|
||||||
public Func<Dictionary<CPos, SpawnOccupant>> SpawnOccupants = () => new Dictionary<CPos, SpawnOccupant>();
|
public Func<Dictionary<CPos, SpawnOccupant>> SpawnOccupants = () => new Dictionary<CPos, SpawnOccupant>();
|
||||||
@@ -81,6 +82,8 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
spawnColor = ChromeMetrics.Get<Color>("SpawnColor");
|
spawnColor = ChromeMetrics.Get<Color>("SpawnColor");
|
||||||
spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor");
|
spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor");
|
||||||
spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset");
|
spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset");
|
||||||
|
|
||||||
|
cellWidth = Game.ModData.Manifest.TileShape == TileShape.Diamond ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MapPreviewWidget(MapPreviewWidget other)
|
protected MapPreviewWidget(MapPreviewWidget other)
|
||||||
@@ -102,6 +105,8 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
spawnColor = ChromeMetrics.Get<Color>("SpawnColor");
|
spawnColor = ChromeMetrics.Get<Color>("SpawnColor");
|
||||||
spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor");
|
spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor");
|
||||||
spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset");
|
spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset");
|
||||||
|
|
||||||
|
cellWidth = other.cellWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Widget Clone() { return new MapPreviewWidget(this); }
|
public override Widget Clone() { return new MapPreviewWidget(this); }
|
||||||
@@ -135,8 +140,13 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
var preview = Preview();
|
var preview = Preview();
|
||||||
var tileShape = Game.ModData.Manifest.TileShape;
|
var tileShape = Game.ModData.Manifest.TileShape;
|
||||||
var point = cell.ToMPos(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));
|
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);
|
return new int2(mapRect.X + dx, mapRect.Y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user