diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs
index 4ebee4554a..114b656702 100644
--- a/OpenRA.Game/Map/Map.cs
+++ b/OpenRA.Game/Map/Map.cs
@@ -207,6 +207,18 @@ namespace OpenRA
public Rectangle Bounds;
+ ///
+ /// The top-left of the playable area in projected world coordinates
+ /// This is a hacky workaround for legacy functionality. Do not use for new code.
+ ///
+ public WPos ProjectedTopLeft;
+
+ ///
+ /// The bottom-right of the playable area in projected world coordinates
+ /// This is a hacky workaround for legacy functionality. Do not use for new code.
+ ///
+ public WPos ProjectedBottomRight;
+
public Lazy SpawnPoints;
// Yaml map data
@@ -397,9 +409,9 @@ namespace OpenRA
var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);
AllCells = new CellRegion(TileShape, tl, br);
- var btl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this);
- var bbr = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this);
- CellsInsideBounds = new CellRegion(TileShape, btl, bbr);
+ var btl = new MPos(Bounds.Left, Bounds.Top);
+ var bbr = new MPos(Bounds.Right - 1, Bounds.Bottom - 1);
+ SetBounds(btl, bbr);
CustomTerrain = new CellLayer(this);
foreach (var uv in AllCells.MapCoords)
@@ -706,13 +718,27 @@ namespace OpenRA
AllCells = new CellRegion(TileShape, tl, br);
}
- public void ResizeCordon(int left, int top, int right, int bottom)
+ public void SetBounds(MPos tl, MPos br)
{
- Bounds = Rectangle.FromLTRB(left, top, right, bottom);
+ // The tl and br coordinates are inclusive, but the Rectangle
+ // is exclusive. Pad the right and bottom edges to match.
+ Bounds = Rectangle.FromLTRB(tl.U, tl.V, br.U + 1, br.V + 1);
+ CellsInsideBounds = new CellRegion(TileShape, tl.ToCPos(this), br.ToCPos(this));
- var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this);
- var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this);
- CellsInsideBounds = new CellRegion(TileShape, tl, br);
+ // Directly calculate the projected map corners in world units avoiding unnecessary
+ // conversions. This abuses the definition that the width of the cell is always
+ // 1024 units, and that the height of two rows is 2048 for classic cells and 1024
+ // for diamond cells.
+ var wtop = tl.V * 1024;
+ var wbottom = (br.V + 1) * 1024;
+ if (TileShape == TileShape.Diamond)
+ {
+ wtop /= 2;
+ wbottom /= 2;
+ }
+
+ ProjectedTopLeft = new WPos(tl.U * 1024, wtop, 0);
+ ProjectedBottomRight = new WPos(br.U * 1024 - 1, wbottom - 1, 0);
}
string ComputeHash()
diff --git a/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs
index 8fc7794f37..3fcf1d0336 100644
--- a/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs
+++ b/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs
@@ -64,16 +64,26 @@ namespace OpenRA.Mods.Common.Scripting
return actors.ToArray();
}
- [Desc("Returns the location of the top-left corner of the map.")]
+ [Desc("Returns the location of the top-left corner of the map (assuming zero terrain height).")]
public WPos TopLeft
{
- get { return new WPos(Context.World.Map.Bounds.Left * 1024, Context.World.Map.Bounds.Top * 1024, 0); }
+ get
+ {
+ // HACK: This api method abuses the coordinate system, and should be removed
+ // in favour of proper actor queries. See #8549.
+ return Context.World.Map.ProjectedTopLeft;
+ }
}
- [Desc("Returns the location of the bottom-right corner of the map.")]
+ [Desc("Returns the location of the bottom-right corner of the map (assuming zero terrain height).")]
public WPos BottomRight
{
- get { return new WPos(Context.World.Map.Bounds.Right * 1024, Context.World.Map.Bounds.Bottom * 1024, 0); }
+ get
+ {
+ // HACK: This api method abuses the coordinate system, and should be removed
+ // in favour of proper actor queries. See #8549.
+ return Context.World.Map.ProjectedBottomRight;
+ }
}
[Desc("Returns a random cell inside the visible region of the map.")]
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs
index 8448322063..30bebf1718 100644
--- a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs
+++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs
@@ -64,7 +64,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
height = Math.Max(2, height);
map.Resize(width + 2, height + tileset.MaxGroundHeight + 2);
- map.ResizeCordon(1, 1, width + 1, height + tileset.MaxGroundHeight + 1);
+
+ var tl = new MPos(1, 1);
+ var br = new MPos(width, height + tileset.MaxGroundHeight);
+ map.SetBounds(tl, br);
+
map.PlayerDefinitions = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length).ToMiniYaml();
map.FixOpenAreas(modRules);